Whamcloud - gitweb
LU-5855 lfsck: misc fixes for zfs-based backend 52/12552/5
authorFan Yong <fan.yong@intel.com>
Wed, 3 Sep 2014 16:25:33 +0000 (00:25 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 19 Nov 2014 19:17:07 +0000 (19:17 +0000)
It contains several fixes to make the LFSCK to work under DNE mode
for zfs-based backend.

Test-Parameters: mdsfilesystemtype=zfs mdtfilesystemtype=zfs ostfilesystemtype=zfs mdscount=2 mdtcount=2 testlist=sanity-lfsck
Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: I8e8758336d4ce67667f7e3586475ddd72db2d419
Reviewed-on: http://review.whamcloud.com/12552
Tested-by: Jenkins
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: wangdi <di.wang@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/obd_support.h
lustre/lfsck/lfsck_namespace.c
lustre/mdd/mdd_dir.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-zfs/osd_index.c
lustre/osd-zfs/osd_internal.h
lustre/osd-zfs/osd_object.c
lustre/tests/sanity-lfsck.sh

index d832503..0bdfc4a 100644 (file)
@@ -528,7 +528,6 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type,
 #define OBD_FAIL_LFSCK_BAD_NETWORK     0x161c
 #define OBD_FAIL_LFSCK_NO_LINKEA       0x161d
 #define OBD_FAIL_LFSCK_BAD_PARENT      0x161e
 #define OBD_FAIL_LFSCK_BAD_NETWORK     0x161c
 #define OBD_FAIL_LFSCK_NO_LINKEA       0x161d
 #define OBD_FAIL_LFSCK_BAD_PARENT      0x161e
-#define OBD_FAIL_LFSCK_BAD_PARENT2     0x161f
 #define OBD_FAIL_LFSCK_DANGLING2       0x1620
 #define OBD_FAIL_LFSCK_DANGLING3       0x1621
 #define OBD_FAIL_LFSCK_MUL_REF         0x1622
 #define OBD_FAIL_LFSCK_DANGLING2       0x1620
 #define OBD_FAIL_LFSCK_DANGLING3       0x1621
 #define OBD_FAIL_LFSCK_MUL_REF         0x1622
index 6641db8..83d62df 100644 (file)
@@ -2554,6 +2554,9 @@ lost_parent:
                GOTO(out, rc);
        }
 
                GOTO(out, rc);
        }
 
+       if (fid_is_zero(pfid))
+               GOTO(out, rc = 0);
+
        /* The ".." name entry is wrong, update it. */
        if (!lu_fid_eq(pfid, lfsck_dto2fid(parent))) {
                if (!lustre_handle_is_used(lh) && retry != NULL) {
        /* The ".." name entry is wrong, update it. */
        if (!lu_fid_eq(pfid, lfsck_dto2fid(parent))) {
                if (!lustre_handle_is_used(lh) && retry != NULL) {
@@ -2619,7 +2622,8 @@ lfsck_namespace_dsd_multiple(const struct lu_env *env,
        struct lfsck_bookmark    *bk            = &lfsck->li_bookmark_ram;
        struct dt_object         *parent        = NULL;
        struct linkea_data        ldata_new     = { 0 };
        struct lfsck_bookmark    *bk            = &lfsck->li_bookmark_ram;
        struct dt_object         *parent        = NULL;
        struct linkea_data        ldata_new     = { 0 };
-       int                       count         = 0;
+       int                       dirent_count  = 0;
+       int                       linkea_count  = 0;
        int                       rc            = 0;
        bool                      once          = true;
        ENTRY;
        int                       rc            = 0;
        bool                      once          = true;
        ENTRY;
@@ -2633,6 +2637,7 @@ again:
                /* Drop invalid linkEA entry. */
                if (!fid_is_sane(tfid)) {
                        linkea_del_buf(ldata, cname);
                /* Drop invalid linkEA entry. */
                if (!fid_is_sane(tfid)) {
                        linkea_del_buf(ldata, cname);
+                       linkea_count++;
                        continue;
                }
 
                        continue;
                }
 
@@ -2666,6 +2671,7 @@ again:
                                 * child to be visible via other parent, then
                                 * remove this linkEA entry. */
                                linkea_del_buf(ldata, cname);
                                 * child to be visible via other parent, then
                                 * remove this linkEA entry. */
                                linkea_del_buf(ldata, cname);
+                               linkea_count++;
                                continue;
                        }
 
                                continue;
                        }
 
@@ -2676,6 +2682,7 @@ again:
                if (unlikely(!dt_try_as_dir(env, parent))) {
                        lfsck_object_put(env, parent);
                        linkea_del_buf(ldata, cname);
                if (unlikely(!dt_try_as_dir(env, parent))) {
                        lfsck_object_put(env, parent);
                        linkea_del_buf(ldata, cname);
+                       linkea_count++;
                        continue;
                }
 
                        continue;
                }
 
@@ -2723,6 +2730,7 @@ rebuild:
                                RETURN(rc);
 
                        linkea_del_buf(ldata, cname);
                                RETURN(rc);
 
                        linkea_del_buf(ldata, cname);
+                       linkea_count++;
                        linkea_first_entry(ldata);
                        /* There may be some invalid dangling name entries under
                         * other parent directories, remove all of them. */
                        linkea_first_entry(ldata);
                        /* There may be some invalid dangling name entries under
                         * other parent directories, remove all of them. */
@@ -2759,13 +2767,13 @@ rebuild:
                                        goto next;
                                }
 
                                        goto next;
                                }
 
-                               count += rc;
+                               dirent_count += rc;
 
 next:
                                linkea_del_buf(ldata, cname);
                        }
 
 
 next:
                                linkea_del_buf(ldata, cname);
                        }
 
