Commit aa4e3c8a authored by Mikhail Pershin's avatar Mikhail Pershin Committed by Greg Kroah-Hartman

staging/lustre/llog: MGC to use OSD API for backup logs

MGC uses lvfs API to access local llogs blocking removal of old code

- llog_is_empty() and llog_backup() are introduced

Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2059
Lustre-change: http://review.whamcloud.com/5049
Cc: Levente Kurusa <levex@linux.com>
Signed-off-by: default avatarMikhail Pershin <mike.pershin@intel.com>
Reviewed-by: default avatarLai Siyao <lai.siyao@intel.com>
Reviewed-by: default avatarAlex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: default avatarJames Simmons <uja.ornl@gmail.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
[pick client side change only -- Peng Tao]
Signed-off-by: default avatarPeng Tao <bergwolf@gmail.com>
Signed-off-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8cc93bc3
...@@ -136,7 +136,11 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt, ...@@ -136,7 +136,11 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
struct llog_handle **lgh, struct llog_logid *logid, struct llog_handle **lgh, struct llog_logid *logid,
char *name, enum llog_open_param open_param); char *name, enum llog_open_param open_param);
int llog_close(const struct lu_env *env, struct llog_handle *cathandle); int llog_close(const struct lu_env *env, struct llog_handle *cathandle);
int llog_get_size(struct llog_handle *loghandle); int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
char *name);
int llog_backup(const struct lu_env *env, struct obd_device *obd,
struct llog_ctxt *ctxt, struct llog_ctxt *bak_ctxt,
char *name, char *backup);
/* llog_process flags */ /* llog_process flags */
#define LLOG_FLAG_NODEAMON 0x0001 #define LLOG_FLAG_NODEAMON 0x0001
...@@ -382,6 +386,13 @@ static inline int llog_data_len(int len) ...@@ -382,6 +386,13 @@ static inline int llog_data_len(int len)
return cfs_size_round(len); return cfs_size_round(len);
} }
static inline int llog_get_size(struct llog_handle *loghandle)
{
if (loghandle && loghandle->lgh_hdr)
return loghandle->lgh_hdr->llh_count;
return 0;
}
static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt) static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt)
{ {
atomic_inc(&ctxt->loc_refcount); atomic_inc(&ctxt->loc_refcount);
......
...@@ -399,8 +399,8 @@ struct client_obd { ...@@ -399,8 +399,8 @@ struct client_obd {
/* mgc datastruct */ /* mgc datastruct */
struct semaphore cl_mgc_sem; struct semaphore cl_mgc_sem;
struct vfsmount *cl_mgc_vfsmnt; struct local_oid_storage *cl_mgc_los;
struct dentry *cl_mgc_configs_dir; struct dt_object *cl_mgc_configs_dir;
atomic_t cl_mgc_refcount; atomic_t cl_mgc_refcount;
struct obd_export *cl_mgc_mgsexp; struct obd_export *cl_mgc_mgsexp;
......
...@@ -99,11 +99,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) ...@@ -99,11 +99,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
static int mgc_cleanup(struct obd_device *obd) static int mgc_cleanup(struct obd_device *obd)
{ {
struct client_obd *cli = &obd->u.cli;
int rc; int rc;
LASSERT(cli->cl_mgc_vfsmnt == NULL);
ptlrpcd_decref(); ptlrpcd_decref();
rc = client_obd_cleanup(obd); rc = client_obd_cleanup(obd);
......
...@@ -41,17 +41,14 @@ ...@@ -41,17 +41,14 @@
#define DEBUG_SUBSYSTEM S_MGC #define DEBUG_SUBSYSTEM S_MGC
#define D_MGC D_CONFIG /*|D_WARNING*/ #define D_MGC D_CONFIG /*|D_WARNING*/
# include <linux/module.h> #include <linux/module.h>
# include <linux/pagemap.h>
# include <linux/miscdevice.h>
# include <linux/init.h>
#include <obd_class.h> #include <obd_class.h>
#include <lustre_dlm.h> #include <lustre_dlm.h>
#include <lprocfs_status.h> #include <lprocfs_status.h>
#include <lustre_log.h> #include <lustre_log.h>
#include <lustre_fsfilt.h>
#include <lustre_disk.h> #include <lustre_disk.h>
#include <dt_object.h>
#include "mgc_internal.h" #include "mgc_internal.h"
static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id, static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
...@@ -578,97 +575,175 @@ static void mgc_requeue_add(struct config_llog_data *cld) ...@@ -578,97 +575,175 @@ static void mgc_requeue_add(struct config_llog_data *cld)
} }
/********************** class fns **********************/ /********************** class fns **********************/
static int mgc_local_llog_init(const struct lu_env *env,
struct obd_device *obd,
struct obd_device *disk)
{
struct llog_ctxt *ctxt;
int rc;
static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_ORIG_CTXT, disk,
struct vfsmount *mnt) &llog_osd_ops);
if (rc)
return rc;
ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
LASSERT(ctxt);
ctxt->loc_dir = obd->u.cli.cl_mgc_configs_dir;
llog_ctxt_put(ctxt);
return 0;
}
static int mgc_local_llog_fini(const struct lu_env *env,
struct obd_device *obd)
{
struct llog_ctxt *ctxt;
ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
llog_cleanup(env, ctxt);
return 0;
}
static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb)
{ {
struct lvfs_run_ctxt saved;
struct lustre_sb_info *lsi = s2lsi(sb); struct lustre_sb_info *lsi = s2lsi(sb);
struct client_obd *cli = &obd->u.cli; struct client_obd *cli = &obd->u.cli;
struct dentry *dentry; struct lu_fid rfid, fid;
char *label; struct dt_object *root, *dto;
int err = 0; struct lu_env *env;
int rc = 0;
LASSERT(lsi); LASSERT(lsi);
LASSERT(lsi->lsi_srv_mnt == mnt); LASSERT(lsi->lsi_dt_dev);
OBD_ALLOC_PTR(env);
if (env == NULL)
return -ENOMEM;
/* The mgc fs exclusion sem. Only one fs can be setup at a time. */ /* The mgc fs exclusion sem. Only one fs can be setup at a time. */
down(&cli->cl_mgc_sem); down(&cli->cl_mgc_sem);
cfs_cleanup_group_info(); cfs_cleanup_group_info();
obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); /* Setup the configs dir */
if (IS_ERR(obd->obd_fsops)) { rc = lu_env_init(env, LCT_MG_THREAD);
up(&cli->cl_mgc_sem); if (rc)
CERROR("%s: No fstype %s: rc = %ld\n", lsi->lsi_fstype, GOTO(out_err, rc);
obd->obd_name, PTR_ERR(obd->obd_fsops));
return PTR_ERR(obd->obd_fsops);
}
cli->cl_mgc_vfsmnt = mnt; fid.f_seq = FID_SEQ_LOCAL_NAME;
err = fsfilt_setup(obd, mnt->mnt_sb); fid.f_oid = 1;
if (err) fid.f_ver = 0;
GOTO(err_ops, err); rc = local_oid_storage_init(env, lsi->lsi_dt_dev, &fid,
&cli->cl_mgc_los);
if (rc)
GOTO(out_env, rc);
OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); rc = dt_root_get(env, lsi->lsi_dt_dev, &rfid);
obd->obd_lvfs_ctxt.pwdmnt = mnt; if (rc)
obd->obd_lvfs_ctxt.pwd = mnt->mnt_root; GOTO(out_env, rc);
obd->obd_lvfs_ctxt.fs = get_ds();
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid,
dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs), &cli->cl_mgc_los->los_dev->dd_lu_dev);
strlen(MOUNT_CONFIGS_DIR)); if (unlikely(IS_ERR(root)))
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); GOTO(out_los, rc = PTR_ERR(root));
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry); dto = local_file_find_or_create(env, cli->cl_mgc_los, root,
CERROR("cannot lookup %s directory: rc = %d\n", MOUNT_CONFIGS_DIR,
MOUNT_CONFIGS_DIR, err); S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
GOTO(err_ops, err); lu_object_put_nocache(env, &root->do_lu);
} if (IS_ERR(dto))
cli->cl_mgc_configs_dir = dentry; GOTO(out_los, rc = PTR_ERR(dto));
cli->cl_mgc_configs_dir = dto;
LASSERT(lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt);
rc = mgc_local_llog_init(env, obd, lsi->lsi_osd_exp->exp_obd);
if (rc)
GOTO(out_llog, rc);
/* We take an obd ref to insure that we can't get to mgc_cleanup /* We take an obd ref to insure that we can't get to mgc_cleanup
without calling mgc_fs_cleanup first. */ * without calling mgc_fs_cleanup first. */
class_incref(obd, "mgc_fs", obd); class_incref(obd, "mgc_fs", obd);
label = fsfilt_get_label(obd, mnt->mnt_sb);
if (label)
CDEBUG(D_MGC, "MGC using disk labelled=%s\n", label);
/* We keep the cl_mgc_sem until mgc_fs_cleanup */ /* We keep the cl_mgc_sem until mgc_fs_cleanup */
return 0; out_llog:
if (rc) {
err_ops: lu_object_put(env, &cli->cl_mgc_configs_dir->do_lu);
fsfilt_put_ops(obd->obd_fsops); cli->cl_mgc_configs_dir = NULL;
obd->obd_fsops = NULL; }
cli->cl_mgc_vfsmnt = NULL; out_los:
if (rc < 0) {
local_oid_storage_fini(env, cli->cl_mgc_los);
cli->cl_mgc_los = NULL;
up(&cli->cl_mgc_sem); up(&cli->cl_mgc_sem);
return err; }
out_env:
lu_env_fini(env);
out_err:
OBD_FREE_PTR(env);
return rc;
} }
static int mgc_fs_cleanup(struct obd_device *obd) static int mgc_fs_cleanup(struct obd_device *obd)
{ {
struct lu_env env;
struct client_obd *cli = &obd->u.cli; struct client_obd *cli = &obd->u.cli;
int rc = 0; int rc;
LASSERT(cli->cl_mgc_vfsmnt != NULL); LASSERT(cli->cl_mgc_los != NULL);
if (cli->cl_mgc_configs_dir != NULL) { rc = lu_env_init(&env, LCT_MG_THREAD);
struct lvfs_run_ctxt saved; if (rc)
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); GOTO(unlock, rc);
l_dput(cli->cl_mgc_configs_dir);
mgc_local_llog_fini(&env, obd);
lu_object_put_nocache(&env, &cli->cl_mgc_configs_dir->do_lu);
cli->cl_mgc_configs_dir = NULL; cli->cl_mgc_configs_dir = NULL;
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
class_decref(obd, "mgc_fs", obd);
}
cli->cl_mgc_vfsmnt = NULL; local_oid_storage_fini(&env, cli->cl_mgc_los);
if (obd->obd_fsops) cli->cl_mgc_los = NULL;
fsfilt_put_ops(obd->obd_fsops); lu_env_fini(&env);
unlock:
class_decref(obd, "mgc_fs", obd);
up(&cli->cl_mgc_sem); up(&cli->cl_mgc_sem);
return 0;
}
static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd)
{
struct llog_ctxt *ctxt;
int rc;
/* setup only remote ctxt, the local disk context is switched per each
* filesystem during mgc_fs_setup() */
rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_REPL_CTXT, obd,
&llog_client_ops);
if (rc)
return rc; return rc;
ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
LASSERT(ctxt);
llog_initiator_connect(ctxt);
llog_ctxt_put(ctxt);
return 0;
}
static int mgc_llog_fini(const struct lu_env *env, struct obd_device *obd)
{
struct llog_ctxt *ctxt;
ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
if (ctxt)
llog_cleanup(env, ctxt);
return 0;
} }
static atomic_t mgc_count = ATOMIC_INIT(0); static atomic_t mgc_count = ATOMIC_INIT(0);
...@@ -694,7 +769,7 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) ...@@ -694,7 +769,7 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
} }
} }
obd_cleanup_client_import(obd); obd_cleanup_client_import(obd);
rc = obd_llog_finish(obd, 0); rc = mgc_llog_fini(NULL, obd);
if (rc != 0) if (rc != 0)
CERROR("failed to cleanup llogging subsystems\n"); CERROR("failed to cleanup llogging subsystems\n");
break; break;
...@@ -704,11 +779,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) ...@@ -704,11 +779,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
static int mgc_cleanup(struct obd_device *obd) static int mgc_cleanup(struct obd_device *obd)
{ {
struct client_obd *cli = &obd->u.cli;
int rc; int rc;
LASSERT(cli->cl_mgc_vfsmnt == NULL);
/* COMPAT_146 - old config logs may have added profiles we don't /* COMPAT_146 - old config logs may have added profiles we don't
know about */ know about */
if (obd->obd_type->typ_refcnt <= 1) if (obd->obd_type->typ_refcnt <= 1)
...@@ -733,7 +805,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) ...@@ -733,7 +805,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
if (rc) if (rc)
GOTO(err_decref, rc); GOTO(err_decref, rc);
rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL); rc = mgc_llog_init(NULL, obd);
if (rc) { if (rc) {
CERROR("failed to setup llogging subsystems\n"); CERROR("failed to setup llogging subsystems\n");
GOTO(err_cleanup, rc); GOTO(err_cleanup, rc);
...@@ -1011,11 +1083,11 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp, ...@@ -1011,11 +1083,11 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp,
} }
if (KEY_IS(KEY_SET_FS)) { if (KEY_IS(KEY_SET_FS)) {
struct super_block *sb = (struct super_block *)val; struct super_block *sb = (struct super_block *)val;
struct lustre_sb_info *lsi;
if (vallen != sizeof(struct super_block)) if (vallen != sizeof(struct super_block))
return -EINVAL; return -EINVAL;
lsi = s2lsi(sb);
rc = mgc_fs_setup(exp->exp_obd, sb, lsi->lsi_srv_mnt); rc = mgc_fs_setup(exp->exp_obd, sb);
if (rc) { if (rc) {
CERROR("set_fs got %d\n", rc); CERROR("set_fs got %d\n", rc);
} }
...@@ -1145,49 +1217,6 @@ static int mgc_import_event(struct obd_device *obd, ...@@ -1145,49 +1217,6 @@ static int mgc_import_event(struct obd_device *obd,
return rc; return rc;
} }
static int mgc_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
struct obd_device *tgt, int *index)
{
struct llog_ctxt *ctxt;
int rc;
LASSERT(olg == &obd->obd_olg);
rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_REPL_CTXT, tgt,
&llog_client_ops);
if (rc)
GOTO(out, rc);
ctxt = llog_group_get_ctxt(olg, LLOG_CONFIG_REPL_CTXT);
if (!ctxt)
GOTO(out, rc = -ENODEV);
llog_initiator_connect(ctxt);
llog_ctxt_put(ctxt);
return 0;
out:
ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
if (ctxt)
llog_cleanup(NULL, ctxt);
return rc;
}
static int mgc_llog_finish(struct obd_device *obd, int count)
{
struct llog_ctxt *ctxt;
ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
if (ctxt)
llog_cleanup(NULL, ctxt);
ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
if (ctxt)
llog_cleanup(NULL, ctxt);
return 0;
}
enum { enum {
CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT), CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT),
CONFIG_READ_NRPAGES = 4 CONFIG_READ_NRPAGES = 4
...@@ -1540,17 +1569,58 @@ static int mgc_process_recover_log(struct obd_device *obd, ...@@ -1540,17 +1569,58 @@ static int mgc_process_recover_log(struct obd_device *obd,
return rc; return rc;
} }
static int mgc_llog_local_copy(const struct lu_env *env,
struct obd_device *obd,
struct llog_ctxt *rctxt,
struct llog_ctxt *lctxt, char *logname)
{
char *temp_log;
int rc;
/*
* - copy it to backup using llog_backup()
* - copy remote llog to logname using llog_backup()
* - if failed then move bakup to logname again
*/
OBD_ALLOC(temp_log, strlen(logname) + 1);
if (!temp_log)
return -ENOMEM;
sprintf(temp_log, "%sT", logname);
/* make a copy of local llog at first */
rc = llog_backup(env, obd, lctxt, lctxt, logname, temp_log);
if (rc < 0 && rc != -ENOENT)
GOTO(out, rc);
/* copy remote llog to the local copy */
rc = llog_backup(env, obd, rctxt, lctxt, logname, logname);
if (rc == -ENOENT) {
/* no remote llog, delete local one too */
llog_erase(env, lctxt, NULL, logname);
} else if (rc < 0) {
/* error during backup, get local one back from the copy */
llog_backup(env, obd, lctxt, lctxt, temp_log, logname);
out:
CERROR("%s: failed to copy remote log %s: rc = %d\n",
obd->obd_name, logname, rc);
}
llog_erase(env, lctxt, NULL, temp_log);
OBD_FREE(temp_log, strlen(logname) + 1);
return rc;
}
/* local_only means it cannot get remote llogs */ /* local_only means it cannot get remote llogs */
static int mgc_process_cfg_log(struct obd_device *mgc, static int mgc_process_cfg_log(struct obd_device *mgc,
struct config_llog_data *cld, struct config_llog_data *cld, int local_only)
int local_only)
{ {
struct llog_ctxt *ctxt, *lctxt = NULL; struct llog_ctxt *ctxt, *lctxt = NULL;
struct lvfs_run_ctxt *saved_ctxt; struct dt_object *cl_mgc_dir = mgc->u.cli.cl_mgc_configs_dir;
struct lustre_sb_info *lsi = NULL; struct lustre_sb_info *lsi = NULL;
int rc = 0, must_pop = 0; int rc = 0;
bool sptlrpc_started = false; bool sptlrpc_started = false;
struct lu_env *env;
LASSERT(cld); LASSERT(cld);
LASSERT(mutex_is_locked(&cld->cld_lock)); LASSERT(mutex_is_locked(&cld->cld_lock));
...@@ -1565,19 +1635,47 @@ static int mgc_process_cfg_log(struct obd_device *mgc, ...@@ -1565,19 +1635,47 @@ static int mgc_process_cfg_log(struct obd_device *mgc,
if (cld->cld_cfg.cfg_sb) if (cld->cld_cfg.cfg_sb)
lsi = s2lsi(cld->cld_cfg.cfg_sb); lsi = s2lsi(cld->cld_cfg.cfg_sb);
ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT); OBD_ALLOC_PTR(env);
if (!ctxt) { if (env == NULL)
CERROR("missing llog context\n");
return -EINVAL;
}
OBD_ALLOC_PTR(saved_ctxt);
if (saved_ctxt == NULL)
return -ENOMEM; return -ENOMEM;
rc = lu_env_init(env, LCT_MG_THREAD);
if (rc)
GOTO(out_free, rc);
ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT);
LASSERT(ctxt);
lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT); lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT);
if (local_only) { /* no local log at client side */ /* Copy the setup log locally if we can. Don't mess around if we're
* running an MGS though (logs are already local). */
if (lctxt && lsi && IS_SERVER(lsi) && !IS_MGS(lsi) &&
cl_mgc_dir != NULL &&
lu2dt_dev(cl_mgc_dir->do_lu.lo_dev) == lsi->lsi_dt_dev) {
if (!local_only)
/* Only try to copy log if we have the lock. */
rc = mgc_llog_local_copy(env, mgc, ctxt, lctxt,
cld->cld_logname);
if (local_only || rc) {
if (llog_is_empty(env, lctxt, cld->cld_logname)) {
LCONSOLE_ERROR_MSG(0x13a,
"Failed to get MGS log %s and no local copy.\n",
cld->cld_logname);
GOTO(out_pop, rc = -ENOTCONN);
}
CDEBUG(D_MGC,
"Failed to get MGS log %s, using local copy for now, will try to update later.\n",
cld->cld_logname);
}
/* Now, whether we copied or not, start using the local llog.
* If we failed to copy, we'll start using whatever the old
* log has. */
llog_ctxt_put(ctxt);
ctxt = lctxt;
lctxt = NULL;
} else {
if (local_only) /* no local log at client side */
GOTO(out_pop, rc = -EIO); GOTO(out_pop, rc = -EIO);
} }
...@@ -1587,19 +1685,16 @@ static int mgc_process_cfg_log(struct obd_device *mgc, ...@@ -1587,19 +1685,16 @@ static int mgc_process_cfg_log(struct obd_device *mgc,
} }
/* logname and instance info should be the same, so use our /* logname and instance info should be the same, so use our
copy of the instance for the update. The cfg_last_idx will * copy of the instance for the update. The cfg_last_idx will
be updated here. */ * be updated here. */
rc = class_config_parse_llog(NULL, ctxt, cld->cld_logname, rc = class_config_parse_llog(env, ctxt, cld->cld_logname,
&cld->cld_cfg); &cld->cld_cfg);
out_pop: out_pop:
llog_ctxt_put(ctxt); __llog_ctxt_put(env, ctxt);
if (lctxt) if (lctxt)
llog_ctxt_put(lctxt); __llog_ctxt_put(env, lctxt);
if (must_pop)
pop_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL);
OBD_FREE_PTR(saved_ctxt);
/* /*
* update settings on existing OBDs. doing it inside * update settings on existing OBDs. doing it inside
* of llog_process_lock so no device is attaching/detaching * of llog_process_lock so no device is attaching/detaching
...@@ -1614,6 +1709,9 @@ static int mgc_process_cfg_log(struct obd_device *mgc, ...@@ -1614,6 +1709,9 @@ static int mgc_process_cfg_log(struct obd_device *mgc,
strlen("-sptlrpc")); strlen("-sptlrpc"));
} }
lu_env_fini(env);
out_free:
OBD_FREE_PTR(env);
return rc; return rc;
} }
...@@ -1801,8 +1899,6 @@ struct obd_ops mgc_obd_ops = { ...@@ -1801,8 +1899,6 @@ struct obd_ops mgc_obd_ops = {
.o_set_info_async = mgc_set_info_async, .o_set_info_async = mgc_set_info_async,
.o_get_info = mgc_get_info, .o_get_info = mgc_get_info,
.o_import_event = mgc_import_event, .o_import_event = mgc_import_event,
.o_llog_init = mgc_llog_init,
.o_llog_finish = mgc_llog_finish,
.o_process_config = mgc_process_config, .o_process_config = mgc_process_config,
}; };
......
...@@ -265,31 +265,6 @@ int llog_init_handle(const struct lu_env *env, struct llog_handle *handle, ...@@ -265,31 +265,6 @@ int llog_init_handle(const struct lu_env *env, struct llog_handle *handle,
} }
EXPORT_SYMBOL(llog_init_handle); EXPORT_SYMBOL(llog_init_handle);
int llog_copy_handler(const struct lu_env *env,
struct llog_handle *llh,
struct llog_rec_hdr *rec,
void *data)
{
struct llog_rec_hdr local_rec = *rec;
struct llog_handle *local_llh = (struct llog_handle *)data;
char *cfg_buf = (char*) (rec + 1);
struct lustre_cfg *lcfg;
int rc = 0;
/* Append all records */
local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
rc = llog_write(env, local_llh, &local_rec, NULL, 0,
(void *)cfg_buf, -1);
lcfg = (struct lustre_cfg *)cfg_buf;
CDEBUG(D_INFO, "idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
return rc;
}
EXPORT_SYMBOL(llog_copy_handler);
static int llog_process_thread(void *arg) static int llog_process_thread(void *arg)
{ {
struct llog_process_info *lpi = arg; struct llog_process_info *lpi = arg;
...@@ -493,14 +468,6 @@ int llog_process(const struct lu_env *env, struct llog_handle *loghandle, ...@@ -493,14 +468,6 @@ int llog_process(const struct lu_env *env, struct llog_handle *loghandle,
} }
EXPORT_SYMBOL(llog_process); EXPORT_SYMBOL(llog_process);
inline int llog_get_size(struct llog_handle *loghandle)
{
if (loghandle && loghandle->lgh_hdr)
return loghandle->lgh_hdr->llh_count;
return 0;
}
EXPORT_SYMBOL(llog_get_size);
int llog_reverse_process(const struct lu_env *env, int llog_reverse_process(const struct lu_env *env,
struct llog_handle *loghandle, llog_cb_t cb, struct llog_handle *loghandle, llog_cb_t cb,
void *data, void *catdata) void *data, void *catdata)
...@@ -767,6 +734,7 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, ...@@ -767,6 +734,7 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
struct llog_handle **res, struct llog_logid *logid, struct llog_handle **res, struct llog_logid *logid,
char *name) char *name)
{ {
struct dt_device *d;
struct thandle *th; struct thandle *th;
int rc; int rc;
...@@ -777,8 +745,7 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, ...@@ -777,8 +745,7 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
if (llog_exist(*res)) if (llog_exist(*res))
return 0; return 0;
if ((*res)->lgh_obj != NULL) { LASSERT((*res)->lgh_obj != NULL);
struct dt_device *d;
d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev); d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);
...@@ -793,11 +760,6 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, ...@@ -793,11 +760,6 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
rc = llog_create(env, *res, th); rc = llog_create(env, *res, th);
} }
dt_trans_stop(env, d, th); dt_trans_stop(env, d, th);
} else {
/* lvfs compat code */
LASSERT((*res)->lgh_file == NULL);
rc = llog_create(env, *res, NULL);
}
out: out:
if (rc) if (rc)
llog_close(env, *res); llog_close(env, *res);
...@@ -842,14 +804,13 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle, ...@@ -842,14 +804,13 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
struct llog_rec_hdr *rec, struct llog_cookie *reccookie, struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
int cookiecount, void *buf, int idx) int cookiecount, void *buf, int idx)
{ {
struct dt_device *dt;
struct thandle *th;
int rc; int rc;
LASSERT(loghandle); LASSERT(loghandle);
LASSERT(loghandle->lgh_ctxt); LASSERT(loghandle->lgh_ctxt);
LASSERT(loghandle->lgh_obj != NULL);
if (loghandle->lgh_obj != NULL) {
struct dt_device *dt;
struct thandle *th;
dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev); dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);
...@@ -871,12 +832,6 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle, ...@@ -871,12 +832,6 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
up_write(&loghandle->lgh_lock); up_write(&loghandle->lgh_lock);
out_trans: out_trans:
dt_trans_stop(env, dt, th); dt_trans_stop(env, dt, th);
} else { /* lvfs compatibility */
down_write(&loghandle->lgh_lock);
rc = llog_write_rec(env, loghandle, rec, reccookie,
cookiecount, buf, idx, NULL);
up_write(&loghandle->lgh_lock);
}
return rc; return rc;
} }
EXPORT_SYMBOL(llog_write); EXPORT_SYMBOL(llog_write);
...@@ -932,3 +887,104 @@ int llog_close(const struct lu_env *env, struct llog_handle *loghandle) ...@@ -932,3 +887,104 @@ int llog_close(const struct lu_env *env, struct llog_handle *loghandle)
return rc; return rc;
} }
EXPORT_SYMBOL(llog_close); EXPORT_SYMBOL(llog_close);
int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
char *name)
{
struct llog_handle *llh;
int rc = 0;
rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
if (rc < 0) {
if (likely(rc == -ENOENT))
rc = 0;
GOTO(out, rc);
}
rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
if (rc)
GOTO(out_close, rc);
rc = llog_get_size(llh);
out_close:
llog_close(env, llh);
out:
/* header is record 1 */
return rc <= 1;
}
EXPORT_SYMBOL(llog_is_empty);
int llog_copy_handler(const struct lu_env *env, struct llog_handle *llh,
struct llog_rec_hdr *rec, void *data)
{
struct llog_handle *copy_llh = data;
/* Append all records */
return llog_write(env, copy_llh, rec, NULL, 0, NULL, -1);
}
EXPORT_SYMBOL(llog_copy_handler);
/* backup plain llog */
int llog_backup(const struct lu_env *env, struct obd_device *obd,
struct llog_ctxt *ctxt, struct llog_ctxt *bctxt,
char *name, char *backup)
{
struct llog_handle *llh, *bllh;
int rc;
/* open original log */
rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
if (rc < 0) {
/* the -ENOENT case is also reported to the caller
* but silently so it should handle that if needed.
*/
if (rc != -ENOENT)
CERROR("%s: failed to open log %s: rc = %d\n",
obd->obd_name, name, rc);
return rc;
}
rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
if (rc)
GOTO(out_close, rc);
/* Make sure there's no old backup log */
rc = llog_erase(env, bctxt, NULL, backup);
if (rc < 0 && rc != -ENOENT)
GOTO(out_close, rc);
/* open backup log */
rc = llog_open_create(env, bctxt, &bllh, NULL, backup);
if (rc) {
CERROR("%s: failed to open backup logfile %s: rc = %d\n",
obd->obd_name, backup, rc);
GOTO(out_close, rc);
}
/* check that backup llog is not the same object as original one */
if (llh->lgh_obj == bllh->lgh_obj) {
CERROR("%s: backup llog %s to itself (%s), objects %p/%p\n",
obd->obd_name, name, backup, llh->lgh_obj,
bllh->lgh_obj);
GOTO(out_backup, rc = -EEXIST);
}
rc = llog_init_handle(env, bllh, LLOG_F_IS_PLAIN, NULL);
if (rc)
GOTO(out_backup, rc);
/* Copy log record by record */
rc = llog_process_or_fork(env, llh, llog_copy_handler, (void *)bllh,
NULL, false);
if (rc)
CERROR("%s: failed to backup log %s: rc = %d\n",
obd->obd_name, name, rc);
out_backup:
llog_close(env, bllh);
out_close:
llog_close(env, llh);
return rc;
}
EXPORT_SYMBOL(llog_backup);
...@@ -855,9 +855,12 @@ int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev, ...@@ -855,9 +855,12 @@ int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev,
(*los)->los_seq = fid_seq(first_fid); (*los)->los_seq = fid_seq(first_fid);
(*los)->los_last_oid = le64_to_cpu(lastid); (*los)->los_last_oid = le64_to_cpu(lastid);
(*los)->los_obj = o; (*los)->los_obj = o;
/* read value should not be less than initial one */ /* Read value should not be less than initial one
LASSERTF((*los)->los_last_oid >= first_oid, "%u < %u\n", * but possible after upgrade from older fs.
(*los)->los_last_oid, first_oid); * In this case just switch to the first_oid in memory and
* it will be updated on disk with first object generated */
if ((*los)->los_last_oid < first_oid)
(*los)->los_last_oid = first_oid;
} }
out: out:
mutex_unlock(&ls->ls_los_mutex); mutex_unlock(&ls->ls_los_mutex);
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
* *
* Author: Mikhail Pershin <mike.pershin@intel.com> * Author: Mikhail Pershin <mike.pershin@intel.com>
*/ */
#ifndef __LOCAL_STORAGE_H
#define __LOCAL_STORAGE_H
#include <dt_object.h> #include <dt_object.h>
#include <obd.h> #include <obd.h>
...@@ -86,3 +88,4 @@ struct los_ondisk { ...@@ -86,3 +88,4 @@ struct los_ondisk {
}; };
#define LOS_MAGIC 0xdecafbee #define LOS_MAGIC 0xdecafbee
#endif
...@@ -429,7 +429,7 @@ LU_KEY_INIT_FINI(lu_global, struct lu_cdebug_data); ...@@ -429,7 +429,7 @@ LU_KEY_INIT_FINI(lu_global, struct lu_cdebug_data);
*/ */
struct lu_context_key lu_global_key = { struct lu_context_key lu_global_key = {
.lct_tags = LCT_MD_THREAD | LCT_DT_THREAD | .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD |
LCT_MG_THREAD | LCT_CL_THREAD, LCT_MG_THREAD | LCT_CL_THREAD | LCT_LOCAL,
.lct_init = lu_global_key_init, .lct_init = lu_global_key_init,
.lct_fini = lu_global_key_fini .lct_fini = lu_global_key_fini
}; };
......
...@@ -631,6 +631,9 @@ int lustre_put_lsi(struct super_block *sb) ...@@ -631,6 +631,9 @@ int lustre_put_lsi(struct super_block *sb)
CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts)); CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts));
if (atomic_dec_and_test(&lsi->lsi_mounts)) { if (atomic_dec_and_test(&lsi->lsi_mounts)) {
if (IS_SERVER(lsi) && lsi->lsi_osd_exp) { if (IS_SERVER(lsi) && lsi->lsi_osd_exp) {
lu_device_put(&lsi->lsi_dt_dev->dd_lu_dev);
lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt = NULL;
lsi->lsi_dt_dev = NULL;
obd_disconnect(lsi->lsi_osd_exp); obd_disconnect(lsi->lsi_osd_exp);
/* wait till OSD is gone */ /* wait till OSD is gone */
obd_zombie_barrier(); obd_zombie_barrier();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment