From: Bobi Jam Date: Mon, 8 Apr 2013 05:55:41 +0000 (+0800) Subject: LU-2459 osd: add LMA incompat flag check X-Git-Tag: 2.3.65~57 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=20544bd96269dbda51a76d31c2d09935637e8b2d LU-2459 osd: add LMA incompat flag check * Add LMA incompatibility flags checking after object initialization. * Add a sanity test case (test_17o). Signed-off-by: Bobi Jam Change-Id: Iec83f3c87bd5ff769c3544c5897011333aa2d656 Reviewed-on: http://review.whamcloud.com/6121 Reviewed-by: Andreas Dilger Reviewed-by: Niu Yawei Tested-by: Hudson Reviewed-by: Mike Pershin Tested-by: Maloo --- diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 9c9ae28..5c44cfb 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -263,6 +263,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, #define OBD_FAIL_OSD_SCRUB_CRASH 0x191 #define OBD_FAIL_OSD_SCRUB_FATAL 0x192 #define OBD_FAIL_OSD_FID_MAPPING 0x193 +#define OBD_FAIL_OSD_LMA_INCOMPAT 0x194 #define OBD_FAIL_OST 0x200 #define OBD_FAIL_OST_CONNECT_NET 0x201 diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 5fdccb3..0351114 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -181,28 +181,22 @@ int osd_get_lma(struct osd_thread_info *info, struct inode *inode, { int rc; - rc = __osd_xattr_get(inode, dentry, XATTR_NAME_LMA, (void *)lma, - sizeof(*lma)); - if (rc == -ERANGE) { - /* try with old lma size */ - rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA, - info->oti_mdt_attrs_old, - LMA_OLD_SIZE); - if (rc > 0) - memcpy(lma, info->oti_mdt_attrs_old, sizeof(*lma)); - } + CLASSERT(LMA_OLD_SIZE >= sizeof(*lma)); + rc = __osd_xattr_get(inode, dentry, XATTR_NAME_LMA, + info->oti_mdt_attrs_old, LMA_OLD_SIZE); if (rc > 0) { + if ((void *)lma != (void *)info->oti_mdt_attrs_old) + memcpy(lma, info->oti_mdt_attrs_old, sizeof(*lma)); + rc = 0; + lustre_lma_swab(lma); /* Check LMA compatibility */ - if (lma->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP)) { - CWARN("%.16s: unsupported incompat LMA feature(s) " - "%lu/%#x\n", + if (lma->lma_incompat & ~LMA_INCOMPAT_SUPP) { + CWARN("%.16s: unsupported incompat LMA feature(s) %#x " + "for fid = "DFID", ino = %lu\n", LDISKFS_SB(inode->i_sb)->s_es->s_volume_name, - inode->i_ino, le32_to_cpu(lma->lma_incompat) & - ~LMA_INCOMPAT_SUPP); - rc = -ENOSYS; - } else { - lustre_lma_swab(lma); - rc = 0; + lma->lma_incompat & ~LMA_INCOMPAT_SUPP, + PFID(&lma->lma_self_fid), inode->i_ino); + rc = -EOPNOTSUPP; } } else if (rc == 0) { rc = -ENODATA; @@ -451,6 +445,38 @@ static void osd_object_init0(struct osd_object *obj) (LOHA_EXISTS | (obj->oo_inode->i_mode & S_IFMT)); } +static int osd_check_lma(const struct lu_env *env, struct osd_object *obj) +{ + struct osd_thread_info *info = osd_oti_get(env); + struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs; + int rc; + ENTRY; + + CLASSERT(LMA_OLD_SIZE >= sizeof(*lma)); + rc = __osd_xattr_get(obj->oo_inode, &info->oti_obj_dentry, + XATTR_NAME_LMA, info->oti_mdt_attrs_old, + LMA_OLD_SIZE); + if (rc > 0) { + rc = 0; + lustre_lma_swab(lma); + if (unlikely((lma->lma_incompat & ~LMA_INCOMPAT_SUPP) || + CFS_FAIL_CHECK(OBD_FAIL_OSD_LMA_INCOMPAT))) { + CWARN("%s: unsupported incompat LMA feature(s) %#x for " + "fid = "DFID", ino = %lu\n", + osd_obj2dev(obj)->od_svname, + lma->lma_incompat & ~LMA_INCOMPAT_SUPP, + PFID(lu_object_fid(&obj->oo_dt.do_lu)), + obj->oo_inode->i_ino); + rc = -EOPNOTSUPP; + } + } else if (rc == -ENODATA) { + /* haven't initialize LMA xattr */ + rc = 0; + } + + RETURN(rc); +} + /* * Concurrency: no concurrent access is possible that early in object * life-cycle. @@ -471,8 +497,10 @@ static int osd_object_init(const struct lu_env *env, struct lu_object *l, result = osd_fid_lookup(env, obj, lu_object_fid(l), conf); obj->oo_dt.do_body_ops = &osd_body_ops_new; - if (result == 0 && obj->oo_inode != NULL) + if (result == 0 && obj->oo_inode != NULL) { osd_object_init0(obj); + result = osd_check_lma(env, obj); + } LINVRNT(osd_invariant(obj)); return result; diff --git a/lustre/osd-zfs/osd_object.c b/lustre/osd-zfs/osd_object.c index 97f954d..9513748 100644 --- a/lustre/osd-zfs/osd_object.c +++ b/lustre/osd-zfs/osd_object.c @@ -349,6 +349,39 @@ int osd_object_init0(const struct lu_env *env, struct osd_object *obj) RETURN(0); } +static int osd_check_lma(const struct lu_env *env, struct osd_object *obj) +{ + struct osd_thread_info *info = osd_oti_get(env); + struct lu_buf buf; + int rc; + struct lustre_mdt_attrs *lma; + ENTRY; + + CLASSERT(sizeof(info->oti_buf) >= sizeof(*lma)); + lma = (struct lustre_mdt_attrs *)info->oti_buf; + buf.lb_buf = lma; + buf.lb_len = sizeof(info->oti_buf); + + rc = osd_xattr_get(env, &obj->oo_dt, &buf, XATTR_NAME_LMA, BYPASS_CAPA); + if (rc > 0) { + rc = 0; + lustre_lma_swab(lma); + if (unlikely((lma->lma_incompat & ~LMA_INCOMPAT_SUPP) || + CFS_FAIL_CHECK(OBD_FAIL_OSD_LMA_INCOMPAT))) { + CWARN("%s: unsupported incompat LMA feature(s) %#x for " + "fid = "DFID"\n", osd_obj2dev(obj)->od_svname, + lma->lma_incompat & ~LMA_INCOMPAT_SUPP, + PFID(lu_object_fid(&obj->oo_dt.do_lu))); + rc = -EOPNOTSUPP; + } + } else if (rc == -ENODATA) { + /* haven't initialize LMA xattr */ + rc = 0; + } + + RETURN(rc); +} + /* * Concurrency: no concurrent access is possible that early in object * life-cycle. @@ -375,17 +408,24 @@ static int osd_object_init(const struct lu_env *env, struct lu_object *l, LASSERT(obj->oo_db == NULL); rc = __osd_obj2dbuf(env, osd->od_objset.os, oid, &obj->oo_db, osd_obj_tag); - if (rc == 0) { - LASSERT(obj->oo_db); - rc = osd_object_init0(env, obj); - } else { + if (rc != 0) { CERROR("%s: lookup "DFID"/"LPX64" failed: rc = %d\n", osd->od_svname, PFID(lu_object_fid(l)), oid, rc); + GOTO(out, rc); } + LASSERT(obj->oo_db); + rc = osd_object_init0(env, obj); + if (rc != 0) + GOTO(out, rc); + + rc = osd_check_lma(env, obj); + if (rc != 0) + GOTO(out, rc); } else if (rc == -ENOENT) { rc = 0; } LASSERT(osd_invariant(obj)); +out: RETURN(rc); } diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 4728c75..682252f 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -677,6 +677,30 @@ test_17n() { } run_test 17n "run e2fsck against master/slave MDT which contains remote dir" +test_17o() { + local WDIR=$DIR/${tdir}o + local mdt_index + local mdtdevname + local rc=0 + + mkdir -p $WDIR + mdt_index=$($LFS getstripe -M $WDIR) + mdt_index=$((mdt_index+1)) + mdtdevname=$(mdsdevname $mdt_index) + + touch $WDIR/$tfile + stop mds${mdt_index} + start mds${mdt_index} $mdtdevname $MDS_MOUNT_OPTS + + #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194 + do_facet mds${mdt_index} lctl set_param fail_loc=0x194 + ls -l $WDIR/$tfile && rc=1 + do_facet mds${mdt_index} lctl set_param fail_loc=0 + [[ $rc -ne 0 ]] && error "stat file should fail" + true +} +run_test 17o "stat file with incompat LMA feature" + test_18() { touch $DIR/f || error "Failed to touch $DIR/f: $?" ls $DIR || error "Failed to ls $DIR: $?"