-                       ns->ln_dirent_repaired += count;
+                       ns->ln_dirent_repaired += dirent_count;
 
                        RETURN(rc);
                }
 
                        RETURN(rc);
                }
@@ -2786,10 +2794,15 @@ next:
                linkea_del_buf(ldata, cname);
        }
 
                linkea_del_buf(ldata, cname);
        }
 
+       linkea_first_entry(ldata);
        if (ldata->ld_leh->leh_reccount == 1) {
                rc = lfsck_namespace_dsd_single(env, com, child, pfid, ldata,
                                                lh, type, NULL);
 
        if (ldata->ld_leh->leh_reccount == 1) {
                rc = lfsck_namespace_dsd_single(env, com, child, pfid, ldata,
                                                lh, type, NULL);
 
+               if (rc == 0 && fid_is_zero(pfid) && linkea_count > 0)
+                       rc = lfsck_namespace_rebuild_linkea(env, com, child,
+                                                           ldata);
+
                RETURN(rc);
        }
 
                RETURN(rc);
        }
 
@@ -2802,7 +2815,6 @@ next:
                RETURN(rc);
        }
 
                RETURN(rc);
        }
 
-       linkea_first_entry(ldata);
        /* If the dangling name entry for the orphan directory object has
         * been remvoed, then just check whether the directory object is
         * still under the .lustre/lost+found/MDTxxxx/ or not. */
        /* If the dangling name entry for the orphan directory object has
         * been remvoed, then just check whether the directory object is
         * still under the .lustre/lost+found/MDTxxxx/ or not. */
@@ -3071,6 +3083,8 @@ lock:
        } else if (lfsck->li_lpf_obj != NULL &&
                   lu_fid_eq(pfid, lfsck_dto2fid(lfsck->li_lpf_obj))) {
                lpf = true;
        } else if (lfsck->li_lpf_obj != NULL &&
                   lu_fid_eq(pfid, lfsck_dto2fid(lfsck->li_lpf_obj))) {
                lpf = true;
+       } else if (unlikely(!fid_is_sane(pfid))) {
+               fid_zero(pfid);
        }
 
        rc = lfsck_links_read(env, child, &ldata);
        }
 
        rc = lfsck_links_read(env, child, &ldata);
index 5ab5e61..d651bc1 100644 (file)
@@ -2334,7 +2334,7 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj,
        mdd_object_make_hint(env, mdd_pobj, son, attr, spec, hint);
 
        memset(ldata, 0, sizeof(*ldata));
        mdd_object_make_hint(env, mdd_pobj, son, attr, spec, hint);
 
        memset(ldata, 0, sizeof(*ldata));
