Whamcloud - gitweb
LU-15840 lov: return st_blocks=1 for HSM released files 91/47291/4
authorQian Yingjin <qian@ddn.com>
Wed, 11 May 2022 08:21:12 +0000 (16:21 +0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 2 Apr 2024 20:59:27 +0000 (20:59 +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.

Change-Id: Id1841147e40a7df0ca615e887f324cff8e613f11
Signed-off-by: Qian Yingjin <qian@ddn.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/47291
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Etienne AUJAMES <eaujames@ddn.com>
lustre/lov/lov_object.c
lustre/tests/sanity-hsm.sh

index 865635e..9f78d62 100644 (file)
@@ -1032,6 +1032,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)
@@ -1138,7 +1157,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 196fa6e..7f5d893 100755 (executable)
@@ -5015,6 +5015,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