Whamcloud - gitweb
LU-2459 osd: add LMA incompat flag check
authorBobi Jam <bobijam.xu@intel.com>
Mon, 8 Apr 2013 05:55:41 +0000 (13:55 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 27 Apr 2013 19:40:55 +0000 (15:40 -0400)
* Add LMA incompatibility flags checking after object initialization.
* Add a sanity test case (test_17o).

Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: Iec83f3c87bd5ff769c3544c5897011333aa2d656
Reviewed-on: http://review.whamcloud.com/6121
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Hudson
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
lustre/include/obd_support.h
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-zfs/osd_object.c
lustre/tests/sanity.sh

index 9c9ae28..5c44cfb 100644 (file)
@@ -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
index 5fdccb3..0351114 100644 (file)
@@ -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;
index 97f954d..9513748 100644 (file)
@@ -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);
 }
 
index 4728c75..682252f 100644 (file)
@@ -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: $?"