-       if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT2)) {
+       if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT)) {
                struct lu_fid tfid = *mdd_object_fid(mdd_pobj);
 
                tfid.f_oid--;
                struct lu_fid tfid = *mdd_object_fid(mdd_pobj);
 
                tfid.f_oid--;
index 519f6ae..3c09617 100644 (file)
@@ -4041,8 +4041,7 @@ static int osd_add_dot_dotdot(struct osd_thread_info *info,
                                                dot_dot_fid, NULL, th);
                }
 
                                                dot_dot_fid, NULL, th);
                }
 
-               if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT) ||
-                   OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT2)) {
+               if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT)) {
                        struct lu_fid tfid = *dot_dot_fid;
 
                        tfid.f_oid--;
                        struct lu_fid tfid = *dot_dot_fid;
 
                        tfid.f_oid--;
index 8765df1..efd2117 100644 (file)
@@ -440,16 +440,20 @@ static int osd_declare_dir_insert(const struct lu_env *env,
 {
        struct osd_object  *obj = osd_dt_obj(dt);
        struct osd_thandle *oh;
 {
        struct osd_object  *obj = osd_dt_obj(dt);
        struct osd_thandle *oh;
+       uint64_t object;
        ENTRY;
 
        LASSERT(th != NULL);
        oh = container_of0(th, struct osd_thandle, ot_super);
 
        ENTRY;
 
        LASSERT(th != NULL);
        oh = container_of0(th, struct osd_thandle, ot_super);
 
-       LASSERT(obj->oo_db);
-       LASSERT(osd_object_is_zap(obj->oo_db));
+       /* This is for inserting dot/dotdot for new created dir. */
+       if (obj->oo_db == NULL)
+               object = DMU_NEW_OBJECT;
+       else
+               object = obj->oo_db->db_object;
 
 
-       dmu_tx_hold_bonus(oh->ot_tx, obj->oo_db->db_object);
-       dmu_tx_hold_zap(oh->ot_tx, obj->oo_db->db_object, TRUE, (char *)key);
+       dmu_tx_hold_bonus(oh->ot_tx, object);
+       dmu_tx_hold_zap(oh->ot_tx, object, TRUE, (char *)key);
 
        RETURN(0);
 }
 
        RETURN(0);
 }
@@ -633,12 +637,25 @@ static int osd_dir_insert(const struct lu_env *env, struct dt_object *dt,
                                 * during iteration */
                                GOTO(out, rc = 0);
                        } else if (name[1] == '.' && name[2] == 0) {
                                 * during iteration */
                                GOTO(out, rc = 0);
                        } else if (name[1] == '.' && name[2] == 0) {
+                               if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT)) {
+                                       struct lu_fid tfid = *fid;
+
+                                       osd_object_put(env, child);
+                                       tfid.f_oid--;
+                                       child = osd_object_find(env, dt, &tfid);
+                                       if (IS_ERR(child))
+                                               RETURN(PTR_ERR(child));
+
+                                       LASSERT(child->oo_db);
+                               }
+
                                /* update parent dnode in the child.
                                 * later it will be used to generate ".." */
                                rc = osd_object_sa_update(parent,
                                                 SA_ZPL_PARENT(osd),
                                                 &child->oo_db->db_object,
                                                 8, oh);
                                /* update parent dnode in the child.
                                 * later it will be used to generate ".." */
                                rc = osd_object_sa_update(parent,
                                                 SA_ZPL_PARENT(osd),
                                                 &child->oo_db->db_object,
                                                 8, oh);
+
                                GOTO(out, rc);
                        }
                }
                                GOTO(out, rc);
                        }
                }
