From 3e38436dc09097429e1ca1fbfa3ef4981e124715 Mon Sep 17 00:00:00 2001 From: Mikhail Pershin Date: Mon, 4 Mar 2013 00:06:41 +0400 Subject: [PATCH] LU-2059 llog: MGC to use OSD API for backup logs MGC uses lvfs API to access local llogs blocking removal of old code - MGS is converted to use OSD API for local llogs - llog_is_empty() and llog_backup() are introduced - initial OSD start initialize run ctxt so llog can use it too - shrink dcache after initial scrub in osd-ldiskfs to avoid holding data of unlinked objects until umount. Signed-off-by: Mikhail Pershin Change-Id: I137e38abb0e93c12406c6610c0922f4294e67290 Reviewed-on: http://review.whamcloud.com/5049 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Alex Zhuravlev Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lustre/include/dt_object.h | 2 +- lustre/include/lustre_log.h | 13 +- lustre/include/obd.h | 4 +- lustre/mgc/libmgc.c | 3 - lustre/mgc/mgc_request.c | 660 +++++++++++++++++-------------------- lustre/mgs/mgs_llog.c | 136 ++------ lustre/obdclass/llog.c | 213 +++++++----- lustre/obdclass/local_storage.c | 9 +- lustre/obdclass/local_storage.h | 3 + lustre/obdclass/lu_object.c | 8 +- lustre/obdclass/obd_mount.c | 3 + lustre/obdclass/obd_mount_server.c | 8 +- lustre/osd-ldiskfs/osd_scrub.c | 9 +- 13 files changed, 502 insertions(+), 569 deletions(-) diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index fb81d4b..477433f 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -692,7 +692,7 @@ struct local_oid_storage { struct dt_object *los_obj; /* data used to generate new fids */ - struct mutex los_id_lock; + struct mutex los_id_lock; __u64 los_seq; __u32 los_last_oid; }; diff --git a/lustre/include/lustre_log.h b/lustre/include/lustre_log.h index e4c4bcf..708d7c8 100644 --- a/lustre/include/lustre_log.h +++ b/lustre/include/lustre_log.h @@ -144,7 +144,11 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_handle **lgh, struct llog_logid *logid, char *name, enum llog_open_param open_param); 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 */ #define LLOG_FLAG_NODEAMON 0x0001 @@ -390,6 +394,13 @@ static inline int llog_data_len(int 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) { cfs_atomic_inc(&ctxt->loc_refcount); diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 73805a4..e9150ae 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -411,8 +411,8 @@ struct client_obd { /* mgc datastruct */ struct semaphore cl_mgc_sem; - struct vfsmount *cl_mgc_vfsmnt; - struct dentry *cl_mgc_configs_dir; + struct local_oid_storage *cl_mgc_los; + struct dt_object *cl_mgc_configs_dir; cfs_atomic_t cl_mgc_refcount; struct obd_export *cl_mgc_mgsexp; diff --git a/lustre/mgc/libmgc.c b/lustre/mgc/libmgc.c index ff98ece..b156ebb 100644 --- a/lustre/mgc/libmgc.c +++ b/lustre/mgc/libmgc.c @@ -99,12 +99,9 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) static int mgc_cleanup(struct obd_device *obd) { - struct client_obd *cli = &obd->u.cli; int rc; ENTRY; - LASSERT(cli->cl_mgc_vfsmnt == NULL); - ptlrpcd_decref(); rc = client_obd_cleanup(obd); diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index cd77628..e503c1b 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -41,21 +41,14 @@ #define DEBUG_SUBSYSTEM S_MGC #define D_MGC D_CONFIG /*|D_WARNING*/ -#ifdef __KERNEL__ -# include -# include -# include -# include -#else -# include -#endif - +#include #include #include #include #include -#include #include +#include + #include "mgc_internal.h" static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id, @@ -602,101 +595,191 @@ static void mgc_requeue_add(struct config_llog_data *cld) } /********************** 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; + + ENTRY; + + rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_ORIG_CTXT, disk, + &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); -static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, - struct vfsmount *mnt) + RETURN(0); +} + +static int mgc_local_llog_fini(const struct lu_env *env, + struct obd_device *obd) { - struct lvfs_run_ctxt saved; - struct lustre_sb_info *lsi = s2lsi(sb); - struct client_obd *cli = &obd->u.cli; - struct dentry *dentry; - char *label; - int err = 0; - ENTRY; + struct llog_ctxt *ctxt; + + ENTRY; + + 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 lustre_sb_info *lsi = s2lsi(sb); + struct client_obd *cli = &obd->u.cli; + struct lu_fid rfid, fid; + struct dt_object *root, *dto; + struct lu_env *env; + int rc = 0; + + ENTRY; - LASSERT(lsi); - LASSERT(lsi->lsi_srv_mnt == mnt); + LASSERT(lsi); + LASSERT(lsi->lsi_dt_dev); - /* The mgc fs exclusion sem. Only one fs can be setup at a time. */ + OBD_ALLOC_PTR(env); + if (env == NULL) + RETURN(-ENOMEM); + + /* The mgc fs exclusion sem. Only one fs can be setup at a time. */ down(&cli->cl_mgc_sem); - cfs_cleanup_group_info(); + cfs_cleanup_group_info(); - obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); - if (IS_ERR(obd->obd_fsops)) { - up(&cli->cl_mgc_sem); - CERROR("%s: No fstype %s: rc = %ld\n", lsi->lsi_fstype, - obd->obd_name, PTR_ERR(obd->obd_fsops)); - RETURN(PTR_ERR(obd->obd_fsops)); - } + /* Setup the configs dir */ + rc = lu_env_init(env, LCT_MG_THREAD); + if (rc) + GOTO(out_err, rc); - cli->cl_mgc_vfsmnt = mnt; - err = fsfilt_setup(obd, mnt->mnt_sb); - if (err) - GOTO(err_ops, err); - - OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); - obd->obd_lvfs_ctxt.pwdmnt = mnt; - obd->obd_lvfs_ctxt.pwd = mnt->mnt_root; - obd->obd_lvfs_ctxt.fs = get_ds(); - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs), - strlen(MOUNT_CONFIGS_DIR)); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); - CERROR("cannot lookup %s directory: rc = %d\n", - MOUNT_CONFIGS_DIR, err); - GOTO(err_ops, err); - } - cli->cl_mgc_configs_dir = dentry; + fid.f_seq = FID_SEQ_LOCAL_NAME; + fid.f_oid = 1; + fid.f_ver = 0; + rc = local_oid_storage_init(env, lsi->lsi_dt_dev, &fid, + &cli->cl_mgc_los); + if (rc) + GOTO(out_env, rc); - /* We take an obd ref to insure that we can't get to mgc_cleanup - without calling mgc_fs_cleanup first. */ - class_incref(obd, "mgc_fs", obd); + rc = dt_root_get(env, lsi->lsi_dt_dev, &rfid); + if (rc) + GOTO(out_env, rc); - label = fsfilt_get_label(obd, mnt->mnt_sb); - if (label) - CDEBUG(D_MGC, "MGC using disk labelled=%s\n", label); + root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid, + &cli->cl_mgc_los->los_dev->dd_lu_dev); + if (unlikely(IS_ERR(root))) + GOTO(out_los, rc = PTR_ERR(root)); - /* We keep the cl_mgc_sem until mgc_fs_cleanup */ - RETURN(0); + dto = local_file_find_or_create(env, cli->cl_mgc_los, root, + MOUNT_CONFIGS_DIR, + S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO); + lu_object_put_nocache(env, &root->do_lu); + if (IS_ERR(dto)) + GOTO(out_los, rc = PTR_ERR(dto)); -err_ops: - fsfilt_put_ops(obd->obd_fsops); - obd->obd_fsops = NULL; - cli->cl_mgc_vfsmnt = NULL; - up(&cli->cl_mgc_sem); - RETURN(err); + 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 + * without calling mgc_fs_cleanup first. */ + class_incref(obd, "mgc_fs", obd); + + /* We keep the cl_mgc_sem until mgc_fs_cleanup */ + EXIT; +out_llog: + if (rc) { + lu_object_put(env, &cli->cl_mgc_configs_dir->do_lu); + cli->cl_mgc_configs_dir = 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); + } +out_env: + lu_env_fini(env); +out_err: + OBD_FREE_PTR(env); + return rc; } static int mgc_fs_cleanup(struct obd_device *obd) { - struct client_obd *cli = &obd->u.cli; - int rc = 0; - ENTRY; + struct lu_env env; + struct client_obd *cli = &obd->u.cli; + int rc; - LASSERT(cli->cl_mgc_vfsmnt != NULL); + ENTRY; - if (cli->cl_mgc_configs_dir != NULL) { - struct lvfs_run_ctxt saved; - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - l_dput(cli->cl_mgc_configs_dir); - cli->cl_mgc_configs_dir = NULL; - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - class_decref(obd, "mgc_fs", obd); - } + LASSERT(cli->cl_mgc_los != NULL); - cli->cl_mgc_vfsmnt = NULL; - if (obd->obd_fsops) - fsfilt_put_ops(obd->obd_fsops); + rc = lu_env_init(&env, LCT_MG_THREAD); + if (rc) + GOTO(unlock, rc); + + mgc_local_llog_fini(&env, obd); + + lu_object_put_nocache(&env, &cli->cl_mgc_configs_dir->do_lu); + cli->cl_mgc_configs_dir = NULL; + + local_oid_storage_fini(&env, cli->cl_mgc_los); + cli->cl_mgc_los = NULL; + lu_env_fini(&env); +unlock: + class_decref(obd, "mgc_fs", obd); up(&cli->cl_mgc_sem); - RETURN(rc); + RETURN(0); +} + +static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd) +{ + struct llog_ctxt *ctxt; + int rc; + + ENTRY; + + /* 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); + + 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; + + ENTRY; + + ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT); + if (ctxt) + llog_cleanup(env, ctxt); + + RETURN(0); +} + + static cfs_atomic_t mgc_count = CFS_ATOMIC_INIT(0); static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) { @@ -721,7 +804,7 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) } } obd_cleanup_client_import(obd); - rc = obd_llog_finish(obd, 0); + rc = mgc_llog_fini(NULL, obd); if (rc != 0) CERROR("failed to cleanup llogging subsystems\n"); break; @@ -731,12 +814,9 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) static int mgc_cleanup(struct obd_device *obd) { - struct client_obd *cli = &obd->u.cli; int rc; ENTRY; - LASSERT(cli->cl_mgc_vfsmnt == NULL); - /* COMPAT_146 - old config logs may have added profiles we don't know about */ if (obd->obd_type->typ_refcnt <= 1) @@ -762,7 +842,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) if (rc) GOTO(err_decref, rc); - rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL); + rc = mgc_llog_init(NULL, obd); if (rc) { CERROR("failed to setup llogging subsystems\n"); GOTO(err_cleanup, rc); @@ -1045,27 +1125,21 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp, rc = mgc_target_register(exp, mti); RETURN(rc); } - if (KEY_IS(KEY_SET_FS)) { - struct super_block *sb = (struct super_block *)val; - struct lustre_sb_info *lsi; - if (vallen != sizeof(struct super_block)) - RETURN(-EINVAL); - lsi = s2lsi(sb); - rc = mgc_fs_setup(exp->exp_obd, sb, lsi->lsi_srv_mnt); - if (rc) { - CERROR("set_fs got %d\n", rc); - } - RETURN(rc); - } - if (KEY_IS(KEY_CLEAR_FS)) { - if (vallen != 0) - RETURN(-EINVAL); - rc = mgc_fs_cleanup(exp->exp_obd); - if (rc) { - CERROR("clear_fs got %d\n", rc); - } - RETURN(rc); - } + if (KEY_IS(KEY_SET_FS)) { + struct super_block *sb = (struct super_block *)val; + + if (vallen != sizeof(struct super_block)) + RETURN(-EINVAL); + + rc = mgc_fs_setup(exp->exp_obd, sb); + RETURN(rc); + } + if (KEY_IS(KEY_CLEAR_FS)) { + if (vallen != 0) + RETURN(-EINVAL); + rc = mgc_fs_cleanup(exp->exp_obd); + RETURN(rc); + } if (KEY_IS(KEY_SET_INFO)) { struct mgs_send_param *msp; @@ -1181,58 +1255,6 @@ static int mgc_import_event(struct obd_device *obd, 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; - ENTRY; - - LASSERT(olg == &obd->obd_olg); - -#ifdef HAVE_LDISKFS_OSD - rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_ORIG_CTXT, tgt, - &llog_lvfs_ops); - if (rc) - RETURN(rc); -#endif - - 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; - - ENTRY; - - 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 { CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT), CONFIG_READ_NRPAGES = 4 @@ -1587,229 +1609,155 @@ out: return rc; } -#ifdef HAVE_LDISKFS_OSD - -/* - * XXX: mgc_copy_llog() does not support osd-based llogs yet - */ - -/* identical to mgs_log_is_empty */ -static int mgc_llog_is_empty(struct obd_device *obd, struct llog_ctxt *ctxt, - char *name) -{ - struct lvfs_run_ctxt saved; - struct llog_handle *llh; - int rc = 0; - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); - if (rc == 0) { - rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL); - if (rc == 0) - rc = llog_get_size(llh); - llog_close(NULL, llh); - } else if (rc == -ENOENT) { - rc = 0; - } - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - /* header is record 1 */ - return (rc <= 1); -} - /* Copy a remote log locally */ -static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt, - struct llog_ctxt *lctxt, char *logname) +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) { - struct llog_handle *local_llh, *remote_llh; - struct obd_uuid *uuid; - char *temp_log; - int rc, rc2; - ENTRY; + char *temp_log; + int rc; - /* Write new log to a temp name, then vfs_rename over logname - upon successful completion. */ + ENTRY; - OBD_ALLOC(temp_log, strlen(logname) + 1); - if (!temp_log) - RETURN(-ENOMEM); - sprintf(temp_log, "%sT", logname); + /* + * - copy it to backup using llog_backup() + * - copy remote llog to logname using llog_backup() + * - if failed then move bakup to logname again + */ - /* Make sure there's no old temp log */ - rc = llog_erase(NULL, lctxt, NULL, temp_log); - if (rc < 0 && rc != -ENOENT) - GOTO(out, rc); + OBD_ALLOC(temp_log, strlen(logname) + 1); + if (!temp_log) + RETURN(-ENOMEM); + sprintf(temp_log, "%sT", logname); - /* open local log */ - rc = llog_open_create(NULL, lctxt, &local_llh, NULL, temp_log); - if (rc) + /* 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); - - /* set the log header uuid for fun */ - OBD_ALLOC_PTR(uuid); - obd_str2uuid(uuid, logname); - rc = llog_init_handle(NULL, local_llh, LLOG_F_IS_PLAIN, uuid); - OBD_FREE_PTR(uuid); - if (rc) - GOTO(out_closel, rc); - - /* open remote log */ - rc = llog_open(NULL, rctxt, &remote_llh, NULL, logname, - LLOG_OPEN_EXISTS); - if (rc < 0) { - if (rc == -ENOENT) - rc = 0; - GOTO(out_closel, rc); - } - - rc = llog_init_handle(NULL, remote_llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(out_closer, rc); - - /* Copy remote log */ - rc = llog_process(NULL, remote_llh, llog_copy_handler, - (void *)local_llh, NULL); - -out_closer: - rc2 = llog_close(NULL, remote_llh); - if (!rc) - rc = rc2; -out_closel: - rc2 = llog_close(NULL, local_llh); - if (!rc) - rc = rc2; - - /* We've copied the remote log to the local temp log, now - replace the old local log with the temp log. */ - if (rc == 0) { - struct client_obd *cli = &obd->u.cli; - - LASSERT(cli); - LASSERT(cli->cl_mgc_configs_dir); - rc = lustre_rename(cli->cl_mgc_configs_dir, cli->cl_mgc_vfsmnt, - temp_log, logname); - } - CDEBUG(D_MGC, "Copied remote log %s (%d)\n", logname, 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: - if (rc) - CERROR("Failed to copy remote log %s (%d)\n", logname, rc); - OBD_FREE(temp_log, strlen(logname) + 1); - RETURN(rc); + 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; } -#endif /* local_only means it cannot get remote llogs */ static int mgc_process_cfg_log(struct obd_device *mgc, - struct config_llog_data *cld, - int local_only) + struct config_llog_data *cld, int local_only) { - struct llog_ctxt *ctxt, *lctxt = NULL; -#ifdef HAVE_LDISKFS_OSD - struct client_obd *cli = &mgc->u.cli; -#endif - struct lvfs_run_ctxt *saved_ctxt; - struct lustre_sb_info *lsi = NULL; - int rc = 0, must_pop = 0; - bool sptlrpc_started = false; + struct llog_ctxt *ctxt, *lctxt = NULL; + struct client_obd *cli = &mgc->u.cli; + struct lustre_sb_info *lsi = NULL; + int rc = 0; + bool sptlrpc_started = false; + struct lu_env *env; - ENTRY; + ENTRY; - LASSERT(cld); + LASSERT(cld); LASSERT(mutex_is_locked(&cld->cld_lock)); - /* - * local copy of sptlrpc log is controlled elsewhere, don't try to - * read it up here. - */ - if (cld_is_sptlrpc(cld) && local_only) - RETURN(0); - - if (cld->cld_cfg.cfg_sb) - lsi = s2lsi(cld->cld_cfg.cfg_sb); - - ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT); - if (!ctxt) { - CERROR("missing llog context\n"); - RETURN(-EINVAL); - } + /* + * local copy of sptlrpc log is controlled elsewhere, don't try to + * read it up here. + */ + if (cld_is_sptlrpc(cld) && local_only) + RETURN(0); - OBD_ALLOC_PTR(saved_ctxt); - if (saved_ctxt == NULL) - RETURN(-ENOMEM); + if (cld->cld_cfg.cfg_sb) + lsi = s2lsi(cld->cld_cfg.cfg_sb); - lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT); + OBD_ALLOC_PTR(env); + if (env == NULL) + RETURN(-ENOMEM); -#ifdef HAVE_LDISKFS_OSD - /* - * XXX: at the moment mgc_copy_llog() works with lvfs-based llogs - */ - /* 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) && - (lsi->lsi_srv_mnt == cli->cl_mgc_vfsmnt) && - !IS_MGS(lsi) && lsi->lsi_srv_mnt) { - push_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL); - must_pop++; - if (!local_only) - /* Only try to copy log if we have the lock. */ - rc = mgc_copy_llog(mgc, ctxt, lctxt, cld->cld_logname); - if (local_only || rc) { - if (mgc_llog_is_empty(mgc, 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 -#endif - if (local_only) { /* no local log at client side */ - GOTO(out_pop, rc = -EIO); - } + 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); + + /* 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) && + cli->cl_mgc_configs_dir != NULL && + lu2dt_dev(cli->cl_mgc_configs_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); + } - if (cld_is_sptlrpc(cld)) { - sptlrpc_conf_log_update_begin(cld->cld_logname); - sptlrpc_started = true; - } + if (cld_is_sptlrpc(cld)) { + sptlrpc_conf_log_update_begin(cld->cld_logname); + sptlrpc_started = true; + } - /* logname and instance info should be the same, so use our - copy of the instance for the update. The cfg_last_idx will - be updated here. */ - rc = class_config_parse_llog(NULL, ctxt, cld->cld_logname, + /* logname and instance info should be the same, so use our + * copy of the instance for the update. The cfg_last_idx will + * be updated here. */ + rc = class_config_parse_llog(env, ctxt, cld->cld_logname, &cld->cld_cfg); - EXIT; + EXIT; out_pop: - llog_ctxt_put(ctxt); - if (lctxt) - llog_ctxt_put(lctxt); - if (must_pop) - pop_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL); + __llog_ctxt_put(env, ctxt); + if (lctxt) + __llog_ctxt_put(env, lctxt); - OBD_FREE_PTR(saved_ctxt); - /* - * update settings on existing OBDs. doing it inside - * of llog_process_lock so no device is attaching/detaching - * in parallel. - * the logname must be -sptlrpc - */ - if (sptlrpc_started) { - LASSERT(cld_is_sptlrpc(cld)); - sptlrpc_conf_log_update_end(cld->cld_logname); - class_notify_sptlrpc_conf(cld->cld_logname, - strlen(cld->cld_logname) - - strlen("-sptlrpc")); - } + /* + * update settings on existing OBDs. doing it inside + * of llog_process_lock so no device is attaching/detaching + * in parallel. + * the logname must be -sptlrpc + */ + if (sptlrpc_started) { + LASSERT(cld_is_sptlrpc(cld)); + sptlrpc_conf_log_update_end(cld->cld_logname); + class_notify_sptlrpc_conf(cld->cld_logname, + strlen(cld->cld_logname) - + strlen("-sptlrpc")); + } - RETURN(rc); + lu_env_fini(env); +out_free: + OBD_FREE_PTR(env); + return rc; } /** Get a config log from the MGS and process it. @@ -1998,8 +1946,6 @@ struct obd_ops mgc_obd_ops = { .o_set_info_async = mgc_set_info_async, .o_get_info = mgc_get_info, .o_import_event = mgc_import_event, - .o_llog_init = mgc_llog_init, - .o_llog_finish = mgc_llog_finish, .o_process_config = mgc_process_config, }; diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index d84d3fe..baaec4a 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -947,7 +947,6 @@ static int mgs_replace_handler(const struct lu_env *env, struct llog_rec_hdr *rec, void *data) { - struct llog_rec_hdr local_rec = *rec; struct mgs_replace_uuid_lookup *mrul; struct lustre_cfg *lcfg = REC_DATA(rec); int cfg_len = REC_DATA_LEN(rec); @@ -994,9 +993,7 @@ static int mgs_replace_handler(const struct lu_env *env, RETURN(0); copy_out: /* Record is placed in temporary llog as is */ - local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail); - rc = llog_write(env, mrul->temp_llh, &local_rec, NULL, 0, - (void *)lcfg, -1); + rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1); CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n", rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, @@ -1010,83 +1007,20 @@ skip_out: RETURN(rc); } -static int mgs_backup_llog(const struct lu_env *env, - struct obd_device *mgs, - char *fsname, char *backup) +static int mgs_log_is_empty(const struct lu_env *env, + struct mgs_device *mgs, char *name) { - struct obd_uuid *uuid; - struct llog_handle *orig_llh, *bak_llh; - struct llog_ctxt *lctxt; - int rc, rc2; - ENTRY; - - lctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT); - if (!lctxt) { - CERROR("%s: missing llog context\n", mgs->obd_name); - GOTO(out, rc = -EINVAL); - } - - /* Make sure there's no old backup log */ - rc = llog_erase(env, lctxt, NULL, backup); - if (rc < 0 && rc != -ENOENT) - GOTO(out_put, rc); - - /* open backup log */ - rc = llog_open_create(env, lctxt, &bak_llh, NULL, backup); - if (rc) { - CERROR("%s: backup logfile open %s: rc = %d\n", - mgs->obd_name, backup, rc); - GOTO(out_put, rc); - } - - /* set the log header uuid */ - OBD_ALLOC_PTR(uuid); - if (uuid == NULL) - GOTO(out_put, rc = -ENOMEM); - obd_str2uuid(uuid, backup); - rc = llog_init_handle(env, bak_llh, LLOG_F_IS_PLAIN, uuid); - OBD_FREE_PTR(uuid); - if (rc) - GOTO(out_close1, rc); - - /* open original log */ - rc = llog_open(env, lctxt, &orig_llh, NULL, fsname, - LLOG_OPEN_EXISTS); - if (rc < 0) { - if (rc == -ENOENT) - rc = 0; - GOTO(out_close1, rc); - } - - rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(out_close2, rc); + struct llog_ctxt *ctxt; + int rc; - /* Copy remote log */ - rc = llog_process(env, orig_llh, llog_copy_handler, - (void *)bak_llh, NULL); + ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); + LASSERT(ctxt != NULL); -out_close2: - rc2 = llog_close(env, orig_llh); - if (!rc) - rc = rc2; -out_close1: - rc2 = llog_close(env, bak_llh); - if (!rc) - rc = rc2; -out_put: - if (lctxt) - llog_ctxt_put(lctxt); -out: - if (rc) - CERROR("%s: Failed to backup log %s: rc = %d\n", - mgs->obd_name, fsname, rc); - RETURN(rc); + rc = llog_is_empty(env, ctxt, name); + llog_ctxt_put(ctxt); + return rc; } -static int mgs_log_is_empty(const struct lu_env *env, struct mgs_device *mgs, - char *name); - static int mgs_replace_nids_log(const struct lu_env *env, struct obd_device *mgs, struct fs_db *fsdb, char *logname, char *devname, char *nids) @@ -1116,19 +1050,19 @@ static int mgs_replace_nids_log(const struct lu_env *env, sprintf(backup, "%s.bak", logname); - rc = mgs_backup_llog(env, mgs, logname, backup); - if (rc < 0) { + rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup); + if (rc == 0) { + /* Now erase original log file. Connections are not allowed. + Backup is already saved */ + rc = llog_erase(env, ctxt, NULL, logname); + if (rc < 0) + GOTO(out_free, rc); + } else if (rc != -ENOENT) { CERROR("%s: can't make backup for %s: rc = %d\n", mgs->obd_name, logname, rc); GOTO(out_free,rc); } - /* Now erase original log file. Connections are not allowed. - Backup is already saved */ - rc = llog_erase(env, ctxt, NULL, logname); - if (rc < 0 && rc != -ENOENT) - GOTO(out_free, rc); - /* open local log */ rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname); if (rc) @@ -1177,7 +1111,8 @@ out_restore: if (rc) { CERROR("%s: llog should be restored: rc = %d\n", mgs->obd_name, rc); - rc2 = mgs_backup_llog(env, mgs, backup, logname); + rc2 = llog_backup(env, mgs, ctxt, ctxt, backup, + logname); if (rc2 < 0) CERROR("%s: can't restore backup %s: rc = %d\n", mgs->obd_name, logname, rc2); @@ -1468,35 +1403,6 @@ static int record_end_log(const struct lu_env *env, struct llog_handle **llh) return rc; } -static int mgs_log_is_empty(const struct lu_env *env, - struct mgs_device *mgs, char *name) -{ - struct llog_handle *llh; - struct llog_ctxt *ctxt; - int rc = 0; - - ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); - LASSERT(ctxt != NULL); - rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); - if (rc < 0) { - if (rc == -ENOENT) - rc = 0; - GOTO(out_ctxt, 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_ctxt: - llog_ctxt_put(ctxt); - /* header is record 1 */ - return (rc <= 1); -} - /******************** config "macros" *********************/ /* write an lcfg directly into a log (with markers) */ @@ -4052,5 +3958,3 @@ out_label: OBD_FREE(label, label_sz); return rc; } - - diff --git a/lustre/obdclass/llog.c b/lustre/obdclass/llog.c index 2cd9598..9477fbb 100644 --- a/lustre/obdclass/llog.c +++ b/lustre/obdclass/llog.c @@ -270,32 +270,6 @@ out: } 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; - ENTRY; - - /* 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) { struct llog_process_info *lpi = arg; @@ -510,14 +484,6 @@ int llog_process(const struct lu_env *env, struct llog_handle *loghandle, } 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, struct llog_handle *loghandle, llog_cb_t cb, void *data, void *catdata) @@ -799,8 +765,9 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_handle **res, struct llog_logid *logid, char *name) { - struct thandle *th; - int rc; + struct dt_device *d; + struct thandle *th; + int rc; ENTRY; @@ -811,27 +778,21 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, if (llog_exist(*res)) RETURN(0); - if ((*res)->lgh_obj != NULL) { - struct dt_device *d; + LASSERT((*res)->lgh_obj != NULL); - d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev); + d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev); - th = dt_trans_create(env, d); - if (IS_ERR(th)) - GOTO(out, rc = PTR_ERR(th)); + th = dt_trans_create(env, d); + if (IS_ERR(th)) + GOTO(out, rc = PTR_ERR(th)); - rc = llog_declare_create(env, *res, th); - if (rc == 0) { - rc = dt_trans_start_local(env, d, th); - if (rc == 0) - rc = llog_create(env, *res, th); - } - dt_trans_stop(env, d, th); - } else { - /* lvfs compat code */ - LASSERT((*res)->lgh_file == NULL); - rc = llog_create(env, *res, NULL); + rc = llog_declare_create(env, *res, th); + if (rc == 0) { + rc = dt_trans_start_local(env, d, th); + if (rc == 0) + rc = llog_create(env, *res, th); } + dt_trans_stop(env, d, th); out: if (rc) llog_close(env, *res); @@ -878,43 +839,36 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle, struct llog_rec_hdr *rec, struct llog_cookie *reccookie, int cookiecount, void *buf, int idx) { - int rc; + struct dt_device *dt; + struct thandle *th; + int rc; ENTRY; LASSERT(loghandle); 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); - th = dt_trans_create(env, dt); - if (IS_ERR(th)) - RETURN(PTR_ERR(th)); + th = dt_trans_create(env, dt); + if (IS_ERR(th)) + RETURN(PTR_ERR(th)); - rc = llog_declare_write_rec(env, loghandle, rec, idx, th); - if (rc) - GOTO(out_trans, rc); + rc = llog_declare_write_rec(env, loghandle, rec, idx, th); + if (rc) + GOTO(out_trans, rc); - rc = dt_trans_start_local(env, dt, th); - if (rc) - GOTO(out_trans, rc); + rc = dt_trans_start_local(env, dt, th); + if (rc) + GOTO(out_trans, rc); - down_write(&loghandle->lgh_lock); - rc = llog_write_rec(env, loghandle, rec, reccookie, - cookiecount, buf, idx, th); - up_write(&loghandle->lgh_lock); + down_write(&loghandle->lgh_lock); + rc = llog_write_rec(env, loghandle, rec, reccookie, + cookiecount, buf, idx, th); + up_write(&loghandle->lgh_lock); out_trans: - 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); - } + dt_trans_stop(env, dt, th); RETURN(rc); } EXPORT_SYMBOL(llog_write); @@ -974,3 +928,104 @@ out: RETURN(rc); } 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; + + ENTRY; + + /* 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); diff --git a/lustre/obdclass/local_storage.c b/lustre/obdclass/local_storage.c index 26a3137..7f41304 100644 --- a/lustre/obdclass/local_storage.c +++ b/lustre/obdclass/local_storage.c @@ -867,9 +867,12 @@ out_los: (*los)->los_seq = fid_seq(first_fid); (*los)->los_last_oid = le64_to_cpu(lastid); (*los)->los_obj = o; - /* read value should not be less than initial one */ - LASSERTF((*los)->los_last_oid >= first_oid, "%u < %u\n", - (*los)->los_last_oid, first_oid); + /* Read value should not be less than initial one + * but possible after upgrade from older fs. + * 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: mutex_unlock(&ls->ls_los_mutex); diff --git a/lustre/obdclass/local_storage.h b/lustre/obdclass/local_storage.h index 9f50128..f7d6c9a 100644 --- a/lustre/obdclass/local_storage.h +++ b/lustre/obdclass/local_storage.h @@ -29,6 +29,8 @@ * * Author: Mikhail Pershin */ +#ifndef __LOCAL_STORAGE_H +#define __LOCAL_STORAGE_H #include #include @@ -87,3 +89,4 @@ struct los_ondisk { #define LOS_MAGIC 0xdecafbee +#endif diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c index 084506c..ba45a0d 100644 --- a/lustre/obdclass/lu_object.c +++ b/lustre/obdclass/lu_object.c @@ -425,10 +425,10 @@ LU_KEY_INIT_FINI(lu_global, struct lu_cdebug_data); * lu_global_init(). */ struct lu_context_key lu_global_key = { - .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD | - LCT_MG_THREAD | LCT_CL_THREAD, - .lct_init = lu_global_key_init, - .lct_fini = lu_global_key_fini + .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD | + LCT_MG_THREAD | LCT_CL_THREAD | LCT_LOCAL, + .lct_init = lu_global_key_init, + .lct_fini = lu_global_key_fini }; /** diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index 425336c..922e877 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -639,6 +639,9 @@ int lustre_put_lsi(struct super_block *sb) CDEBUG(D_MOUNT, "put %p %d\n", sb, cfs_atomic_read(&lsi->lsi_mounts)); if (cfs_atomic_dec_and_test(&lsi->lsi_mounts)) { 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); /* wait till OSD is gone */ obd_zombie_barrier(); diff --git a/lustre/obdclass/obd_mount_server.c b/lustre/obdclass/obd_mount_server.c index 9b8b144..9137219 100644 --- a/lustre/obdclass/obd_mount_server.c +++ b/lustre/obdclass/obd_mount_server.c @@ -1663,14 +1663,18 @@ static int osd_start(struct lustre_sb_info *lsi, unsigned long mflags) obd->obd_force = 1; class_manual_cleanup(obd); lsi->lsi_dt_dev = NULL; + RETURN(rc); } - /* XXX: to keep support old components relying on lsi_srv_mnt - * we get this info from OSD just started */ LASSERT(obd->obd_lu_dev); + lu_device_get(obd->obd_lu_dev); lsi->lsi_dt_dev = lu2dt_dev(obd->obd_lu_dev); LASSERT(lsi->lsi_dt_dev); + /* set disk context for llog usage */ + OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); + obd->obd_lvfs_ctxt.dt = lsi->lsi_dt_dev; + dt_conf_get(NULL, lsi->lsi_dt_dev, &p); lsi->lsi_srv_mnt = p.ddp_mnt; diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 72ed5b8..98a3b24 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -1021,7 +1021,7 @@ static int osd_scrub_main(void *args) int rc; ENTRY; - rc = lu_env_init(&env, LCT_DT_THREAD); + rc = lu_env_init(&env, LCT_LOCAL); if (rc != 0) { CERROR("%.16s: OI scrub, fail to init env, rc = %d\n", LDISKFS_SB(sb)->s_es->s_volume_name, rc); @@ -1796,6 +1796,13 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) rc = osd_scrub_start(dev); } + /* it is possible that dcache entries may keep objects after they are + * deleted by OSD. While it looks safe this can cause object data to + * stay until umount causing failures in tests calculating free space, + * e.g. replay-ost-single. Since those dcache entries are not used + * anymore let's just free them after use here */ + shrink_dcache_sb(sb); + RETURN(rc); } -- 1.8.3.1