From 47ce8c5341bccdc5f8ce044be5268569d217ed5d Mon Sep 17 00:00:00 2001 From: Hongchao Zhang Date: Tue, 18 Feb 2025 16:42:32 +0800 Subject: [PATCH] LU-16265 ofd: update projid on OST by Client Occasionally it is possible that the projid of an OST object does not get the projid from the MDS, even though the projid is set correctly on the MDT inode. This patch checks the projid of the file while writing or truncating it on OST, and update its projid if it is 0 Signed-off-by: Hongchao Zhang Change-Id: If8bf071341e3b8114add5fc7a2e741d3a101ac99 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/58301 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Li Dongyang Reviewed-by: Oleg Drokin --- lustre/include/obd_support.h | 1 + lustre/ofd/ofd_objects.c | 10 +++++++++- lustre/tests/sanity-quota.sh | 45 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 24a7658..894f6da 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -708,6 +708,7 @@ extern bool obd_enable_fname_encoding; #define OBD_FAIL_OUT_EIO 0x1709 #define OBD_FAIL_BUT_UPDATE_NET_REP 0x170a #define OBD_FAIL_OUT_DROP_DESTROY 0x170b +#define OBD_FAIL_OUT_DROP_PROJID_SET 0x170c /* MIGRATE */ #define OBD_FAIL_MIGRATE_ENTRIES 0x1801 diff --git a/lustre/ofd/ofd_objects.c b/lustre/ofd/ofd_objects.c index fd895be..fa4185d 100644 --- a/lustre/ofd/ofd_objects.c +++ b/lustre/ofd/ofd_objects.c @@ -527,7 +527,10 @@ int ofd_attr_handle_id(const struct lu_env *env, struct ofd_object *fo, la->la_valid &= ~LA_UID; if (!(ln->la_mode & S_ISGID)) la->la_valid &= ~LA_GID; - if (!(ln->la_mode & S_ISVTX)) + /* LU-16265: also update the PROJID if it's 0 and + * the PROJID of the incoming request isn't 0 */ + if (!(ln->la_mode & S_ISVTX) && + (ln->la_projid != 0 || la->la_projid == 0)) la->la_valid &= ~LA_PROJID; } @@ -680,6 +683,11 @@ int ofd_attr_set(const struct lu_env *env, struct ofd_object *fo, if (!ofd_object_exists(fo)) GOTO(out, rc = -ENOENT); + + if (la->la_valid & LA_PROJID && + CFS_FAIL_CHECK(OBD_FAIL_OUT_DROP_PROJID_SET)) + la->la_valid &= ~LA_PROJID; + /* VBR: version recovery check */ rc = ofd_version_get_check(info, fo); if (rc) diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index ee693c3..615aaf1 100755 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -6791,6 +6791,51 @@ test_92() } run_test 92 "Cannot set inode limit with Quota Pools" +test_93() +{ + (( OST1_VERSION >= $(version_code 2.16.52) )) || + skip "Need OST version at least 2.16.52" + + local testfile="$DIR/$tdir/$tfile" + local cnt=30 + local usage + + setup_quota_test || error "setup quota failed with $?" + + $LFS setstripe $testfile -i 0 -c 1 || error "setstripe $testfile failed" + $DD of=$testfile count=$cnt || error "failed to write $testfile" + + cancel_lru_locks osc + sync; sync_all_data || true + sleep 5 + + usage=$(getquota -p $TSTPRJID ${FSNAME}-OST0000 curspace) + (( usage == 0 )) || error "usage for $TSTPRJID should be 0" + + #define OBD_FAIL_OUT_DROP_PROJID_SET 0x170c + do_facet ost1 $LCTL set_param fail_loc=0x8000170C + change_project -p $TSTPRJID $testfile + + cancel_lru_locks osc + sync; sync_all_data || true + sleep 5 + + usage=$(getquota -p $TSTPRJID ${FSNAME}-OST0000 curspace) + (( usage == 0 )) || error "usage for $TSTPRJID should still be 0" + + $DD of=$testfile conv=notrunc oflag=append count=5 || + error "failed to append $testfile" + + cancel_lru_locks osc + sync; sync_all_data || true + sleep 5 + + usage=$(getquota -p $TSTPRJID global curspace) + (( usage > (cnt * 1024 * 9 / 10) )) || + error "usage for $TSTPRJID is incorrect: $usage" +} +run_test 93 "update projid while client write to OST" + quota_fini() { do_nodes $(comma_list $(nodes_list)) \ -- 1.8.3.1