Whamcloud - gitweb
LU-13397 llite: support fallocate() on selected mirror 21/44721/3
authorMikhail Pershin <mpershin@whamcloud.com>
Sun, 22 Aug 2021 19:41:33 +0000 (22:41 +0300)
committerOleg Drokin <green@whamcloud.com>
Wed, 22 Sep 2021 04:41:36 +0000 (04:41 +0000)
- add ability to do fallocate() on designated mirror in
  FLR file
- add missing FALLOC_FL_KEEP_SIZE flag to fallocate() call
  in llapi_hole_punch(). It was just not working without
  that flag silently
- add corresponding test_50d in sanity-flr.sh

Fixes: 4126fbb30c ("LU-13397 lfs: mirror resync to keep sparseness")
Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: I8d700fce904c84458a50650f1d3cb09d23989eba
Reviewed-on: https://review.whamcloud.com/44721
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/file.c
lustre/lov/lov_io.c
lustre/tests/sanity-flr.sh
lustre/utils/liblustreapi_lseek.c

index 75a01e4..0021c76 100644 (file)
@@ -5335,7 +5335,8 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
 }
 #endif
 
-int cl_falloc(struct inode *inode, int mode, loff_t offset, loff_t len)
+int cl_falloc(struct file *file, struct inode *inode, int mode, loff_t offset,
+             loff_t len)
 {
        struct lu_env *env;
        struct cl_io *io;
@@ -5351,6 +5352,8 @@ int cl_falloc(struct inode *inode, int mode, loff_t offset, loff_t len)
 
        io = vvp_env_thread_io(env);
        io->ci_obj = ll_i2info(inode)->lli_clob;
+       ll_io_set_mirror(io, file);
+
        io->ci_verify_layout = 1;
        io->u.ci_setattr.sa_parent_fid = lu_object_fid(&io->ci_obj->co_lu);
        io->u.ci_setattr.sa_falloc_mode = mode;
@@ -5389,7 +5392,7 @@ out:
 
 long ll_fallocate(struct file *filp, int mode, loff_t offset, loff_t len)
 {
-       struct inode *inode = filp->f_path.dentry->d_inode;
+       struct inode *inode = file_inode(filp);
        int rc;
 
        if (offset < 0 || len <= 0)
@@ -5414,7 +5417,7 @@ long ll_fallocate(struct file *filp, int mode, loff_t offset, loff_t len)
 
        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FALLOCATE, 1);
 
-       rc = cl_falloc(inode, mode, offset, len);
+       rc = cl_falloc(filp, inode, mode, offset, len);
        /*
         * ENOTSUPP (524) is an NFSv3 specific error code erroneously
         * used by Lustre in several places. Retuning it here would
index 56706b4..b3fd6d8 100644 (file)
@@ -331,7 +331,8 @@ static int lov_io_mirror_init(struct lov_io *lio, struct lov_object *obj,
                CDEBUG(D_LAYOUT, "designated I/O mirror state: %d\n",
                      lov_flr_state(obj));
 
-               if ((cl_io_is_trunc(io) || io->ci_type == CIT_WRITE) &&
+               if ((cl_io_is_trunc(io) || io->ci_type == CIT_WRITE ||
+                    cl_io_is_fallocate(io)) &&
                    (io->ci_layout_version != obj->lo_lsm->lsm_layout_gen)) {
                        /*
                         * For resync I/O, the ci_layout_version was the layout
index cff383e..a6dc15d 100644 (file)
@@ -2674,6 +2674,65 @@ test_50c() {
 }
 run_test 50c "punch_hole/mmap_write stale other mirrors"
 
+test_50d() {
+       $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
+               skip "OST does not support SEEK_HOLE"
+       (( $LINUX_VERSION_CODE > $(version_code 3.0.0) )) ||
+               skip "client kernel does not support SEEK_HOLE"
+
+       local file=$DIR/$tdir/$tfile
+       local offset
+       local prt
+       local rc
+
+       mkdir -p $DIR/$tdir
+
+       echo " ** create mirrored file $file"
+       $LFS mirror create -N -E1M -c1 -S1M -E eof \
+               -N -E2M -S1M -E eof -S2M $file ||
+               error "cannot create mirrored file"
+       echo " ** write data chunk at 1M boundary"
+       dd if=/dev/urandom of=$file bs=1k count=20 seek=1021 ||
+               error "cannot write data at 1M boundary"
+       echo " ** create hole at the file start"
+       prt=$(fallocate -p -o 0 -l 1M $file 2>&1)
+       rc=$?
+
+       if [[ $rc -eq 0 ]]; then
+               verify_flr_state $file "wp"
+       elif [[ ! $prt =~ "unsupported" ]]; then
+               error "punch hole in $file failed: $prt"
+       else
+               skip "Fallocate punch is not supported"
+       fi
+
+       echo " ** verify sparseness"
+       offset=$(lseek_test -d 1000 $file)
+       echo "    first data offset: $offset"
+       (( $offset >= 1024 * 1024 )) ||
+               error "src: data is not expected at offset $offset"
+
+       echo " ** resync mirror #2"
+       $LFS mirror resync $file
+
+       # check llapi_mirror_copy_many correctness
+       sum_1=$($LFS mirror read -N 1 $file | md5sum)
+       sum_2=$($LFS mirror read -N 2 $file | md5sum)
+       [[ $sum_1 == $sum_2 ]] ||
+               error "data mismatch: \'$sum_1\' vs. \'$sum_2\'"
+
+       cancel_lru_locks osc
+
+       # stale first component in mirror #1
+       $LFS setstripe --comp-set -I0x10001 --comp-flags=stale,nosync $file
+       echo " ** verify sparseness of mirror #2"
+       offset=$(lseek_test -d 1000 $file)
+       echo "    first data offset: $offset"
+       (( $offset >= 1024 * 1024 )) ||
+               error "src: data is not expected at offset $offset"
+}
+run_test 50d "mirror rsync keep holes"
+
 test_60a() {
        $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
                skip "OST does not support SEEK_HOLE"
index cd3f008..9073999 100644 (file)
@@ -127,7 +127,8 @@ int llapi_hole_punch(int fd, off_t start, size_t length)
 {
        int rc;
 
-       rc = fallocate(fd, FALLOC_FL_PUNCH_HOLE, start, length);
+       rc = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+                      start, length);
        if (rc)
                rc = -errno;
        return rc;