From: Mikhail Pershin Date: Mon, 15 Feb 2021 12:25:38 +0000 (+0300) Subject: LU-14433 llite: do fallocate() size checks under lock X-Git-Tag: 2.14.52~134 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=f23ac22c4c79750fed6b05ddbe460bfc9b0f0ea5 LU-14433 llite: do fallocate() size checks under lock Check about fallocate() range vs file size in vvp_io_setattr_start() instead of ll_fallocate() so inode size cannot be changed by pending write or truncate. This implies that IO is initialized already and requires changes in LOV to update sub-IOs with proper inode size and valid size attribute values Fix also vvp_io_setattr_lock() to don't include fallocate_end in lock range Signed-off-by: Mikhail Pershin Change-Id: I8c1d295464be24d6638005bc9d46cff50656cf11 Reviewed-on: https://review.whamcloud.com/41668 Reviewed-by: Bobi Jam Reviewed-by: Andreas Dilger Reviewed-by: Arshad Hussain Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/file.c b/lustre/llite/file.c index de918fb..bdeac63 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -5152,11 +5152,6 @@ int cl_falloc(struct inode *inode, int mode, loff_t offset, loff_t len) rc = -EFBIG; goto out; } - io->u.ci_setattr.sa_attr.lvb_size = sa_falloc_end; - if (!(mode & FALLOC_FL_KEEP_SIZE)) - io->u.ci_setattr.sa_avalid |= ATTR_SIZE; - } else { - io->u.ci_setattr.sa_attr.lvb_size = size; } again: diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index e4faf2c..59fd213 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "llite_internal.h" #include "vvp_internal.h" @@ -661,7 +662,7 @@ static int vvp_io_setattr_lock(const struct lu_env *env, enqflags = CEF_DISCARD_DATA; } else if (cl_io_is_fallocate(io)) { lock_start = io->u.ci_setattr.sa_falloc_offset; - lock_end = io->u.ci_setattr.sa_falloc_end; + lock_end = io->u.ci_setattr.sa_falloc_end - 1; } else { unsigned int valid = io->u.ci_setattr.sa_avalid; @@ -729,17 +730,30 @@ static int vvp_io_setattr_time(const struct lu_env *env, static int vvp_io_setattr_start(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); + int mode = io->u.ci_setattr.sa_falloc_mode; if (cl_io_is_trunc(io)) { trunc_sem_down_write(&lli->lli_trunc_sem); mutex_lock(&lli->lli_setattr_mutex); inode_dio_wait(inode); } else if (cl_io_is_fallocate(io)) { - inode_lock(inode); + loff_t size; + + trunc_sem_down_write(&lli->lli_trunc_sem); + mutex_lock(&lli->lli_setattr_mutex); inode_dio_wait(inode); + + ll_merge_attr(env, inode); + size = i_size_read(inode); + if (io->u.ci_setattr.sa_falloc_end > size && + !(mode & FALLOC_FL_KEEP_SIZE)) { + size = io->u.ci_setattr.sa_falloc_end; + io->u.ci_setattr.sa_avalid |= ATTR_SIZE; + } + io->u.ci_setattr.sa_attr.lvb_size = size; } else { mutex_lock(&lli->lli_setattr_mutex); } @@ -764,7 +778,8 @@ static void vvp_io_setattr_end(const struct lu_env *env, mutex_unlock(&lli->lli_setattr_mutex); trunc_sem_up_write(&lli->lli_trunc_sem); } else if (cl_io_is_fallocate(io)) { - inode_unlock(inode); + mutex_unlock(&lli->lli_setattr_mutex); + trunc_sem_up_write(&lli->lli_trunc_sem); } else { mutex_unlock(&lli->lli_setattr_mutex); } diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index 5cfb773..79021f0 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -692,7 +692,7 @@ static void lov_io_sub_inherit(struct lov_io_sub *sub, struct lov_io *lio, io->u.ci_setattr.sa_falloc_offset = start; io->u.ci_setattr.sa_falloc_end = end; } - if (cl_io_is_trunc(io) || cl_io_is_fallocate(io)) { + if (cl_io_is_trunc(io)) { loff_t new_size = parent->u.ci_setattr.sa_attr.lvb_size; new_size = lov_size_to_stripe(lsm, index, new_size, @@ -1475,6 +1475,32 @@ static int lov_io_fault_start(const struct lu_env *env, RETURN(lov_io_start(env, ios)); } +static int lov_io_setattr_start(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct lov_io *lio = cl2lov_io(env, ios); + struct cl_io *parent = ios->cis_io; + struct lov_io_sub *sub; + struct lov_stripe_md *lsm = lio->lis_object->lo_lsm; + + ENTRY; + + if (cl_io_is_fallocate(parent)) { + list_for_each_entry(sub, &lio->lis_active, sub_linkage) { + loff_t size = parent->u.ci_setattr.sa_attr.lvb_size; + int index = lov_comp_entry(sub->sub_subio_index); + int stripe = lov_comp_stripe(sub->sub_subio_index); + + size = lov_size_to_stripe(lsm, index, size, stripe); + sub->sub_io.u.ci_setattr.sa_attr.lvb_size = size; + sub->sub_io.u.ci_setattr.sa_avalid = + parent->u.ci_setattr.sa_avalid; + } + } + + RETURN(lov_io_start(env, ios)); +} + static void lov_io_fsync_end(const struct lu_env *env, const struct cl_io_slice *ios) { @@ -1616,7 +1642,7 @@ static const struct cl_io_operations lov_io_ops = { .cio_iter_fini = lov_io_iter_fini, .cio_lock = lov_io_lock, .cio_unlock = lov_io_unlock, - .cio_start = lov_io_start, + .cio_start = lov_io_setattr_start, .cio_end = lov_io_end }, [CIT_DATA_VERSION] = {