From 5b91c09eb97c5d756e88d7278b7dd3fa68e54f7f Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Wed, 10 Apr 2013 03:16:15 +0800 Subject: [PATCH] LU-3125 layout: allow stripeless layouts swap * allow stripeless layouts swap * `lfs swap_layouts` should open with O_LOV_DELAY_CREATE Signed-off-by: Lai Siyao Change-Id: I3947005d1060ee9be189a9c2adbab61064a8e6f0 Reviewed-on: http://review.whamcloud.com/5998 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev --- lustre/lod/lod_object.c | 2 ++ lustre/lod/lod_qos.c | 7 ---- lustre/mdd/mdd_object.c | 81 +++++++++++++++++++++++++++------------------ lustre/tests/sanity.sh | 31 +++++++++++++++++ lustre/utils/liblustreapi.c | 4 +-- 5 files changed, 83 insertions(+), 42 deletions(-) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index bbbb3a2..0acd7fe 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -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) { + 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); } diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index a009f8b..5b05ec4 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -1233,13 +1233,6 @@ static int lod_use_defined_striping(const struct lu_env *env, 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); diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index c5a7da4..7c338e8 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -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; + int fst_fl; 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) - GOTO(unlock, rc); + GOTO(stop, rc); } 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) - GOTO(unlock, rc); + GOTO(stop, rc); } /* 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 */ @@ -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); + fst_fl = LU_XATTR_REPLACE; } 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++; @@ -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) { + /* 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; - } - if (snd_lmm) { - snd_lmm->lmm_layout_gen = cpu_to_le16(fst_gen); 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, - LU_XATTR_REPLACE, handle); + fst_fl, handle); 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); @@ -1390,15 +1399,18 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1, 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); - 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; @@ -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) { + 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; + 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" @@ -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); -unlock: mdd_write_unlock(env, o2); mdd_write_unlock(env, o1); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index a191b71..dbb7dcf 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -9755,6 +9755,37 @@ test_184c() { } 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 diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index f1d15a6..85dadd4 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -4266,7 +4266,7 @@ int llapi_swap_layouts(const char *path1, const char *path2, { 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", @@ -4274,7 +4274,7 @@ int llapi_swap_layouts(const char *path1, const char *path2, 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", -- 1.8.3.1