@@ -654,6 +671,12 @@ static int osd_dir_insert(const struct lu_env *env, struct dt_object *dt,
        rc = -zap_add(osd->od_os, parent->oo_db->db_object,
                      (char *)key, 8, sizeof(oti->oti_zde) / 8,
                      (void *)&oti->oti_zde, oh->ot_tx);
        rc = -zap_add(osd->od_os, parent->oo_db->db_object,
                      (char *)key, 8, sizeof(oti->oti_zde) / 8,
                      (void *)&oti->oti_zde, oh->ot_tx);
+       if (unlikely(rc == -EEXIST &&
+                    name[0] == '.' && name[1] == '.' && name[2] == 0))
+               /* Update (key,oid) in ZAP */
+               rc = -zap_update(osd->od_os, parent->oo_db->db_object,
+                               (char *)key, 8, sizeof(oti->oti_zde) / 8,
+                               (void *)&oti->oti_zde, oh->ot_tx);
 
 out:
        if (child != NULL)
 
 out:
        if (child != NULL)
@@ -1085,7 +1108,7 @@ static int osd_dir_it_load(const struct lu_env *env,
        RETURN(rc);
 }
 
        RETURN(rc);
 }
 
-static struct dt_index_operations osd_dir_ops = {
+struct dt_index_operations osd_dir_ops = {
        .dio_lookup         = osd_dir_lookup,
        .dio_declare_insert = osd_declare_dir_insert,
        .dio_insert         = osd_dir_insert,
        .dio_lookup         = osd_dir_lookup,
        .dio_declare_insert = osd_declare_dir_insert,
        .dio_insert         = osd_dir_insert,
index 90c8366..9bb7f98 100644 (file)
@@ -333,6 +333,7 @@ int osd_statfs(const struct lu_env *, struct dt_device *, struct obd_statfs *);
 extern const struct dt_index_operations osd_acct_index_ops;
 uint64_t osd_quota_fid2dmu(const struct lu_fid *fid);
 extern struct lu_device_operations  osd_lu_ops;
 extern const struct dt_index_operations osd_acct_index_ops;
 uint64_t osd_quota_fid2dmu(const struct lu_fid *fid);
 extern struct lu_device_operations  osd_lu_ops;
+extern struct dt_index_operations osd_dir_ops;
 int osd_declare_quota(const struct lu_env *env, struct osd_device *osd,
                      qid_t uid, qid_t gid, long long space,
                      struct osd_thandle *oh, bool is_blk, int *flags,
 int osd_declare_quota(const struct lu_env *env, struct osd_device *osd,
                      qid_t uid, qid_t gid, long long space,
                      struct osd_thandle *oh, bool is_blk, int *flags,
index 6bf8185..e66d2e0 100644 (file)
@@ -1092,6 +1092,7 @@ static int osd_declare_object_create(const struct lu_env *env,
 
        switch (dof->dof_type) {
                case DFT_DIR:
 
        switch (dof->dof_type) {
                case DFT_DIR:
+                       dt->do_index_ops = &osd_dir_ops;
                case DFT_INDEX:
                        /* for zap create */
                        dmu_tx_hold_zap(oh->ot_tx, DMU_NEW_OBJECT, 1, NULL);
                case DFT_INDEX:
                        /* for zap create */
                        dmu_tx_hold_zap(oh->ot_tx, DMU_NEW_OBJECT, 1, NULL);
index 5af004b..0ece9cd 100644 (file)
@@ -48,6 +48,10 @@ setupall
 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.50) ]] &&
        ALWAYS_EXCEPT="$ALWAYS_EXCEPT 2d 2e 3 22 23 24 25 26 27 28 29 30 31"
 
 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.50) ]] &&
        ALWAYS_EXCEPT="$ALWAYS_EXCEPT 2d 2e 3 22 23 24 25 26 27 28 29 30 31"
 
+# DNE does not support striped directory on zfs-based backend yet.
+[ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
+       ALWAYS_EXCEPT="$ALWAYS_EXCEPT 31"
+
 build_test_filter
 
 $LCTL set_param debug=+lfsck > /dev/null || true
 build_test_filter
 
 $LCTL set_param debug=+lfsck > /dev/null || true
@@ -2758,7 +2762,7 @@ test_22a() {
        echo "#####"
        echo "The parent_A references the child directory via some name entry,"
        echo "but the child directory back references another parent_B via its"
        echo "#####"
        echo "The parent_A references the child directory via some name entry,"
        echo "but the child directory back references another parent_B via its"
-       echo "".." name entry. The parent_A does not exist. Then the namesapce"
+       echo "".." name entry. The parent_B does not exist. Then the namesapce"
        echo "LFSCK will repair the child directory's ".." name entry."
        echo "#####"
 
        echo "LFSCK will repair the child directory's ".." name entry."
        echo "#####"
 
@@ -2807,7 +2811,7 @@ test_22b() {
        echo "The parent_A references the child directory via the name entry_B,"
        echo "but the child directory back references another parent_C via its"
        echo "".." name entry. The parent_C exists, but there is no the name"
        echo "The parent_A references the child directory via the name entry_B,"
        echo "but the child directory back references another parent_C via its"
        echo "".." name entry. The parent_C exists, but there is no the name"
-       echo "entry_B under the parent_B. Then the namesapce LFSCK will repair"
+       echo "entry_B under the parent_C. Then the namesapce LFSCK will repair"
        echo "the child directory's ".." name entry and its linkEA."
        echo "#####"
 
        echo "the child directory's ".." name entry and its linkEA."
        echo "#####"
 
@@ -2819,8 +2823,8 @@ test_22b() {
        echo "Inject failure stub on MDT0 to simulate bad dotdot name entry"
        echo "and bad linkEA. The dummy's dotdot name entry references the"
        echo "guard. The dummy's linkEA references n non-exist name entry."
        echo "Inject failure stub on MDT0 to simulate bad dotdot name entry"
        echo "and bad linkEA. The dummy's dotdot name entry references the"
        echo "guard. The dummy's linkEA references n non-exist name entry."
-       #define OBD_FAIL_LFSCK_BAD_PARENT2      0x161f
-       do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161f
+       #define OBD_FAIL_LFSCK_BAD_PARENT       0x161e
+       do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161e
        $LFS mkdir -i 0 $DIR/$tdir/foo/dummy ||
                error "(3) Fail to mkdir on MDT0"
        do_facet $SINGLEMDS $LCTL set_param fail_loc=0
        $LFS mkdir -i 0 $DIR/$tdir/foo/dummy ||
                error "(3) Fail to mkdir on MDT0"
        do_facet $SINGLEMDS $LCTL set_param fail_loc=0
@@ -3065,7 +3069,13 @@ test_24() {
 
        mkdir $DIR/$tdir/d0/dummy || error "(2) Fail to mkdir dummy"
        $LFS path2fid $DIR/$tdir/d0/dummy
 
        mkdir $DIR/$tdir/d0/dummy || error "(2) Fail to mkdir dummy"
        $LFS path2fid $DIR/$tdir/d0/dummy
-       local pfid=$($LFS path2fid $DIR/$tdir/d0/dummy)
+
+       local pfid
+       if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
+               pfid=$($LFS path2fid $DIR/$tdir/d0/guard)
+       else
+               pfid=$($LFS path2fid $DIR/$tdir/d0/dummy)
+       fi
 
        touch $DIR/$tdir/d0/guard/foo ||
                error "(3) Fail to touch $DIR/$tdir/d0/guard/foo"
 
        touch $DIR/$tdir/d0/guard/foo ||
                error "(3) Fail to touch $DIR/$tdir/d0/guard/foo"
@@ -3082,6 +3092,7 @@ test_24() {
        do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1622
        $LFS mkdir -i 0 $DIR/$tdir/d0/dummy/foo ||
                error "(4) Fail to mkdir $DIR/$tdir/d0/dummy/foo"
        do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1622
        $LFS mkdir -i 0 $DIR/$tdir/d0/dummy/foo ||
                error "(4) Fail to mkdir $DIR/$tdir/d0/dummy/foo"
+       $LFS path2fid $DIR/$tdir/d0/dummy/foo
        local cfid=$($LFS path2fid $DIR/$tdir/d0/dummy/foo)
        rmdir $DIR/$tdir/d0/dummy/foo ||
                error "(5) Fail to remove $DIR/$tdir/d0/dummy/foo name entry"
        local cfid=$($LFS path2fid $DIR/$tdir/d0/dummy/foo)
        rmdir $DIR/$tdir/d0/dummy/foo ||
                error "(5) Fail to remove $DIR/$tdir/d0/dummy/foo name entry"