Whamcloud - gitweb
LU-14433 llite: do fallocate() size checks under lock 68/41668/9
authorMikhail Pershin <mpershin@whamcloud.com>
Mon, 15 Feb 2021 12:25:38 +0000 (15:25 +0300)
committerOleg Drokin <green@whamcloud.com>
Wed, 21 Apr 2021 03:14:53 +0000 (03:14 +0000)
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 <mpershin@whamcloud.com>
Change-Id: I8c1d295464be24d6638005bc9d46cff50656cf11
Reviewed-on: https://review.whamcloud.com/41668
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/file.c
lustre/llite/vvp_io.c
lustre/lov/lov_io.c

index de918fb..bdeac63 100644 (file)
@@ -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:
index e4faf2c..59fd213 100644 (file)
@@ -40,6 +40,7 @@
 #include <obd.h>
 #include <linux/pagevec.h>
 #include <linux/memcontrol.h>
+#include <linux/falloc.h>
 
 #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);
        }
index 5cfb773..79021f0 100644 (file)
@@ -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] = {