From c8210e24ded0922dc08b0667c3a4ca9f22f817f4 Mon Sep 17 00:00:00 2001 From: Qian Yingjin Date: Fri, 17 Dec 2021 16:53:37 +0800 Subject: [PATCH] LU-15381 hsm: update size upon completion of data version We found a HSM retore followed by a HSM release will set the file size with 0 wrongly during the tests. The reason is that the file size and blocks information is incorrect obtained via @ll_merger_attr(). The data version operation will flush dirty pages from all clients, the size and blocks information returns from the Lustre OST is correct. In this patch, we update the size and block attributes for a file upon the completion of the data version operation accordingly. By this way, HSM release will set the size and blocks information correctly after data version ioctl operation. Add sanity-hsm test_261. lustre-change: https://review.whamcloud.com/45935 lustre-commit: dd3b5601ec6905b00d07cbcb8c139c46dd555b3b Signed-off-by: Qian Yingjin Change-Id: Ifdbf6b58ecd00dc9677a2328438ef68529b72882 Reviewed-on: https://review.whamcloud.com/45935 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Artem Blagodarenko Reviewed-by: Oleg Drokin Reviewed-on: https://review.whamcloud.com/46336 Reviewed-by: Andreas Dilger --- lustre/include/uapi/linux/lustre/lustre_user.h | 1 + lustre/llite/file.c | 6 +++-- lustre/osc/osc_io.c | 32 +++++++++++++++++++++----- lustre/tests/sanity-hsm.sh | 30 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 705ace8..eaedc46 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -2189,6 +2189,7 @@ struct ioc_data_version { enum ioc_data_version_flags { LL_DV_RD_FLUSH = (1 << 0), /* Flush dirty pages from clients */ LL_DV_WR_FLUSH = (1 << 1), /* Flush all caching pages from clients */ + LL_DV_SZ_UPDATE = (1 << 2), /* Update the file size on the client */ }; #ifndef offsetof diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 6c68b8a..77e40a5 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2889,8 +2889,9 @@ int ll_hsm_release(struct inode *inode) struct lu_env *env; struct obd_client_handle *och = NULL; __u64 data_version = 0; - int rc; __u16 refcheck; + int rc; + ENTRY; CDEBUG(D_INODE, "%s: Releasing file "DFID".\n", @@ -2902,7 +2903,8 @@ int ll_hsm_release(struct inode *inode) GOTO(out, rc = PTR_ERR(och)); /* Grab latest data_version and [am]time values */ - rc = ll_data_version(inode, &data_version, LL_DV_WR_FLUSH); + rc = ll_data_version(inode, &data_version, + LL_DV_WR_FLUSH | LL_DV_SZ_UPDATE); if (rc != 0) GOTO(out, rc); diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index dfffa7c..0f72479 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -825,8 +825,12 @@ static void osc_io_data_version_end(const struct lu_env *env, const struct cl_io_slice *slice) { struct cl_data_version_io *dv = &slice->cis_io->u.ci_data_version; - struct osc_io *oio = cl2osc_io(env, slice); + struct osc_io *oio = cl2osc_io(env, slice); + struct cl_object *obj = slice->cis_obj; struct osc_async_cbargs *cbargs = &oio->oi_cbarg; + struct cl_attr *attr = &osc_env_info(env)->oti_attr; + struct obdo *oa = &oio->oi_oa; + unsigned int cl_valid = 0; ENTRY; wait_for_completion(&cbargs->opc_sync); @@ -835,14 +839,30 @@ static void osc_io_data_version_end(const struct lu_env *env, slice->cis_io->ci_result = cbargs->opc_rc; } else { slice->cis_io->ci_result = 0; - if (!(oio->oi_oa.o_valid & + if (!(oa->o_valid & (OBD_MD_LAYOUT_VERSION | OBD_MD_FLDATAVERSION))) slice->cis_io->ci_result = -ENOTSUPP; - if (oio->oi_oa.o_valid & OBD_MD_LAYOUT_VERSION) - dv->dv_layout_version = oio->oi_oa.o_layout_version; - if (oio->oi_oa.o_valid & OBD_MD_FLDATAVERSION) - dv->dv_data_version = oio->oi_oa.o_data_version; + if (oa->o_valid & OBD_MD_LAYOUT_VERSION) + dv->dv_layout_version = oa->o_layout_version; + if (oa->o_valid & OBD_MD_FLDATAVERSION) + dv->dv_data_version = oa->o_data_version; + + if (dv->dv_flags & LL_DV_SZ_UPDATE) { + if (oa->o_valid & OBD_MD_FLSIZE) { + attr->cat_size = oa->o_size; + cl_valid |= CAT_SIZE; + } + + if (oa->o_valid & OBD_MD_FLBLOCKS) { + attr->cat_blocks = oa->o_blocks; + cl_valid |= CAT_BLOCKS; + } + + cl_object_attr_lock(obj); + cl_object_attr_update(env, obj, attr, cl_valid); + cl_object_attr_unlock(obj); + } } EXIT; diff --git a/lustre/tests/sanity-hsm.sh b/lustre/tests/sanity-hsm.sh index a9b8572..a6c02b7 100755 --- a/lustre/tests/sanity-hsm.sh +++ b/lustre/tests/sanity-hsm.sh @@ -4831,6 +4831,36 @@ test_260c() } run_test 260c "Requests are not reordered on the 'hot' path of the coordinator" +test_261() { + local file=$DIR/$tdir/$tfile + local size + local fid + + copytool setup + mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed" + + dd if=/dev/zero of=$file bs=4k count=2 || error "Write $file failed" + fid=$(path2fid $file) + $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $file + wait_request_state $fid ARCHIVE SUCCEED + + $LFS hsm_state $file + $LFS hsm_release $file + $LFS hsm_restore $file + wait_request_state $fid RESTORE SUCCEED + $LFS hsm_release $file + size=$(stat -c %s $file) + [[ $size == 8192 ]] || error "Size after HSM release: $size" + + $LFS hsm_release $file + $LFS hsm_restore $file + $LFS hsm_release $file + size=$(stat -c %s $file) + [[ $size == 8192 ]] || error "Size after HSM release: $size" + $LFS hsm_state $file +} +run_test 261 "Report 0 bytes size after HSM release" + test_300() { [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return -- 1.8.3.1