Whamcloud - gitweb
LU-15519 quota: fallocate does not increase projectid usage 76/46676/7
authorArshad Hussain <arshad.hussain@aeoncomputing.com>
Mon, 14 Feb 2022 08:36:47 +0000 (14:06 +0530)
committerOleg Drokin <green@whamcloud.com>
Mon, 30 May 2022 19:04:14 +0000 (19:04 +0000)
fallocate() was not accounting for projectid quota usage.
This was happening due to two reasons. 1) the projectid
was not properly passed to md_op_data in ll_set_project()
and 2) the OBD_MD_FLPROJID flag was not set receive the
projctid.

This patch addresses the above reasons.

Test-case: sanity-quota/78a added

Fixes: 48457868a02a ("LU-3606 fallocate: Implement fallocate preallocate operation")
Signed-off-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Change-Id: I3ed44e7ef7ca8fe49a08133449c33b62b1eff500
Reviewed-on: https://review.whamcloud.com/46676
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/cl_object.h
lustre/llite/file.c
lustre/llite/vvp_object.c
lustre/lov/lov_io.c
lustre/osc/osc_io.c
lustre/tests/sanity-quota.sh

index e6cc54d..b37e2e4 100644 (file)
@@ -1881,6 +1881,7 @@ struct cl_io {
                        loff_t                   sa_falloc_end;
                        uid_t                    sa_falloc_uid;
                        gid_t                    sa_falloc_gid;
+                       __u32                    sa_falloc_projid;
                } ci_setattr;
                struct cl_data_version_io {
                        u64 dv_data_version;
index 066d209..dbf79e9 100644 (file)
@@ -2757,7 +2757,7 @@ static int ll_do_fiemap(struct inode *inode, struct fiemap *fiemap,
                        GOTO(out, rc);
        }
 
-       fmkey.lfik_oa.o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
+       fmkey.lfik_oa.o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLPROJID;
        obdo_from_inode(&fmkey.lfik_oa, inode, OBD_MD_FLSIZE);
        obdo_set_parent_fid(&fmkey.lfik_oa, &ll_i2info(inode)->lli_fid);
 
@@ -3498,8 +3498,8 @@ int ll_ioctl_check_project(struct inode *inode, __u32 xflags,
 
 static int ll_set_project(struct inode *inode, __u32 xflags, __u32 projid)
 {
-       struct md_op_data *op_data;
        struct ptlrpc_request *req = NULL;
+       struct md_op_data *op_data;
        struct cl_object *obj;
        unsigned int inode_flags;
        int rc = 0;
@@ -3517,7 +3517,10 @@ static int ll_set_project(struct inode *inode, __u32 xflags, __u32 projid)
        op_data->op_attr_flags = ll_inode_to_ext_flags(inode_flags);
        if (xflags & FS_XFLAG_PROJINHERIT)
                op_data->op_attr_flags |= LUSTRE_PROJINHERIT_FL;
+
+       /* pass projid to md_op_data */
        op_data->op_projid = projid;
+
        op_data->op_xvalid |= OP_XVALID_PROJID | OP_XVALID_FLAGS;
        rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data, NULL, 0, &req);
        ptlrpc_req_finished(req);
@@ -5371,11 +5374,11 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
 int cl_falloc(struct file *file, struct inode *inode, int mode, loff_t offset,
              loff_t len)
 {
+       loff_t size = i_size_read(inode);
        struct lu_env *env;
        struct cl_io *io;
        __u16 refcheck;
        int rc;
-       loff_t size = i_size_read(inode);
 
        ENTRY;
 
@@ -5394,12 +5397,14 @@ int cl_falloc(struct file *file, struct inode *inode, int mode, loff_t offset,
        io->u.ci_setattr.sa_falloc_end = offset + len;
        io->u.ci_setattr.sa_subtype = CL_SETATTR_FALLOCATE;
 
-       CDEBUG(D_INODE, "UID %u GID %u\n",
+       CDEBUG(D_INODE, "UID %u GID %u PRJID %u\n",
               from_kuid(&init_user_ns, inode->i_uid),
-              from_kgid(&init_user_ns, inode->i_gid));
+              from_kgid(&init_user_ns, inode->i_gid),
+              ll_i2info(inode)->lli_projid);
 
        io->u.ci_setattr.sa_falloc_uid = from_kuid(&init_user_ns, inode->i_uid);
        io->u.ci_setattr.sa_falloc_gid = from_kgid(&init_user_ns, inode->i_gid);
+       io->u.ci_setattr.sa_falloc_projid = ll_i2info(inode)->lli_projid;
 
        if (io->u.ci_setattr.sa_falloc_end > size) {
                loff_t newsize = io->u.ci_setattr.sa_falloc_end;
index 2413da9..ab5c68b 100644 (file)
@@ -198,7 +198,8 @@ static void vvp_req_attr_set(const struct lu_env *env, struct cl_object *obj,
 {
        struct inode *inode;
        struct obdo  *oa;
-       u64 valid_flags = OBD_MD_FLTYPE | OBD_MD_FLUID | OBD_MD_FLGID;
+       u64 valid_flags = OBD_MD_FLTYPE | OBD_MD_FLUID | OBD_MD_FLGID |
+                         OBD_MD_FLPROJID;
 
        oa = attr->cra_oa;
        inode = vvp_object_inode(obj);
index ce4fa30..381ae56 100644 (file)
@@ -694,6 +694,8 @@ static void lov_io_sub_inherit(struct lov_io_sub *sub, struct lov_io *lio,
                                parent->u.ci_setattr.sa_falloc_uid;
                        io->u.ci_setattr.sa_falloc_gid =
                                parent->u.ci_setattr.sa_falloc_gid;
+                       io->u.ci_setattr.sa_falloc_projid =
+                               parent->u.ci_setattr.sa_falloc_projid;
                }
                if (cl_io_is_trunc(io)) {
                        loff_t new_size = parent->u.ci_setattr.sa_attr.lvb_size;
index e4bd273..8639965 100644 (file)
@@ -680,11 +680,14 @@ static int osc_io_setattr_start(const struct lu_env *env,
                        oa->o_blocks = io->u.ci_setattr.sa_falloc_end;
                        oa->o_uid = io->u.ci_setattr.sa_falloc_uid;
                        oa->o_gid = io->u.ci_setattr.sa_falloc_gid;
+                       oa->o_projid = io->u.ci_setattr.sa_falloc_projid;
                        oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
-                               OBD_MD_FLUID | OBD_MD_FLGID;
+                               OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLPROJID;
 
-                       CDEBUG(D_INODE, "size %llu blocks %llu uid %u gid %u\n",
-                              oa->o_size, oa->o_blocks, oa->o_uid, oa->o_gid);
+                       CDEBUG(D_INODE,
+                              "size %llu blocks %llu uid %u gid %u prjid %u\n",
+                              oa->o_size, oa->o_blocks, oa->o_uid, oa->o_gid,
+                              oa->o_projid);
                        result = osc_fallocate_base(osc_export(cl2osc(obj)),
                                                    oa, osc_async_upcall,
                                                    cbargs, falloc_mode);
index 80be73d..d79ab11 100755 (executable)
@@ -5244,6 +5244,53 @@ test_78()
 }
 run_test 78 "Check fallocate increase quota usage"
 
+test_78a()
+{
+       (( $CLIENT_VERSION >= $(version_code 2.15.0) )) ||
+               skip "need client at least 2.15.0"
+       (( $OST1_VERSION >= $(version_code 2.15.0) )) ||
+               skip "need OST at least 2.15.0"
+       check_set_fallocate_or_skip
+
+       setup_quota_test || error "setup quota failed with $?"
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       mkdir -p $DIR/$tdir || error "failed to create $tdir"
+
+       local projectid=5200 # Random project id to test
+
+       change_project -sp $projectid $DIR/$tdir
+
+       # setup quota limit
+       $LFS setquota -p $projectid -b25M -B25M $DIR/$tdir ||
+               error "lfs setquota project failed"
+
+       # call fallocate
+       fallocate -l 204800 $DIR/$tdir/$tfile
+
+       # Get curspace (kbytes) for $projectid
+       local kbytes=$(getquota -p $projectid global curspace)
+
+       echo "kbytes returned:$kbytes"
+
+       # For file size of 204800. We should be having roughly 200 kbytes
+       # returned. Anything alarmingly low (50 taken as arbitrary value)
+       # would bail out this TC. Also this also avoids $kbytes of 0
+       # to be used in calculation below.
+       (( $kbytes > 50 )) ||
+               error "fallocate did not use projectid. kbytes returned:$kbytes"
+
+       local expect_lo=$(($kbytes * 95 / 100)) # 5% below
+       local expect_hi=$(($kbytes * 105 / 100)) # 5% above
+
+       # Verify kbytes is 200 (204800/1024). With a permited  5% drift
+       (( $kbytes >= $expect_lo && $kbytes <= $expect_hi )) ||
+               error "fallocate did not use quota projectid correctly"
+}
+run_test 78a "Check fallocate increase projectid usage"
+
 test_79()
 {
        local qpool="qpool1"