Whamcloud - gitweb
LU-3125 layout: allow stripeless layouts swap
authorLai Siyao <lai.siyao@intel.com>
Tue, 9 Apr 2013 19:16:15 +0000 (03:16 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 23 Apr 2013 16:15:16 +0000 (12:15 -0400)
* allow stripeless layouts swap
* `lfs swap_layouts` should open with O_LOV_DELAY_CREATE

Signed-off-by: Lai Siyao <lai.siyao@intel.com>
Change-Id: I3947005d1060ee9be189a9c2adbab61064a8e6f0
Reviewed-on: http://review.whamcloud.com/5998
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
lustre/lod/lod_object.c
lustre/lod/lod_qos.c
lustre/mdd/mdd_object.c
lustre/tests/sanity.sh
lustre/utils/liblustreapi.c

index bbbb3a2..0acd7fe 100644 (file)
@@ -570,6 +570,8 @@ static int lod_xattr_del(const struct lu_env *env, struct dt_object *dt,
                         const char *name, struct thandle *th,
                         struct lustre_capa *capa)
 {
                         const char *name, struct thandle *th,
                         struct lustre_capa *capa)
 {
+       if (!strcmp(name, XATTR_NAME_LOV))
+               lod_object_free_striping(env, lod_dt_obj(dt));
        return dt_xattr_del(env, dt_object_child(dt), name, th, capa);
 }
 
        return dt_xattr_del(env, dt_object_child(dt), name, th, capa);
 }
 
index a009f8b..5b05ec4 100644 (file)
@@ -1233,13 +1233,6 @@ static int lod_use_defined_striping(const struct lu_env *env,
                GOTO(out, rc = -EINVAL);
        }
 
                GOTO(out, rc = -EINVAL);
        }
 
-       /*
-        * LOD shouldn't be aware of recovery at all,
-        * but this track recovery status (to some extent)
-        * to be do additional checks like this one
-        */
-       LASSERT(d->lod_recovery_completed == 0);
-
        mo->ldo_stripe_size = le32_to_cpu(v1->lmm_stripe_size);
        mo->ldo_stripenr = le16_to_cpu(v1->lmm_stripe_count);
        mo->ldo_layout_gen = le16_to_cpu(v1->lmm_layout_gen);
        mo->ldo_stripe_size = le32_to_cpu(v1->lmm_stripe_size);
        mo->ldo_stripenr = le16_to_cpu(v1->lmm_stripe_count);
        mo->ldo_layout_gen = le16_to_cpu(v1->lmm_layout_gen);
index c5a7da4..7c338e8 100644 (file)
@@ -1270,6 +1270,7 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
        struct mdd_device       *mdd = mdo2mdd(obj1);
        int                      rc;
        __u16                    fst_gen, snd_gen;
        struct mdd_device       *mdd = mdo2mdd(obj1);
        int                      rc;
        __u16                    fst_gen, snd_gen;
+       int                      fst_fl;
        ENTRY;
 
        /* we have to sort the 2 obj, so locking will always
        ENTRY;
 
        /* we have to sort the 2 obj, so locking will always
@@ -1306,7 +1307,7 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
                rc = PTR_ERR(lmm1_buf);
                lmm1_buf = NULL;
                if (rc != -ENODATA)
                rc = PTR_ERR(lmm1_buf);
                lmm1_buf = NULL;
                if (rc != -ENODATA)
-                       GOTO(unlock, rc);
+                       GOTO(stop, rc);
        }
 
        lmm2_buf = mdd_get_lov_ea(env, o2);
        }
 
        lmm2_buf = mdd_get_lov_ea(env, o2);
@@ -1314,12 +1315,12 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
                rc = PTR_ERR(lmm2_buf);
                lmm2_buf = NULL;
                if (rc != -ENODATA)
                rc = PTR_ERR(lmm2_buf);
                lmm2_buf = NULL;
                if (rc != -ENODATA)
-                       GOTO(unlock, rc);
+                       GOTO(stop, rc);
        }
 
        /* swapping 2 non existant layouts is a success */
        if ((lmm1_buf == NULL) && (lmm2_buf == NULL))
        }
 
        /* swapping 2 non existant layouts is a success */
        if ((lmm1_buf == NULL) && (lmm2_buf == NULL))
-               GOTO(unlock, rc = 0);
+               GOTO(stop, rc = 0);
 
        /* to help inode migration between MDT, it is better to
         * start by the no layout file (if one), so we order the swap */
 
        /* to help inode migration between MDT, it is better to
         * start by the no layout file (if one), so we order the swap */
@@ -1339,26 +1340,16 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
        if (fst_buf) {
                fst_lmm = fst_buf->lb_buf;
                fst_gen = le16_to_cpu(fst_lmm->lmm_layout_gen);
        if (fst_buf) {
                fst_lmm = fst_buf->lb_buf;
                fst_gen = le16_to_cpu(fst_lmm->lmm_layout_gen);
+               fst_fl  = LU_XATTR_REPLACE;
        } else {
                fst_lmm = NULL;
                fst_gen = 0;
        } else {
                fst_lmm = NULL;
                fst_gen = 0;
+               fst_fl  = LU_XATTR_CREATE;
        }
 
        }
 
