From: Arshad Hussain Date: Mon, 14 Feb 2022 08:36:47 +0000 (+0530) Subject: LU-15519 quota: fallocate does not increase projectid usage X-Git-Tag: 2.15.51~224 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;ds=sidebyside;h=5fc934ebbbe665f24e2f11fe224065dd8e9a08ba;p=fs%2Flustre-release.git LU-15519 quota: fallocate does not increase projectid usage 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 Change-Id: I3ed44e7ef7ca8fe49a08133449c33b62b1eff500 Reviewed-on: https://review.whamcloud.com/46676 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index e6cc54d..b37e2e4 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -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; diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 066d209..dbf79e9 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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; diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index 2413da9..ab5c68b 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -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); diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index ce4fa30..381ae56 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -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; diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index e4bd273..8639965 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -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); diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 80be73d..d79ab11 100755 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -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"