From 51851705e936b2dbc9cf141ecf7ab4e3be04333a Mon Sep 17 00:00:00 2001 From: Qian Yingjin Date: Wed, 23 Nov 2022 02:44:47 -0500 Subject: [PATCH] LU-16334 llite: update statx size/ctime for fallocate 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 Change-Id: Ib8128892222a01cd00250c704328bd13cfb12e2d Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49221 Reviewed-by: Oleg Drokin Reviewed-by: Arshad Hussain Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo --- lustre/llite/vvp_io.c | 18 ++++++++++++++---- lustre/tests/sanity.sh | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index f095c0a..67066ec 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -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 { diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 3faa5e1..4487174 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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)) -- 1.8.3.1