Whamcloud - gitweb
LU-8929 lfsck: dumper gets current position properly
[fs/lustre-release.git] / lustre / lfsck / lfsck_striped_dir.c
index 663bc55..857953a 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2014, Intel Corporation.
+ * Copyright (c) 2014, 2015, Intel Corporation.
  */
 /*
  * 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,
@@ -238,16 +238,16 @@ static int lfsck_disable_master_lmv(const struct lu_env *env,
                GOTO(unlock, rc = 0);
 
        if (del_lmv) {
-               rc = dt_xattr_del(env, obj, XATTR_NAME_LMV, th, BYPASS_CAPA);
+               rc = dt_xattr_del(env, obj, XATTR_NAME_LMV, th);
                if (rc != 0)
                        GOTO(unlock, rc);
        }
 
-       rc = dt_attr_get(env, obj, la, BYPASS_CAPA);
+       rc = dt_attr_get(env, obj, la);
        if (rc == 0 && !(la->la_flags & LUSTRE_IMMUTABLE_FL)) {
                la->la_valid = LA_FLAGS;
                la->la_flags |= LUSTRE_IMMUTABLE_FL;
-               rc = dt_attr_set(env, obj, la, th, BYPASS_CAPA);
+               rc = dt_attr_set(env, obj, la, th);
        }
 
        GOTO(unlock, rc);
@@ -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
@@ -845,7 +845,7 @@ int lfsck_read_stripe_lmv(const struct lu_env *env, struct dt_object *obj,
 
        dt_read_lock(env, obj, 0);
        rc = dt_xattr_get(env, obj, lfsck_buf_get(env, lmv, sizeof(*lmv)),
-                         XATTR_NAME_LMV, BYPASS_CAPA);
+                         XATTR_NAME_LMV);
        dt_read_unlock(env, obj);
        if (rc != sizeof(*lmv))
                return rc > 0 ? -EINVAL : rc;
@@ -1043,7 +1043,7 @@ int lfsck_namespace_update_lmv(const struct lu_env *env,
        if (lfsck->li_bookmark_ram.lb_param & LPF_DRYRUN)
                GOTO(unlock, rc = 0);
 
-       rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMV, 0, th, BYPASS_CAPA);
+       rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMV, 0, th);
 
        GOTO(unlock, rc);
 
@@ -1112,7 +1112,7 @@ static int lfsck_allow_regenerate_master_lmv(const struct lu_env *env,
        snprintf(info->lti_tmpbuf, sizeof(info->lti_tmpbuf), DFID":%u",
                 PFID(cfid), cidx);
        rc = dt_lookup(env, obj, (struct dt_rec *)tfid,
-                      (const struct dt_key *)info->lti_tmpbuf, BYPASS_CAPA);
+                      (const struct dt_key *)info->lti_tmpbuf);
        if (rc != 0)
                RETURN(rc);
 
@@ -1121,7 +1121,7 @@ static int lfsck_allow_regenerate_master_lmv(const struct lu_env *env,
 
        args = lfsck->li_args_dir & ~(LUDA_VERIFY | LUDA_VERIFY_DRYRUN);
        iops = &obj->do_index_ops->dio_it;
-       di = iops->init(env, obj, args, BYPASS_CAPA);
+       di = iops->init(env, obj, args);
        if (IS_ERR(di))
                RETURN(PTR_ERR(di));
 
@@ -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,
@@ -1485,7 +1485,7 @@ int lfsck_namespace_repair_bad_name_hash(const struct lu_env *env,
        ENTRY;
 
        rc = dt_lookup(env, shard, (struct dt_rec *)pfid,
-                      (const struct dt_key *)dotdot, BYPASS_CAPA);
+                      (const struct dt_key *)dotdot);
        if (rc != 0 || !fid_is_sane(pfid))
                GOTO(log, rc);
 
@@ -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,
@@ -1578,7 +1584,7 @@ int lfsck_namespace_scan_shard(const struct lu_env *env,
 
        args = lfsck->li_args_dir & ~(LUDA_VERIFY | LUDA_VERIFY_DRYRUN);
        iops = &child->do_index_ops->dio_it;
-       di = iops->init(env, child, args, BYPASS_CAPA);
+       di = iops->init(env, child, args);
        if (IS_ERR(di))
                GOTO(out, rc = PTR_ERR(di));
 
@@ -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,
@@ -1688,7 +1695,7 @@ int lfsck_namespace_verify_stripe_slave(const struct lu_env *env,
        }
 
        rc = dt_lookup(env, obj, (struct dt_rec *)pfid,
-                      (const struct dt_key *)dotdot, BYPASS_CAPA);
+                      (const struct dt_key *)dotdot);
        if (rc != 0 || !fid_is_sane(pfid)) {
                rc = lfsck_namespace_trace_update(env, com, cfid,
                                        LNTF_UNCERTAIN_LMV, true);
@@ -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);
 
@@ -1764,7 +1774,7 @@ int lfsck_namespace_verify_stripe_slave(const struct lu_env *env,
        }
 
        rc = dt_lookup(env, parent, (struct dt_rec *)&tfid,
-                      (const struct dt_key *)name2, BYPASS_CAPA);
+                      (const struct dt_key *)name2);
        if (rc != 0 || !lu_fid_eq(cfid, &tfid))
                rc = lfsck_namespace_trace_update(env, com, cfid,
                                                  LNTF_UNCERTAIN_LMV, true);
@@ -1798,17 +1808,14 @@ out:
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
- * \paran[in] dir      pointer to the striped directory or its shard to be
- *                     rescanned
  * \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,
                                       struct lfsck_component *com,
-                                      struct dt_object *dir,
                                       struct lfsck_namespace_req *lnr)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
@@ -1817,7 +1824,10 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
        struct lfsck_lmv                *llmv   = lnr->lnr_lmv;
        struct lmv_mds_md_v1            *lmv    = &llmv->ll_lmv;
        struct lmv_mds_md_v1            *lmv2   = &info->lti_lmv2;
-       const struct lu_fid             *pfid   = lfsck_dto2fid(dir);
+       struct lfsck_assistant_object   *lso    = lnr->lnr_lar.lar_parent;
+       const struct lu_fid             *pfid   = &lso->lso_fid;
+       struct dt_object                *dir    = NULL;
+       struct dt_object                *obj    = NULL;
        struct lu_seq_range             *range  = &info->lti_range;
        struct seq_server_site          *ss     = lfsck_dev_site(lfsck);
        __u32                            stripe_count;
@@ -1829,8 +1839,7 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
        if (llmv->ll_lmv_slave) {
                if (llmv->ll_lmv_verified) {
                        ns->ln_striped_shards_scanned++;
-                       lfsck_namespace_trace_update(env, com,
-                                       lfsck_dto2fid(dir),
+                       lfsck_namespace_trace_update(env, com, pfid,
                                        LNTF_UNCERTAIN_LMV |
                                        LNTF_RECHECK_NAME_HASH, false);
                }
@@ -1879,6 +1888,15 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
        }
 
        if (llmv->ll_lmv_updated) {
+               if (dir == NULL) {
+                       dir = lfsck_assistant_object_load(env, lfsck, lso);
+                       if (IS_ERR(dir)) {
+                               rc = PTR_ERR(dir);
+
+                               RETURN(rc == -ENOENT ? 0 : rc);
+                       }
+               }
+
                lmv->lmv_layout_version++;
                rc = lfsck_namespace_update_lmv(env, com, dir, lmv, false);
                if (rc != 0)
@@ -1890,7 +1908,6 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
 
        fld_range_set_mdt(range);
        for (i = 0; i <= llmv->ll_max_filled_off; i++) {
-               struct dt_object *obj = NULL;
                struct lfsck_slave_lmv_rec *lslr = llmv->ll_lslr + i;
                const struct lu_fid *cfid = &lslr->lslr_fid;
                const struct lu_name *cname;
@@ -1917,8 +1934,18 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
 
                obj = lfsck_object_find_bottom_nowait(env, lfsck, cfid);
                if (IS_ERR(obj)) {
-                       if (lfsck_is_dead_obj(dir))
-                               RETURN(0);
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       if (PTR_ERR(dir) == -ENOENT)
+                                               RETURN(0);
+
+                                       dir = NULL;
+                               }
+                       } else if (lfsck_is_dead_obj(dir)) {
+                               GOTO(out, rc = 0);
+                       }
 
                        rc1 = PTR_ERR(obj);
                        goto next;
@@ -1957,7 +1984,7 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
                        break;
                }
 
-               rc1 = lfsck_links_read(env, obj, &ldata);
+               rc1 = lfsck_links_read_with_rec(env, obj, &ldata);
                if (rc1 == -ENOENT) {
                        create = true;
                        goto repair;
@@ -1982,6 +2009,20 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
 
 repair:
                if (create) {
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       rc1 = PTR_ERR(dir);
+
+                                       if (rc1 == -ENOENT)
+                                               GOTO(out, rc = 0);
+
+                                       dir = NULL;
+                                       goto next;
+                               }
+                       }
+
                        rc1 = lfsck_namespace_repair_dangling(env, com, dir,
                                                              obj, lnr);
                        if (rc1 >= 0) {
@@ -2047,6 +2088,20 @@ repair:
                }
 
                if (rename) {
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       rc1 = PTR_ERR(dir);
+
+                                       if (rc1 == -ENOENT)
+                                               GOTO(out, rc = 0);
+
+                                       dir = NULL;
+                                       goto next;
+                               }
+                       }
+
                        rc1 = lfsck_namespace_repair_dirent(env, com, dir, obj,
                                        info->lti_tmpbuf2, lnr->lnr_name,
                                        lnr->lnr_type, true, false);
@@ -2067,23 +2122,34 @@ repair:
                if (repair_linkea) {
                        struct lustre_handle lh = { 0 };
 
-                       rc1 = linkea_data_new(&ldata, &info->lti_big_buf);
+                       rc1 = linkea_links_new(&ldata, &info->lti_big_buf,
+                                              cname, lfsck_dto2fid(dir));
                        if (rc1 != 0)
                                goto next;
 
-                       rc1 = linkea_add_buf(&ldata, cname, lfsck_dto2fid(dir));
-                       if (rc1 != 0)
-                               goto next;
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       rc1 = PTR_ERR(dir);
+
+                                       if (rc1 == -ENOENT)
+                                               GOTO(out, rc = 0);
+
+                                       dir = NULL;
+                                       goto next;
+                               }
+                       }
 
                        rc1 = lfsck_ibits_lock(env, lfsck, obj, &lh,
                                               MDS_INODELOCK_UPDATE |
                                               MDS_INODELOCK_XATTR, LCK_EX);
-                       lfsck_ibits_unlock(&lh, LCK_EX);
                        if (rc1 != 0)
                                goto next;
 
                        rc1 = lfsck_namespace_rebuild_linkea(env, com, obj,
                                                             &ldata);
+                       lfsck_ibits_unlock(&lh, LCK_EX);
                        if (rc1 >= 0) {
                                linkea_repaired = true;
                                if (rc1 > 0)
@@ -2104,8 +2170,10 @@ next:
                      repair_lmvea ? "yes" : "no",
                      lmvea_repaired ? "yes" : "no", rc1);
 
-               if (obj != NULL && !IS_ERR(obj))
+               if (obj != NULL && !IS_ERR(obj)) {
                        lfsck_object_put(env, obj);
+                       obj = NULL;
+               }
 
                if (rc1 < 0) {
                        rc = rc1;
@@ -2113,7 +2181,16 @@ next:
                }
        }
 
-       RETURN(rc);
+       GOTO(out, rc);
+
+out:
+       if (obj != NULL && !IS_ERR(obj))
+               lfsck_object_put(env, obj);
+
+       if (dir != NULL && !IS_ERR(dir))
+               lfsck_object_put(env, dir);
+
+       return rc;
 }
 
 /**
@@ -2159,17 +2236,14 @@ next:
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
- * \param[in] dir      pointer to the master MDT-object of the
- *                     striped directory
  * \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,
                                          struct lfsck_component *com,
-                                         struct dt_object *dir,
                                          struct lfsck_namespace_req *lnr)
 {
        struct lfsck_thread_info   *info        = lfsck_env_info(env);
@@ -2177,7 +2251,9 @@ int lfsck_namespace_handle_striped_master(const struct lu_env *env,
        struct lfsck_instance      *lfsck       = com->lc_lfsck;
        struct lfsck_namespace     *ns          = com->lc_file_ram;
        struct lfsck_lmv           *llmv        = lnr->lnr_lmv;
-       const struct lu_fid        *pfid        = lfsck_dto2fid(dir);
+       struct lfsck_assistant_object *lso      = lnr->lnr_lar.lar_parent;
+       const struct lu_fid        *pfid        = &lso->lso_fid;
+       struct dt_object           *dir;
        struct dt_object           *obj         = NULL;
        struct dt_device           *dev         = NULL;
        int                         shard_idx   = 0;
@@ -2191,6 +2267,13 @@ int lfsck_namespace_handle_striped_master(const struct lu_env *env,
        if (unlikely(llmv->ll_ignore))
                RETURN(0);
 
+       dir = lfsck_assistant_object_load(env, lfsck, lso);
+       if (IS_ERR(dir)) {
+               rc = PTR_ERR(dir);
+
+               RETURN(rc == -ENOENT ? 0 : rc);
+       }
+
        shard_idx = lfsck_find_mdt_idx_by_fid(env, lfsck, &lnr->lnr_fid);
        if (shard_idx < 0)
                GOTO(fail_lmv, rc = shard_idx);
@@ -2213,7 +2296,7 @@ int lfsck_namespace_handle_striped_master(const struct lu_env *env,
                        GOTO(out, rc);
                }
 
-               ltd = LTD_TGT(&lfsck->li_mdt_descs, shard_idx);
+               ltd = lfsck_ltd2tgt(&lfsck->li_mdt_descs, shard_idx);
                if (unlikely(ltd == NULL)) {
                        CDEBUG(D_LFSCK, "%s: cannot talk with MDT %x which "
                               "did not join the namespace LFSCK\n",
@@ -2311,8 +2394,7 @@ out:
                CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant fail to handle "
                       "the shard: "DFID", parent "DFID", name %.*s: rc = %d\n",
                       lfsck_lfsck2name(lfsck), PFID(&lnr->lnr_fid),
-                      PFID(lfsck_dto2fid(dir)),
-                      lnr->lnr_namelen, lnr->lnr_name, rc);
+                      PFID(pfid), lnr->lnr_namelen, lnr->lnr_name, rc);
 
                if ((rc == -ENOTCONN || rc == -ESHUTDOWN || rc == -EREMCHG ||
                     rc == -ETIMEDOUT || rc == -EHOSTDOWN ||
@@ -2344,5 +2426,7 @@ out:
        if (obj != NULL && !IS_ERR(obj))
                lfsck_object_put(env, obj);
 
+       lfsck_object_put(env, dir);
+
        return rc;
 }