From: Fan Yong Date: Sun, 3 Apr 2016 13:10:48 +0000 (+0800) Subject: LU-8048 mgc: use the same lu_env for mgc_fs_{set,clean}up X-Git-Tag: 2.8.54~72 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=eaab0922aaaec6d68a2c8121220eb5ca21f186d3 LU-8048 mgc: use the same lu_env for mgc_fs_{set,clean}up Originally, the mgc_fs_setup() and mgc_fs_cleanup use each own lu_env. Sometimes the mgc_fs_cleanup() may fail to prepare the lu_env. Such failure will cause local_oid_storage_fini() to be skipped as to object leak found when osd_device_free(). This patch prepares the lu_env before calling mgs_fs_setup(), then mgc_fs_setup() and mgc_fs_cleanup() can share the lu_env and no need to worry about the failures in mgc_fs_cleanup(). Signed-off-by: Fan Yong Change-Id: I7062abd670c53e93f456a8d8f1f6131d7ee92320 Reviewed-on: http://review.whamcloud.com/19692 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Dmitry Eremin Reviewed-by: Niu Yawei Reviewed-by: Oleg Drokin --- diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 0d1ea9f..6f65aa9 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -711,13 +711,13 @@ static int mgc_local_llog_fini(const struct lu_env *env, RETURN(0); } -static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb) +static int mgc_fs_setup(const struct lu_env *env, 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; @@ -725,29 +725,21 @@ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb) LASSERT(lsi); LASSERT(lsi->lsi_dt_dev); - OBD_ALLOC_PTR(env); - if (env == NULL) - RETURN(-ENOMEM); - /* The mgc fs exclusion mutex. Only one fs can be setup at a time. */ mutex_lock(&cli->cl_mgc_mutex); /* Setup the configs dir */ - rc = lu_env_init(env, LCT_MG_THREAD); - if (rc) - GOTO(out_err, rc); - 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); + RETURN(rc); rc = dt_root_get(env, lsi->lsi_dt_dev, &rfid); if (rc) - GOTO(out_env, rc); + GOTO(out_los, rc); root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid, &cli->cl_mgc_los->los_dev->dd_lu_dev, NULL); @@ -785,37 +777,24 @@ out_los: cli->cl_mgc_los = NULL; mutex_unlock(&cli->cl_mgc_mutex); } -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(const struct lu_env *env, struct obd_device *obd) { - struct lu_env env; struct client_obd *cli = &obd->u.cli; - int rc; - ENTRY; LASSERT(cli->cl_mgc_los != NULL); - rc = lu_env_init(&env, LCT_MG_THREAD); - if (rc) - GOTO(unlock, rc); - - mgc_local_llog_fini(&env, obd); + mgc_local_llog_fini(env, obd); - lu_object_put_nocache(&env, &cli->cl_mgc_configs_dir->do_lu); + 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); + 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); mutex_unlock(&cli->cl_mgc_mutex); @@ -1219,13 +1198,13 @@ static int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp, if (vallen != sizeof(struct super_block)) RETURN(-EINVAL); - rc = mgc_fs_setup(exp->exp_obd, sb); + rc = mgc_fs_setup(env, exp->exp_obd, sb); RETURN(rc); } if (KEY_IS(KEY_CLEAR_FS)) { if (vallen != 0) RETURN(-EINVAL); - rc = mgc_fs_cleanup(exp->exp_obd); + rc = mgc_fs_cleanup(env, exp->exp_obd); RETURN(rc); } if (KEY_IS(KEY_SET_INFO)) { diff --git a/lustre/obdclass/obd_mount_server.c b/lustre/obdclass/obd_mount_server.c index 5a70b89..c8c90ec 100644 --- a/lustre/obdclass/obd_mount_server.c +++ b/lustre/obdclass/obd_mount_server.c @@ -292,7 +292,8 @@ static int server_stop_mgs(struct super_block *sb) /* Since there's only one mgc per node, we have to change it's fs to get access to the right disk. */ -static int server_mgc_set_fs(struct obd_device *mgc, struct super_block *sb) +static int server_mgc_set_fs(const struct lu_env *env, + struct obd_device *mgc, struct super_block *sb) { struct lustre_sb_info *lsi = s2lsi(sb); int rc; @@ -301,7 +302,7 @@ static int server_mgc_set_fs(struct obd_device *mgc, struct super_block *sb) CDEBUG(D_MOUNT, "Set mgc disk for %s\n", lsi->lsi_lmd->lmd_dev); /* cl_mgc_sem in mgc insures we sleep if the mgc_fs is busy */ - rc = obd_set_info_async(NULL, mgc->obd_self_export, + rc = obd_set_info_async(env, mgc->obd_self_export, sizeof(KEY_SET_FS), KEY_SET_FS, sizeof(*sb), sb, NULL); if (rc != 0) @@ -310,14 +311,15 @@ static int server_mgc_set_fs(struct obd_device *mgc, struct super_block *sb) RETURN(rc); } -static int server_mgc_clear_fs(struct obd_device *mgc) +static int server_mgc_clear_fs(const struct lu_env *env, + struct obd_device *mgc) { int rc; ENTRY; CDEBUG(D_MOUNT, "Unassign mgc disk\n"); - rc = obd_set_info_async(NULL, mgc->obd_self_export, + rc = obd_set_info_async(env, mgc->obd_self_export, sizeof(KEY_CLEAR_FS), KEY_CLEAR_FS, 0, NULL, NULL); RETURN(rc); @@ -1239,7 +1241,7 @@ static int server_start_targets(struct super_block *sb) struct obd_device *obd; struct lustre_sb_info *lsi = s2lsi(sb); struct config_llog_instance cfg; - struct lu_env env; + struct lu_env mgc_env; struct lu_device *dev; int rc; ENTRY; @@ -1283,11 +1285,15 @@ static int server_start_targets(struct super_block *sb) mutex_unlock(&server_start_lock); } + rc = lu_env_init(&mgc_env, LCT_MG_THREAD); + if (rc != 0) + GOTO(out_stop_service, rc); + /* Set the mgc fs to our server disk. This allows the MGC to * read and write configs locally, in case it can't talk to the MGS. */ - rc = server_mgc_set_fs(lsi->lsi_mgc, sb); + rc = server_mgc_set_fs(&mgc_env, lsi->lsi_mgc, sb); if (rc) - GOTO(out_stop_service, rc); + GOTO(out_env, rc); /* Register with MGS */ rc = server_register_target(lsi); @@ -1339,6 +1345,8 @@ static int server_start_targets(struct super_block *sb) /* log has been fully processed, let clients connect */ dev = obd->obd_lu_dev; if (dev && dev->ld_ops->ldo_prepare) { + struct lu_env env; + rc = lu_env_init(&env, dev->ld_type->ldt_ctx_tags); if (rc == 0) { struct lu_context session_ctx; @@ -1366,8 +1374,9 @@ static int server_start_targets(struct super_block *sb) out_mgc: /* Release the mgc fs for others to use */ - server_mgc_clear_fs(lsi->lsi_mgc); - + server_mgc_clear_fs(&mgc_env, lsi->lsi_mgc); +out_env: + lu_env_fini(&mgc_env); out_stop_service: if (rc != 0) server_stop_servers(lsi->lsi_flags);