Whamcloud - gitweb
LU-15840 lov: return st_blocks=1 for HSM released files
authorQian Yingjin <qian@ddn.com>
Wed, 11 May 2022 08:21:12 +0000 (16:21 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Tue, 31 May 2022 15:51:48 +0000 (15:51 +0000)
The MDT will return st_blocks=1 for a HSM released file.
In the call ->coo_attr_get in LOV layer, the client should also
return st_blocks=1 for a HSM released file.

Otherwise, the client may get 0 block count. It is very easy to
reproduce this problem via the following commands for a archived
file:
# $LFS hsm_restore $file
# $LFS hsm_release $file
# $LFS hsm_release $file
After release a file twice, the reported block count via stat()
call will become 0.

Lustre-change: https://review.whamcloud.com/47291
Lustre-commit: TBD (from 974320c61ee7d165073bb2810795575261996dc7)

Change-Id: Id1841147e40a7df0ca615e887f324cff8e613f11
Signed-off-by: Qian Yingjin <qian@ddn.com>
Reviewed-on: https://review.whamcloud.com/47290
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/lov/lov_object.c
lustre/tests/sanity-hsm.sh

index bedcaf4..850b512 100644 (file)
@@ -1015,6 +1015,25 @@ static int lov_attr_get_empty(const struct lu_env *env, struct cl_object *obj,
         return 0;
 }
 
+/**
+ * The MDT returns st_blocks=1 for the HSM released file (See LU-3864).
+ * The LOV layouer should also return st_blocks=1 for the HSM released file
+ * in the call ->coo_attr_get().
+ * Otherwise, the client may get 0 block count. This caused tools like tar
+ * then to consider the file as fully sparse and to archive it as is without
+ * attempting to access/restore its content.
+ */
+static int lov_attr_get_released(const struct lu_env *env,
+                                struct cl_object *obj, struct cl_attr *attr)
+{
+       if (attr->cat_size == 0)
+               attr->cat_blocks = 0;
+       else
+               attr->cat_blocks = 1;
+
+       return 0;
+}
+
 static int lov_attr_get_composite(const struct lu_env *env,
                                  struct cl_object *obj,
                                  struct cl_attr *attr)
@@ -1117,7 +1136,7 @@ const static struct lov_layout_operations lov_dispatch[] = {
                .llo_page_init = lov_page_init_empty,
                .llo_lock_init = lov_lock_init_empty,
                .llo_io_init   = lov_io_init_released,
-               .llo_getattr   = lov_attr_get_empty,
+               .llo_getattr   = lov_attr_get_released,
                .llo_flush     = lov_flush_empty,
        },
        [LLT_COMP] = {
index 27ed436..6981896 100755 (executable)
@@ -4918,6 +4918,28 @@ test_261() {
 }
 run_test 261 "Report 0 bytes size after HSM release"
 
+test_262() {
+       local file=$DIR/$tdir/$tfile
+       local blocks
+       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_release $file || error "HSM release $file failed"
+       $LFS hsm_restore $file || error "HSM restore $file failed"
+       $LFS hsm_release $file || error "HSM release $file failed"
+       $LFS hsm_release $file || error "HSM release $file failed"
+       blocks=$(stat -c "%b" $file)
+       [ $blocks -eq "1" ] || error "wrong block number is $blocks, not 1"
+}
+run_test 262 "The client should return 1 block for HSM released files"
+
 test_300() {
        [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return