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_PARENT2     0x161f
 #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);
        }
 
+       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) {
@@ -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 };
-       int                       count         = 0;
+       int                       dirent_count  = 0;
+       int                       linkea_count  = 0;
        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);
+                       linkea_count++;
                        continue;
                }
 
@@ -2666,6 +2671,7 @@ again:
                                 * child to be visible via other parent, then
                                 * remove this linkEA entry. */
                                linkea_del_buf(ldata, cname);
+                               linkea_count++;
                                continue;
                        }
 
@@ -2676,6 +2682,7 @@ again:
                if (unlikely(!dt_try_as_dir(env, parent))) {
                        lfsck_object_put(env, parent);
                        linkea_del_buf(ldata, cname);
+                       linkea_count++;
                        continue;
                }
 
@@ -2723,6 +2730,7 @@ rebuild:
                                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. */
@@ -2759,13 +2767,13 @@ rebuild:
                                        goto next;
                                }
 
-                               count += rc;
+                               dirent_count += rc;
 
 next:
                                linkea_del_buf(ldata, cname);
                        }
 
-                       ns->ln_dirent_repaired += count;
+                       ns->ln_dirent_repaired += dirent_count;
 
                        RETURN(rc);
                }
@@ -2786,10 +2794,15 @@ next:
                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 (rc == 0 && fid_is_zero(pfid) && linkea_count > 0)
+                       rc = lfsck_namespace_rebuild_linkea(env, com, child,
+                                                           ldata);
+
                RETURN(rc);
        }
 
@@ -2802,7 +2815,6 @@ next:
                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. */
@@ -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 (unlikely(!fid_is_sane(pfid))) {
+               fid_zero(pfid);
        }
 
        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));
-       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--;
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);
                }
 
-               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--;
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;
+       uint64_t object;
        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);
 }
@@ -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) {
+                               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);
+
                                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);
+       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)
@@ -1085,7 +1108,7 @@ static int osd_dir_it_load(const struct lu_env *env,
        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,
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 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,
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:
+                       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);
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"
 
+# 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
@@ -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 "".." 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 "#####"
 
@@ -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 "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 "#####"
 
@@ -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."
-       #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
@@ -3065,7 +3069,13 @@ test_24() {
 
        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"
@@ -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"
+       $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"