Whamcloud - gitweb
LU-6351 lfsck: check object existence before using it 09/14009/7
authorFan Yong <fan.yong@intel.com>
Wed, 8 Apr 2015 13:31:02 +0000 (21:31 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 28 Apr 2015 05:12:29 +0000 (05:12 +0000)
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 <fan.yong@intel.com>
Change-Id: I637eb9bc8c3e283394c8bf9e1250d83659c5e5ba
Reviewed-on: http://review.whamcloud.com/14009
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lfsck/lfsck_namespace.c
lustre/lfsck/lfsck_striped_dir.c

index cd519fc..d1b66a8 100644 (file)
@@ -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;
        }
 
index d9c7c39..8ed965c 100644 (file)
@@ -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,