From 26995a3588e72d65f609b12772d24a879c9deb7f Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Thu, 4 Sep 2014 00:25:33 +0800 Subject: [PATCH] LU-5855 lfsck: misc fixes for zfs-based backend 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 Change-Id: I8e8758336d4ce67667f7e3586475ddd72db2d419 Reviewed-on: http://review.whamcloud.com/12552 Tested-by: Jenkins Reviewed-by: Alex Zhuravlev Tested-by: Maloo Reviewed-by: wangdi Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- lustre/include/obd_support.h | 1 - lustre/lfsck/lfsck_namespace.c | 22 ++++++++++++++++++---- lustre/mdd/mdd_dir.c | 2 +- lustre/osd-ldiskfs/osd_handler.c | 3 +-- lustre/osd-zfs/osd_index.c | 33 ++++++++++++++++++++++++++++----- lustre/osd-zfs/osd_internal.h | 1 + lustre/osd-zfs/osd_object.c | 1 + lustre/tests/sanity-lfsck.sh | 21 ++++++++++++++++----- 8 files changed, 66 insertions(+), 18 deletions(-) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index d832503..0bdfc4a 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -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 diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index 6641db8..83d62df 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -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); diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 5ab5e61..d651bc1 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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--; diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 519f6ae..3c09617 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -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--; diff --git a/lustre/osd-zfs/osd_index.c b/lustre/osd-zfs/osd_index.c index 8765df1..efd2117 100644 --- a/lustre/osd-zfs/osd_index.c +++ b/lustre/osd-zfs/osd_index.c @@ -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, diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h index 90c8366..9bb7f98 100644 --- a/lustre/osd-zfs/osd_internal.h +++ b/lustre/osd-zfs/osd_internal.h @@ -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, diff --git a/lustre/osd-zfs/osd_object.c b/lustre/osd-zfs/osd_object.c index 6bf8185..e66d2e0 100644 --- a/lustre/osd-zfs/osd_object.c +++ b/lustre/osd-zfs/osd_object.c @@ -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); diff --git a/lustre/tests/sanity-lfsck.sh b/lustre/tests/sanity-lfsck.sh index 5af004b..0ece9cd 100644 --- a/lustre/tests/sanity-lfsck.sh +++ b/lustre/tests/sanity-lfsck.sh @@ -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" -- 1.8.3.1