From: Marc Vef Date: Wed, 2 Apr 2025 19:49:59 +0000 (+0200) Subject: LU-18757 client: Set UID/GID/PROJID on OST for OST_PUNCH RPC X-Git-Tag: 2.16.55~129 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=e6298c804fedfa2265c4674d9e7d9a2ceb14b25b;p=fs%2Flustre-release.git LU-18757 client: Set UID/GID/PROJID on OST for OST_PUNCH RPC The OST_PUNCH RPC (as generated by "truncate -s" commands) does not set the UID/GID/PROJID stored on an OST object. This is because the obdo fields and corresponding valid flags are not set on the client and OST sides. This patch adds support for setting UID/GID/PROJID on the corresponding OST objects for operations that send the OST_PUNCH RPC. Sanity-sec test_75 is added to check that the IDs are set on the OST objects. Signed-off-by: Marc Vef Change-Id: I9baabbe9e523c98523fa30d387197e1faf38199a Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/58647 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index d7237e7..bd63a16 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -1793,9 +1793,10 @@ struct cl_io { int sa_falloc_mode; loff_t sa_falloc_offset; loff_t sa_falloc_end; - uid_t sa_falloc_uid; - gid_t sa_falloc_gid; - __u32 sa_falloc_projid; + /* id fields used for truncate/fallocate */ + uid_t sa_attr_uid; + gid_t sa_attr_gid; + __u32 sa_attr_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 549cbf6..e3b4a90 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -3096,8 +3096,8 @@ static ssize_t ll_lov_setstripe(struct inode *inode, struct file *file, ll_i2info(inode)->lli_clob) { struct iattr attr = { 0 }; - rc = cl_setattr_ost(ll_i2info(inode)->lli_clob, &attr, - OP_XVALID_FLAGS, LUSTRE_ENCRYPT_FL); + rc = cl_setattr_ost(inode, &attr, OP_XVALID_FLAGS, + LUSTRE_ENCRYPT_FL); } } cl_lov_delay_create_clear(&file->f_flags); @@ -4269,7 +4269,6 @@ int ll_set_project(struct inode *inode, __u32 xflags, __u32 projid) { struct ptlrpc_request *req = NULL; struct md_op_data *op_data; - struct cl_object *obj; int rc = 0; CDEBUG(D_QUOTA, DFID" xflags=%x projid=%u\n", @@ -4299,11 +4298,10 @@ int ll_set_project(struct inode *inode, __u32 xflags, __u32 projid) if (xflags == 0 || xflags == FS_XFLAG_PROJINHERIT) GOTO(out_fsxattr, rc); - obj = ll_i2info(inode)->lli_clob; - if (obj) { + if (ll_i2info(inode)->lli_clob) { struct iattr attr = { 0 }; - rc = cl_setattr_ost(obj, &attr, OP_XVALID_FLAGS, xflags); + rc = cl_setattr_ost(inode, &attr, OP_XVALID_FLAGS, xflags); } out_fsxattr: @@ -6492,9 +6490,9 @@ static int cl_falloc(struct file *file, struct inode *inode, int mode, 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; + io->u.ci_setattr.sa_attr_uid = from_kuid(&init_user_ns, inode->i_uid); + io->u.ci_setattr.sa_attr_gid = from_kgid(&init_user_ns, inode->i_gid); + io->u.ci_setattr.sa_attr_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/lcommon_cl.c b/lustre/llite/lcommon_cl.c index d83f892..7e7733e 100644 --- a/lustre/llite/lcommon_cl.c +++ b/lustre/llite/lcommon_cl.c @@ -46,16 +46,19 @@ __u16 cl_inode_fini_refcheck; */ static DEFINE_MUTEX(cl_inode_fini_guard); -int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr, +int cl_setattr_ost(struct inode *inode, const struct iattr *attr, enum op_xvalid xvalid, unsigned int attr_flags) { + struct cl_object *obj; struct lu_env *env; - struct cl_io *io; + struct cl_io *io; int result; __u16 refcheck; ENTRY; + obj = ll_i2info(inode)->lli_clob; + env = cl_env_get(&refcheck); if (IS_ERR(env)) RETURN(PTR_ERR(env)); @@ -72,8 +75,14 @@ int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr, io->u.ci_setattr.sa_avalid = attr->ia_valid; io->u.ci_setattr.sa_xvalid = xvalid; io->u.ci_setattr.sa_parent_fid = lu_object_fid(&obj->co_lu); - if (attr->ia_valid & ATTR_SIZE) + if (attr->ia_valid & ATTR_SIZE) { io->u.ci_setattr.sa_subtype = CL_SETATTR_TRUNC; + io->u.ci_setattr.sa_attr_uid = + from_kuid(&init_user_ns, current_uid()); + io->u.ci_setattr.sa_attr_gid = + from_kgid(&init_user_ns, current_gid()); + io->u.ci_setattr.sa_attr_projid = ll_i2info(inode)->lli_projid; + } again: if (attr->ia_valid & ATTR_FILE) ll_io_set_mirror(io, attr->ia_file); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index ff10cb5..006bfc0 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -2116,7 +2116,7 @@ int ll_page_sync_io(const struct lu_env *env, struct cl_io *io, int ll_getparent(struct file *file, struct getparent __user *arg); /* lcommon_cl.c */ -int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr, +int cl_setattr_ost(struct inode *inode, const struct iattr *attr, enum op_xvalid xvalid, unsigned int attr_flags); extern struct lu_env *cl_inode_fini_env; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 56dff93..7b64959 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2448,7 +2448,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, attr->ia_size = ref_attr.cat_size; } } - rc = cl_setattr_ost(lli->lli_clob, attr, xvalid, flags); + rc = cl_setattr_ost(inode, attr, xvalid, flags); } } @@ -3256,7 +3256,6 @@ static int fileattr_set(struct inode *inode, int flags) struct ll_sb_info *sbi = ll_i2sbi(inode); struct ptlrpc_request *req = NULL; struct md_op_data *op_data; - struct cl_object *obj; struct fsxattr fa = { 0 }; struct iattr *attr; int rc; @@ -3286,15 +3285,14 @@ static int fileattr_set(struct inode *inode, int flags) ll_update_inode_flags(inode, flags); - obj = ll_i2info(inode)->lli_clob; - if (obj == NULL) + if (!ll_i2info(inode)->lli_clob) RETURN(0); OBD_ALLOC_PTR(attr); if (attr == NULL) RETURN(-ENOMEM); - rc = cl_setattr_ost(obj, attr, OP_XVALID_FLAGS, flags); + rc = cl_setattr_ost(inode, attr, OP_XVALID_FLAGS, flags); OBD_FREE_PTR(attr); RETURN(rc); diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index dcf41b53..bc0669a 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -715,12 +715,12 @@ static void lov_io_sub_inherit(struct lov_io_sub *sub, struct lov_io *lio, if (cl_io_is_fallocate(io)) { io->u.ci_setattr.sa_falloc_offset = start; io->u.ci_setattr.sa_falloc_end = end; - io->u.ci_setattr.sa_falloc_uid = - 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; + io->u.ci_setattr.sa_attr_uid = + parent->u.ci_setattr.sa_attr_uid; + io->u.ci_setattr.sa_attr_gid = + parent->u.ci_setattr.sa_attr_gid; + io->u.ci_setattr.sa_attr_projid = + parent->u.ci_setattr.sa_attr_projid; } if (cl_io_is_trunc(io)) { loff_t new_size = parent->u.ci_setattr.sa_attr.lvb_size; @@ -728,6 +728,12 @@ static void lov_io_sub_inherit(struct lov_io_sub *sub, struct lov_io *lio, new_size = lov_size_to_stripe(lsm, index, new_size, stripe); io->u.ci_setattr.sa_attr.lvb_size = new_size; + io->u.ci_setattr.sa_attr_uid = + parent->u.ci_setattr.sa_attr_uid; + io->u.ci_setattr.sa_attr_gid = + parent->u.ci_setattr.sa_attr_gid; + io->u.ci_setattr.sa_attr_projid = + parent->u.ci_setattr.sa_attr_projid; } lov_lsm2layout(lsm, lsm->lsm_entries[index], &io->u.ci_setattr.sa_layout); diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index 47c2d0a..253d68d 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -2105,7 +2105,8 @@ static int ofd_punch_hdl(struct tgt_session_info *tsi) GOTO(out, rc = PTR_ERR(fo)); la_from_obdo(&info->fti_attr, oa, - OBD_MD_FLMTIME | OBD_MD_FLATIME | OBD_MD_FLCTIME); + OBD_MD_FLMTIME | OBD_MD_FLATIME | OBD_MD_FLCTIME | + OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLPROJID); info->fti_attr.la_size = start; info->fti_attr.la_valid |= LA_SIZE; diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index 40f76f0..ca0d9d3 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -663,9 +663,9 @@ static int osc_io_setattr_start(const struct lu_env *env, oa->o_size = io->u.ci_setattr.sa_falloc_offset; 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_uid = io->u.ci_setattr.sa_attr_uid; + oa->o_gid = io->u.ci_setattr.sa_attr_gid; + oa->o_projid = io->u.ci_setattr.sa_attr_projid; oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLPROJID; @@ -679,7 +679,12 @@ static int osc_io_setattr_start(const struct lu_env *env, } else if (ia_avalid & ATTR_SIZE) { oa->o_size = size; oa->o_blocks = OBD_OBJECT_EOF; - oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS; + oa->o_uid = io->u.ci_setattr.sa_attr_uid; + oa->o_gid = io->u.ci_setattr.sa_attr_gid; + oa->o_projid = io->u.ci_setattr.sa_attr_projid; + oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | + OBD_MD_FLUID | OBD_MD_FLGID | + OBD_MD_FLPROJID; result = osc_punch_send(osc_export(cl2osc(obj)), oa, osc_async_upcall, cbargs); } else { diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index 055dd7d..413712a 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -7705,6 +7705,72 @@ test_74() { } run_test 74 "Set nodemap deny_mount flag" +check_ost_object_ids() { + local file=$1 + local expected_uid=$2 + local expected_gid=$3 + local expected_projid=$4 + local objdump=$DIR/$tdir/objdump + + mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" + + # Get the OST object path. We assume the file has one stripe on ost1 + local fids=($($LFS getstripe $file | grep 0x)) + local fid="${fids[3]}:${fids[2]}:0" + local objpath=$(ost_fid2_objpath ost1 $fid) + + do_facet ost1 "$DEBUGFS -c -R 'stat $objpath' $(ostdevname 1)" | \ + grep "Project" > $objdump + local obj_uid=$(awk '{print $2}' $objdump) + local obj_gid=$(awk '{print $4}' $objdump) + local obj_projid=$(awk '{print $6}' $objdump) + echo "OST object ids and size for file '$file': $(cat $objdump)" + + [[ "$obj_uid" == "$expected_uid" ]] || + error "uid is not set to expected value $expected_uid" + [[ "$obj_gid" == "$expected_gid" ]] || + error "gid is not set to expected value $expected_gid" + [[ "$obj_projid" == "$expected_projid" ]] || + error "projid is not set to expected value $expected_projid" +} + +test_75() { + local tfile_write=$DIR/$tdir/${tfile}_write + local tfile_trunc=$DIR/$tdir/${tfile}_trunc + local testdir_projid=42 + + (( $OST1_VERSION >= $(version_code 2.16.53) && + $CLIENT_VERSION >= $(version_code 2.16.53) )) || + skip "Both client and OST need at least 2.16.53" + + [[ "$ost1_FSTYPE" == ldiskfs ]] || + skip "ldiskfs only test (using debugfs)" + + # setup + mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" + $LFS project -s -p $testdir_projid $DIR/$tdir || + error "lfs project failed" + chown $USER0 $DIR/$tdir || error "chown Failed" + + # Sanity check IDs with OST_WRITE RPC + $RUNAS_CMD -u $ID0 $LFS setstripe -c 1 -i 0 $tfile_write + $RUNAS_CMD -u $ID0 dd if=/dev/urandom of=$tfile_write bs=1M count=1 && \ + sync + + # OST_PUNCH RPC (via truncate) setting OST object IDs correctly + $RUNAS_CMD -u $ID0 $LFS setstripe -c 1 -i 0 $tfile_trunc + $RUNAS_CMD -u $ID0 $TRUNCATE $tfile_trunc 1048576 && sync + + # wait for asynchronous MDS-OST sync and force flush to OST + sync_all_data + wait_mds_ost_sync || error "wait_mds_ost_sync failed" + do_facet ost1 "sync; sync" + + check_ost_object_ids $tfile_write $ID0 $ID0 $testdir_projid + check_ost_object_ids $tfile_trunc $ID0 $ID0 $testdir_projid +} +run_test 75 "check uid/gid/projid are set on OST for OST_PUNCH RPC" + log "cleanup: ======================================================" sec_unsetup() {