-       if (snd_buf) {
-               snd_lmm = snd_buf->lb_buf;
-               snd_gen = le16_to_cpu(snd_lmm->lmm_layout_gen);
-       } else {
-               snd_lmm = NULL;
-               snd_gen = 0;
-       }
-
-       /* save the orignal lmm common header of first file
-        * to be able to roll back */
-       OBD_ALLOC_PTR(old_fst_lmm);
-       if (old_fst_lmm == NULL)
-               GOTO(unlock, rc = -ENOMEM);
-
-       memcpy(old_fst_lmm, fst_lmm, sizeof(*old_fst_lmm));
+       LASSERT(snd_buf != NULL);
+       snd_lmm = snd_buf->lb_buf;
+       snd_gen = le16_to_cpu(snd_lmm->lmm_layout_gen);
 
        /* increase the generation layout numbers */
        snd_gen++;
 
        /* increase the generation layout numbers */
        snd_gen++;
@@ -1366,23 +1357,41 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
 
        /* set the file specific informations in lmm */
        if (fst_lmm) {
 
        /* set the file specific informations in lmm */
        if (fst_lmm) {
+               /* save the orignal lmm common header of first file
+                * to be able to roll back */
+               OBD_ALLOC_PTR(old_fst_lmm);
+               if (old_fst_lmm == NULL)
+                       GOTO(stop, rc = -ENOMEM);
+               *old_fst_lmm = *fst_lmm;
+
                fst_lmm->lmm_layout_gen = cpu_to_le16(snd_gen);
                fst_lmm->lmm_oi = snd_lmm->lmm_oi;
                fst_lmm->lmm_layout_gen = cpu_to_le16(snd_gen);
                fst_lmm->lmm_oi = snd_lmm->lmm_oi;
-       }
 
 
-       if (snd_lmm) {
-               snd_lmm->lmm_layout_gen = cpu_to_le16(fst_gen);
                snd_lmm->lmm_oi = old_fst_lmm->lmm_oi;
                snd_lmm->lmm_oi = old_fst_lmm->lmm_oi;
+       } else {
+               if (snd_lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1))
+                       snd_lmm->lmm_magic = cpu_to_le32(LOV_MAGIC_V1_DEF);
+               else if (snd_lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3))
+                       snd_lmm->lmm_magic = cpu_to_le32(LOV_MAGIC_V3_DEF);
+               else
+                       GOTO(stop, rc = -EPROTO);
        }
 
        }
 
+       snd_lmm->lmm_layout_gen = cpu_to_le16(fst_gen);
+
        /* prepare transaction */
        rc = mdd_declare_xattr_set(env, mdd, fst_o, snd_buf, XATTR_NAME_LOV,
        /* prepare transaction */
        rc = mdd_declare_xattr_set(env, mdd, fst_o, snd_buf, XATTR_NAME_LOV,
-                                  LU_XATTR_REPLACE, handle);
+                                  fst_fl, handle);
        if (rc)
                GOTO(stop, rc);
 
        if (rc)
                GOTO(stop, rc);
 
-       rc = mdd_declare_xattr_set(env, mdd, snd_o, fst_buf, XATTR_NAME_LOV,
-                                  LU_XATTR_REPLACE, handle);
+       if (fst_buf)
+               rc = mdd_declare_xattr_set(env, mdd, snd_o, fst_buf,
+                                          XATTR_NAME_LOV, LU_XATTR_REPLACE,
+                                          handle);
+       else
+               rc = mdd_declare_xattr_del(env, mdd, snd_o, XATTR_NAME_LOV,
+                                          handle);
        if (rc)
                GOTO(stop, rc);
 
        if (rc)
                GOTO(stop, rc);
 
@@ -1390,15 +1399,18 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
        if (rc)
                GOTO(stop, rc);
 
        if (rc)
                GOTO(stop, rc);
 
-       rc = mdo_xattr_set(env, fst_o, snd_buf, XATTR_NAME_LOV,
-                          LU_XATTR_REPLACE, handle,
+       rc = mdo_xattr_set(env, fst_o, snd_buf, XATTR_NAME_LOV, fst_fl, handle,
                           mdd_object_capa(env, fst_o));
        if (rc)
                GOTO(stop, rc);
 
                           mdd_object_capa(env, fst_o));
        if (rc)
                GOTO(stop, rc);
 
