From: Fan Yong Date: Wed, 8 Apr 2015 13:31:02 +0000 (+0800) Subject: LU-6351 lfsck: check object existence before using it X-Git-Tag: 2.7.53~36 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=f3ea0cea6bb6766eaa55571774b9ae942a6bf297;hp=5b3eef20c5a0e31d2cd9580f0cbaa0223783905a LU-6351 lfsck: check object existence before using it Under some cases, when the LFSCK locate the object via its FID, it does not check whether it exists or not, then further using such object may access NULL-pointed local object (inode). Signed-off-by: Fan Yong Change-Id: I637eb9bc8c3e283394c8bf9e1250d83659c5e5ba Reviewed-on: http://review.whamcloud.com/14009 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index cd519fc..d1b66a8 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -557,7 +557,7 @@ static int lfsck_namespace_init(const struct lu_env *env, * trace file * \param[in] add true if add new flags, otherwise remove flags * - * \retval 0 for succeed or nothing to be done + * \retval 0 for success or nothing to be done * \retval negative error number on failure */ int lfsck_namespace_trace_update(const struct lu_env *env, @@ -2150,7 +2150,7 @@ log: "entry for: parent "DFID", child "DFID", name %s, type " "in name entry %o, type claimed by child %o. repair it " "by %s with new name2 %s: rc = %d\n", lfsck_lfsck2name(lfsck), - PFID(lfsck_dto2fid(parent)), PFID(lfsck_dto2fid(child)), + PFID(lfsck_dto2fid(parent)), PFID(cfid), name, type, update ? lfsck_object_type(child) : 0, update ? "updating" : "removing", name2, rc); @@ -4539,7 +4539,7 @@ static int lfsck_namespace_in_notify(const struct lu_env *env, struct lfsck_assistant_data *lad = com->lc_data; struct lfsck_tgt_descs *ltds = &lfsck->li_mdt_descs; struct lfsck_tgt_desc *ltd; - int rc; + int rc = 0; bool fail = false; ENTRY; @@ -4630,7 +4630,10 @@ log: if (IS_ERR(obj)) RETURN(PTR_ERR(obj)); - rc = lfsck_namespace_notify_lmv_master_local(env, com, obj); + if (likely(dt_object_exists(obj))) + rc = lfsck_namespace_notify_lmv_master_local(env, com, + obj); + lfsck_object_put(env, obj); RETURN(rc > 0 ? 0 : rc); @@ -5390,7 +5393,7 @@ out: rc = lfsck_namespace_repair_bad_name_hash(env, com, dir, lnr->lnr_lmv, lnr->lnr_name); - if (rc >= 0) + if (rc == 0) bad_hash = true; } diff --git a/lustre/lfsck/lfsck_striped_dir.c b/lustre/lfsck/lfsck_striped_dir.c index d9c7c39..8ed965c 100644 --- a/lustre/lfsck/lfsck_striped_dir.c +++ b/lustre/lfsck/lfsck_striped_dir.c @@ -196,7 +196,7 @@ void lfsck_lmv_put(const struct lu_env *env, struct lfsck_lmv *llmv) * \param[in] del_lmv true if need to drop the LMV EA * * \retval positive number if nothing to be done - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ static int lfsck_disable_master_lmv(const struct lu_env *env, @@ -295,7 +295,7 @@ static inline bool lfsck_is_valid_slave_lmv(struct lmv_mds_md_v1 *lmv) * striped directory to be handled and other information * * \retval positive number if nothing to be done - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ static int lfsck_remove_lmv(const struct lu_env *env, @@ -379,7 +379,7 @@ static int lfsck_remove_dirent(const struct lu_env *env, * \param[in] index the old shard's index in the striped directory * \param[in] flags the new shard's flags in the @lslr slot * - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ static int lfsck_replace_lmv(const struct lu_env *env, @@ -476,7 +476,7 @@ static int lfsck_replace_lmv(const struct lu_env *env, * we define the max depth can be called recursively * (LFSCK_REC_LMV_MAX_DEPTH) * - * \retval zero for succeed + * \retval zero for success * \retval "-ERANGE" for invalid @shard_idx * \retval "-EEXIST" for the required lslr slot has been * occupied by other shard @@ -1191,7 +1191,7 @@ out: * \param[in] index the MDT index on which the LFSCK instance to be notified * * \retval positive number if nothing to be done - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ static int lfsck_namespace_notify_lmv_remote(const struct lu_env *env, @@ -1258,7 +1258,7 @@ out: * \param[in] obj pointer to the striped directory to be rescanned * * \retval positive number if nothing to be done - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ int lfsck_namespace_notify_lmv_master_local(const struct lu_env *env, @@ -1353,7 +1353,7 @@ int lfsck_namespace_notify_lmv_master_local(const struct lu_env *env, * \param[in] flags to indicate which element(s) in the LMV EA will be set * * \retval positive number if nothing to be done - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ static int lfsck_namespace_set_lmv_master(const struct lu_env *env, @@ -1467,7 +1467,7 @@ log: * \param[in] name the name of the bad name hash * * \retval positive number if nothing to be done - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ int lfsck_namespace_repair_bad_name_hash(const struct lu_env *env, @@ -1493,6 +1493,12 @@ int lfsck_namespace_repair_bad_name_hash(const struct lu_env *env, if (IS_ERR(parent)) GOTO(log, rc = PTR_ERR(parent)); + if (unlikely(!dt_object_exists(parent))) + /* The parent object was previously accessed when verifying + * the slave LMV EA. If this condition is true it is because + * the striped directory is being removed. */ + GOTO(log, rc = 1); + *lmv2 = llmv->ll_lmv; lmv2->lmv_hash_type = LMV_HASH_TYPE_UNKNOWN | LMV_HASH_FLAG_BAD_TYPE; rc = lfsck_namespace_set_lmv_master(env, com, parent, lmv2, @@ -1613,7 +1619,7 @@ int lfsck_namespace_scan_shard(const struct lu_env *env, ns->ln_flags |= LF_INCONSISTENT; rc = lfsck_namespace_repair_bad_name_hash(env, com, child, llmv, ent->lde_name); - if (rc >= 0) + if (rc == 0) ns->ln_name_hash_repaired++; } @@ -1659,7 +1665,8 @@ out: * \param[in] obj pointer to the object which LMV EA will be checked * \param[in] llmv pointer to buffer holding the slave LMV EA * - * \retval zero for succeed + * \retval positive number if nothing to be done + * \retval zero for success * \retval negative error number on failure */ int lfsck_namespace_verify_stripe_slave(const struct lu_env *env, @@ -1704,6 +1711,9 @@ int lfsck_namespace_verify_stripe_slave(const struct lu_env *env, GOTO(out, rc); } + if (unlikely(!dt_object_exists(parent))) + GOTO(out, rc = 1); + if (unlikely(!dt_try_as_dir(env, parent))) GOTO(out, rc = -ENOTDIR); @@ -1801,7 +1811,7 @@ out: * \param[in] lnr pointer to the namespace request that contains the * striped directory or the shard * - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env, @@ -2232,7 +2242,7 @@ out: * \param[in] lnr pointer to the namespace request that contains the * shard's name, parent object, parent's LMV, and ect. * - * \retval zero for succeed + * \retval zero for success * \retval negative error number on failure */ int lfsck_namespace_handle_striped_master(const struct lu_env *env,