Whamcloud - gitweb
LU-16334 llite: update statx size/ctime for fallocate 21/49221/4
authorQian Yingjin <qian@ddn.com>
Wed, 23 Nov 2022 07:44:47 +0000 (02:44 -0500)
committerOleg Drokin <green@whamcloud.com>
Tue, 13 Dec 2022 16:08:14 +0000 (16:08 +0000)
In the VFS interface ->fallocate(), it should update i_size and
i_ctime returned by statx() accordingly when the file size grows.

Add sanity/150h.

fallocate() call does not update the attributes on MDT.
We use STATX with cached-always mode to verify it as it will not
send Glimpse lock RPCs to OSTs to obtain file size information
and use the caching attributes (size) on the client side as much
as possible.

Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: Ib8128892222a01cd00250c704328bd13cfb12e2d
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49221
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/llite/vvp_io.c
lustre/tests/sanity.sh

index f095c0a..67066ec 100644 (file)
@@ -767,17 +767,27 @@ static int vvp_io_setattr_start(const struct lu_env *env,
 static void vvp_io_setattr_end(const struct lu_env *env,
                                const struct cl_io_slice *ios)
 {
-       struct cl_io            *io    = ios->cis_io;
-       struct inode            *inode = vvp_object_inode(io->ci_obj);
-       struct ll_inode_info    *lli   = ll_i2info(inode);
+       struct cl_io *io = ios->cis_io;
+       struct inode *inode = vvp_object_inode(io->ci_obj);
+       struct ll_inode_info *lli = ll_i2info(inode);
+       loff_t size = io->u.ci_setattr.sa_attr.lvb_size;
 
        if (cl_io_is_trunc(io)) {
                /* Truncate in memory pages - they must be clean pages
                 * because osc has already notified to destroy osc_extents. */
-               vvp_do_vmtruncate(inode, io->u.ci_setattr.sa_attr.lvb_size);
+               vvp_do_vmtruncate(inode, size);
                mutex_unlock(&lli->lli_setattr_mutex);
                trunc_sem_up_write(&lli->lli_trunc_sem);
        } else if (cl_io_is_fallocate(io)) {
+               int mode = io->u.ci_setattr.sa_falloc_mode;
+
+               if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+                   size > i_size_read(inode)) {
+                       ll_inode_size_lock(inode);
+                       i_size_write(inode, size);
+                       ll_inode_size_unlock(inode);
+               }
+               inode->i_ctime = current_time(inode);
                mutex_unlock(&lli->lli_setattr_mutex);
                trunc_sem_up_write(&lli->lli_trunc_sem);
        } else {
index 3faa5e1..4487174 100755 (executable)
@@ -15275,6 +15275,24 @@ test_150g() {
 }
 run_test 150g "Verify fallocate punch on large range"
 
+test_150h() {
+       local file=$DIR/$tfile
+       local size
+
+       check_set_fallocate_or_skip
+       statx_supported || skip_env "Test must be statx() syscall supported"
+
+       # fallocate() does not update the size information on the MDT
+       fallocate -l 16K $file || error "failed to fallocate $file"
+       cancel_lru_locks $OSC
+       # STATX with cached-always mode will not send glimpse RPCs to OST,
+       # it uses the caching attrs on the client side as much as possible.
+       size=$($STATX --cached=always -c %s $file)
+       [ $size == 16384 ] ||
+               error "size after fallocate() is $size, expected 16384"
+}
+run_test 150h "Verify extend fallocate updates the file size"
+
 #LU-2902 roc_hit was not able to read all values from lproc
 function roc_hit_init() {
        local list=$(comma_list $(osts_nodes))