-       rc = mdo_xattr_set(env, snd_o, fst_buf, XATTR_NAME_LOV,
-                          LU_XATTR_REPLACE, handle,
-                          mdd_object_capa(env, snd_o));
+       if (fst_buf)
+               rc = mdo_xattr_set(env, snd_o, fst_buf, XATTR_NAME_LOV,
+                                  LU_XATTR_REPLACE, handle,
+                                  mdd_object_capa(env, snd_o));
+       else
+               rc = mdo_xattr_del(env, snd_o, XATTR_NAME_LOV, handle,
+                                  mdd_object_capa(env, snd_o));
        if (rc) {
                int     rc2;
 
        if (rc) {
                int     rc2;
 
@@ -1407,13 +1419,17 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
                /* restore object_id, object_seq and generation number
                 * on first file */
                if (fst_lmm) {
                /* restore object_id, object_seq and generation number
                 * on first file */
                if (fst_lmm) {
+                       LASSERT(old_fst_lmm != NULL);
                        fst_lmm->lmm_oi = old_fst_lmm->lmm_oi;
                        fst_lmm->lmm_layout_gen = old_fst_lmm->lmm_layout_gen;
                        fst_lmm->lmm_oi = old_fst_lmm->lmm_oi;
                        fst_lmm->lmm_layout_gen = old_fst_lmm->lmm_layout_gen;
+                       rc2 = mdo_xattr_set(env, fst_o, fst_buf, XATTR_NAME_LOV,
+                                           LU_XATTR_REPLACE, handle,
+                                           mdd_object_capa(env, fst_o));
+               } else {
+                       rc2 = mdo_xattr_del(env, fst_o, XATTR_NAME_LOV, handle,
+                                           mdd_object_capa(env, fst_o));
                }
 
                }
 
-               rc2 = mdo_xattr_set(env, fst_o, fst_buf, XATTR_NAME_LOV,
-                                   LU_XATTR_REPLACE, handle,
-                                   mdd_object_capa(env, fst_o));
                if (rc2) {
                        /* very bad day */
                        CERROR("%s: unable to roll back after swap layouts"
                if (rc2) {
                        /* very bad day */
                        CERROR("%s: unable to roll back after swap layouts"
@@ -1443,7 +1459,6 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
 
 stop:
        mdd_trans_stop(env, mdd, rc, handle);
 
 stop:
        mdd_trans_stop(env, mdd, rc, handle);
-unlock:
        mdd_write_unlock(env, o2);
        mdd_write_unlock(env, o1);
 
        mdd_write_unlock(env, o2);
        mdd_write_unlock(env, o1);
 
index a191b71..dbb7dcf 100644 (file)
@@ -9755,6 +9755,37 @@ test_184c() {
 }
 run_test 184c "Concurrent write and layout swap"
 
 }
 run_test 184c "Concurrent write and layout swap"
 
+test_184d() {
+       check_swap_layouts_support && return 0
+
+       local file1=$DIR/$tdir/$tfile-1
+       local file2=$DIR/$tdir/$tfile-2
+       local file3=$DIR/$tdir/$tfile-3
+       local lovea1
+       local lovea2
+
+       mkdir -p $DIR/$tdir
+       touch $file1 || error "create $file1 failed"
+       $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
+               error "create $file2 failed"
+       $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
+               error "create $file3 failed"
+       lovea1=$($LFS getstripe $file1 | sed 1d)
+
+       $LFS swap_layouts $file2 $file3 ||
+               error "swap $file2 $file3 layouts failed"
+       $LFS swap_layouts $file1 $file2 ||
+               error "swap $file1 $file2 layouts failed"
+
+       lovea2=$($LFS getstripe $file2 | sed 1d)
+       [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
+
+       lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
+       [ -z $lovea1 ] || error "$file1 shouldn't have lovea"
+}
+run_test 184d "allow stripeless layouts swap"
+
+
 test_185() { # LU-2441
        mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
        touch $DIR/$tdir/spoo
 test_185() { # LU-2441
        mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
        touch $DIR/$tdir/spoo
index f1d15a6..85dadd4 100644 (file)
@@ -4266,7 +4266,7 @@ int llapi_swap_layouts(const char *path1, const char *path2,
 {
        int     fd1, fd2, rc;
 
 {
        int     fd1, fd2, rc;
 
-       fd1 = open(path1, O_WRONLY);
+       fd1 = open(path1, O_WRONLY | O_LOV_DELAY_CREATE);
        if (fd1 < 0) {
                llapi_error(LLAPI_MSG_ERROR, -errno,
                                "error: cannot open for write %s",
        if (fd1 < 0) {
                llapi_error(LLAPI_MSG_ERROR, -errno,
                                "error: cannot open for write %s",
@@ -4274,7 +4274,7 @@ int llapi_swap_layouts(const char *path1, const char *path2,
                return -errno;
        }
 
                return -errno;
        }
 
-       fd2 = open(path2, O_WRONLY);
+       fd2 = open(path2, O_WRONLY | O_LOV_DELAY_CREATE);
        if (fd2 < 0) {
                llapi_error(LLAPI_MSG_ERROR, -errno,
                                "error: cannot open for write %s",
        if (fd2 < 0) {
                llapi_error(LLAPI_MSG_ERROR, -errno,
                                "error: cannot open for write %s",