From 9d8dbed27c042124fa30f958093c7ee4f7af0872 Mon Sep 17 00:00:00 2001 From: Shaun Tancheff Date: Mon, 5 May 2025 13:20:37 -0700 Subject: [PATCH] LU-16594 build: get_random_u32_below, get_acl with dentry Linux commit v6.1-13825-g3c202d14a9d7 prandom: remove prandom_u32_max() Use get_random_u32_below() and provide a replacement when get_random_u32_below is not available. Linux commit v6.1-rc1-2-g138060ba92b3 fs: pass dentry to set acl method Linux commit v6.1-rc1-4-g7420332a6ff4 fs: add new get acl method get_acl() and set_acl() have new signatures Lustre-change: https://review.whamcloud.com/50193 Lustre-commit: 3ef773db80fc346455c9939ad108f3f56990ee9c Was-Change-Id: I1de02f86fd2719fc75de4f014f51d73736d83c33 LU-18127 autoconf: fix configure tests -Warray-bounds errors Kernel commit v5.17-rc3-1-ge6148767825c (Makefile: Enable -Warray-bounds) enabled -Warray-bounds option, which caused Lustre configure tests hit false failures as follows: build/conftest.c: In function 'main': build/conftest.c:228:39: error: array subscript 0 is outside array bounds of 'struct inode_operations[0]' [-Werror=array-bounds] 228 | ((struct inode_operations *)1)->get_acl((struct inode *)NULL, 0, false); | ^~ cc1: all warnings being treated as errors This patch fixes the "struct inode_operations" related configure tests to avoid the above failures. The -Warray-bounds option was disabled by the following kernel commits: - v5.19-rc1-28-gf0be87c42cbd (gcc-12: disable '-Warray-bounds' universally for now) - v6.2-rc3-9-g5a41237ad1d4 (gcc: disable -Warray-bounds for gcc-11 too) - v6.3-rc7-202-g0da6e5fd6c37 (gcc: disable '-Warray-bounds' for gcc-13 too) Lustre-change: https://review.whamcloud.com/55989 Lustre-commit: a78894ee642d423a244fc0dcbc518c57a458a2db Was-Change-Id: Iee73962ffc117a2f98e8f339462820aff2278815 Signed-off-by: Jian Yu LU-18388 llite: handle -EOPNOTSUPP in get_inode_acl When ll_xattr_list returns -EOPNOTSUPP [-95] NULL should be returned to avoid sanity failing to run as non-root users with: operation mds_getxattr to node 192.168.122.50@tcp failed: rc = -95 Fixes: 13fd5ebef3 ("LU-18101 sec: fix ACL handling on recent kernels again") Lustre-change: https://review.whamcloud.com/56756 Lustre-commit: 7e457159a097d69e76097c55c75546163a44befa Was-Change-Id: I208e7e6095c19728643a6d208becd448ed2e2539 LU-18070 sec: clear ACL caches if ACL empty When the lli_posix_acl field of struct ll_inode_info is updated, check if new ACL is empty, and clear ACL caches for this inode in this case. Also fix sanity test_103a when it is run with multiple MDTs. The test has several requirements regarding uids and gids, but in case they are not met, missing ids are only configured on mds1. So make sure the directory used for the test ($DIR/$tdir) is created on mds1. Fixes: 13fd5ebef3 ("LU-18101 sec: fix ACL handling on recent kernels again") Fixes: aa636f8ae6 ("LU-18095 sec: fix ACL handling on recent kernels") Lustre-change: https://review.whamcloud.com/56600 Lustre-commit: 659bb1d704317346ebfde1899c8ee8b38c9c3f80 Was-Change-Id: I91109bf98bc65dfb1fcefb2551be84d9c73f8ee2 Signed-off-by: Sebastien Buisson LU-18101 sec: fix ACL handling on recent kernels again On recent distributions like Ubuntu 24.04, the kernel offers the .get_inode_acl op on struct inode_operations. This must be defined and fetch ACLs, otherwise they can end up being incorrect on inodes. Lustre-change: https://review.whamcloud.com/56552 Lustre-commit: 13fd5ebef3a7a1ae3574458674e16ca782b181e7 Was-Change-Id: Idcc642a11f6f6198217e5eadb2a2c32e8117b8b7 Fixes: aa636f8ae6 ("LU-18095 sec: fix ACL handling on recent kernels") Signed-off-by: Sebastien Buisson LU-18095 sec: fix ACL handling on recent kernels On recent distributions like Ubuntu 24.04, the kernel imposes that ACLs are fetched via the dedicated .get_acl operation (or .get_inode_acl) instead of doing this via the xattr handlers. So in ll_get_acl() explicitly fetch the xattr containing ACLs, XATTR_NAME_ACL_ACCESS or XATTR_NAME_ACL_DEFAULT. This is going to populate to xattr cache, hence avoiding multiple requests to the MDS. Also fix sanity-sec test_23b to make sure variable comparisons are correct. And fix test cleanup to avoid leftovers. Lustre-change: https://review.whamcloud.com/56254 Lustre-commit: aa636f8ae6883cef018b859bba70140df9a826c4 Was-Change-Id: I467d5a558eaa524e823527a8798478934f65abf9 Signed-off-by: Sebastien Buisson LU-18329 tests: check version for parallel-scale-nfs/test_1 Check the lustre client version of nfs server (MDS1 by default) in parallel-scale-nfs/test_1 for interop test. Lustre-change: https://review.whamcloud.com/56674 Lustre-commit: ebfdfd587bc5804acf48d444b182fa9b7ef4d3c9 Was-Change-Id: I76ecb3bc28f37ba7d0c24d18eead621d6b066800 Test-Parameters: testlist=parallel-scale-nfsv3 env=ONLY=1 Test-Parameters: serverversion=2.15.5 testlist=parallel-scale-nfsv3 env=ONLY=1 Fixes: 69dcd1b940 ("LU-18030 tests: Add a test to ensure permissions copy on nfs") Signed-off-by: Feng Lei LU-18030 tests: Add a test to ensure permissions copy on nfs Also ensure no empty POSIX ACL is created. Lustre-change: https://review.whamcloud.com/56176 Lustre-commit: 69dcd1b940ce43af17489b0268d16c5186cf0325 Was-Change-Id: I85d37f8eebd17d6acdb67c552fec2caa79dbd39c Test-Parameters: testlist=parallel-scale-nfsv3 LU-18030 llite: make ll_set_acl send xattr to server unmodified Otherwise posix_acl_update_mode might convert acl into inode mode change and as the result it's lost and the existing ACL xattr is removed (if any Lustre-change: https://review.whamcloud.com/55715 Lustre-commit: 75f55f99a328923ec9fb5bb4ca3418aa11bbe336 Was-Change-Id: I3956beac04889a657f76f9b36dbe97518ae9f2ac LU-14707 tests: Bashify more scripts for Ubuntu et. al. Some scripts that are not POSIX sh are being invoked using sh. The scripts should be called using the shell listed in the shebang. Lustre-change: https://review.whamcloud.com/49296 Lustre-commit: 2faee9972cdcde6652db1a857b548b3f7396944b Was-Change-Id: I7233ce56df95a5b8698b39872e6118a4fa1a029a Signed-off-by: Timothy Day HPE-bug-id: LUS-11556 Signed-off-by: Shaun Tancheff Change-Id: I1de02f86fd2719fc75de4f014f51d73736d83c33 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59109 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- contrib/scripts/spelling.txt | 1 + libcfs/libcfs/fail.c | 2 +- lnet/lnet/net_fault.c | 28 ++++----- lnet/lnet/router.c | 2 +- lustre/autoconf/lustre-core.m4 | 106 ++++++++++++++++++++++++++++++++--- lustre/llite/acl.c | 98 ++++++++++++++++++++++++++++---- lustre/llite/file.c | 3 + lustre/llite/llite_internal.h | 34 ++++++++--- lustre/llite/llite_lib.c | 2 +- lustre/llite/namei.c | 6 ++ lustre/lod/lod_qos.c | 4 +- lustre/mgc/mgc_request.c | 2 +- lustre/obdclass/lu_tgt_descs.c | 4 +- lustre/ptlrpc/nrs_delay.c | 4 +- lustre/tests/acceptance-small.sh | 2 +- lustre/tests/ost_oos.sh | 4 +- lustre/tests/parallel-scale-nfs.sh | 42 ++++++++++++++ lustre/tests/parallel-scale-nfsv4.sh | 2 +- lustre/tests/sanity-sec.sh | 39 ++++++++----- lustre/tests/sanity.sh | 2 +- lustre/tests/test-framework.sh | 31 ++++++---- 21 files changed, 338 insertions(+), 80 deletions(-) diff --git a/contrib/scripts/spelling.txt b/contrib/scripts/spelling.txt index 055a18b..bc8bc2d 100644 --- a/contrib/scripts/spelling.txt +++ b/contrib/scripts/spelling.txt @@ -199,6 +199,7 @@ page_cache_release||put_page PAGE_CACHE_SHIFT||PAGE_SHIFT PAGE_CACHE_SIZE||PAGE_SIZE prandom_u32||get_random_u32 +prandom_u32_max||get_random_u32_below return seq_printf||seq_printf setup_timer||cfs_timer_setup = seq_printf||seq_printf diff --git a/libcfs/libcfs/fail.c b/libcfs/libcfs/fail.c index 00c4c2b..5623e3f 100644 --- a/libcfs/libcfs/fail.c +++ b/libcfs/libcfs/fail.c @@ -64,7 +64,7 @@ int __cfs_fail_check_set(u32 id, u32 value, int set) /* Fail 1/cfs_fail_val times */ if (cfs_fail_loc & CFS_FAIL_RAND) { - if (cfs_fail_val < 2 || prandom_u32_max(cfs_fail_val) > 0) + if (cfs_fail_val < 2 || get_random_u32_below(cfs_fail_val) > 0) return 0; } diff --git a/lnet/lnet/net_fault.c b/lnet/lnet/net_fault.c index 98bdb16..0ad206b 100644 --- a/lnet/lnet/net_fault.c +++ b/lnet/lnet/net_fault.c @@ -174,9 +174,9 @@ lnet_drop_rule_add(struct lnet_fault_attr *attr) if (attr->u.drop.da_interval != 0) { rule->dr_time_base = ktime_get_seconds() + attr->u.drop.da_interval; rule->dr_drop_time = ktime_get_seconds() + - prandom_u32_max(attr->u.drop.da_interval); + get_random_u32_below(attr->u.drop.da_interval); } else { - rule->dr_drop_at = prandom_u32_max(attr->u.drop.da_rate); + rule->dr_drop_at = get_random_u32_below(attr->u.drop.da_rate); } lnet_net_lock(LNET_LOCK_EX); @@ -281,10 +281,10 @@ lnet_drop_rule_reset(void) memset(&rule->dr_stat, 0, sizeof(rule->dr_stat)); if (attr->u.drop.da_rate != 0) { - rule->dr_drop_at = prandom_u32_max(attr->u.drop.da_rate); + rule->dr_drop_at = get_random_u32_below(attr->u.drop.da_rate); } else { rule->dr_drop_time = ktime_get_seconds() + - prandom_u32_max(attr->u.drop.da_interval); + get_random_u32_below(attr->u.drop.da_interval); rule->dr_time_base = ktime_get_seconds() + attr->u.drop.da_interval; } spin_unlock(&rule->dr_lock); @@ -303,7 +303,7 @@ lnet_fault_match_health(enum lnet_msg_hstatus *hstatus, __u32 mask) int i; /* assign a random failure */ - choice = prandom_u32_max(LNET_MSG_STATUS_END - LNET_MSG_STATUS_OK); + choice = get_random_u32_below(LNET_MSG_STATUS_END - LNET_MSG_STATUS_OK); if (choice == 0) choice++; @@ -369,7 +369,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, /* match this rule, check drop rate now */ spin_lock(&rule->dr_lock); if (attr->u.drop.da_random) { - int value = prandom_u32_max(attr->u.drop.da_interval); + int value = get_random_u32_below(attr->u.drop.da_interval); if (value >= (attr->u.drop.da_interval / 2)) drop = true; else @@ -384,7 +384,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, rule->dr_time_base = now; rule->dr_drop_time = rule->dr_time_base + - prandom_u32_max(attr->u.drop.da_interval); + get_random_u32_below(attr->u.drop.da_interval); rule->dr_time_base += attr->u.drop.da_interval; CDEBUG(D_NET, "Drop Rule %s->%s: next drop : %lld\n", @@ -400,7 +400,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, count = rule->dr_stat.fs_count; if (do_div(count, attr->u.drop.da_rate) == 0) { rule->dr_drop_at = rule->dr_stat.fs_count + - prandom_u32_max(attr->u.drop.da_rate); + get_random_u32_below(attr->u.drop.da_rate); CDEBUG(D_NET, "Drop Rule %s->%s: next drop: %lu\n", libcfs_nid2str(attr->fa_src), libcfs_nid2str(attr->fa_dst), rule->dr_drop_at); @@ -552,7 +552,7 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, rule->dl_time_base = now; rule->dl_delay_time = rule->dl_time_base + - prandom_u32_max(attr->u.delay.la_interval); + get_random_u32_below(attr->u.delay.la_interval); rule->dl_time_base += attr->u.delay.la_interval; CDEBUG(D_NET, "Delay Rule %s->%s: next delay : %lld\n", @@ -569,7 +569,7 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, count = rule->dl_stat.fs_count; if (do_div(count, attr->u.delay.la_rate) == 0) { rule->dl_delay_at = rule->dl_stat.fs_count + - prandom_u32_max(attr->u.delay.la_rate); + get_random_u32_below(attr->u.delay.la_rate); CDEBUG(D_NET, "Delay Rule %s->%s: next delay: %lu\n", libcfs_nid2str(attr->fa_src), libcfs_nid2str(attr->fa_dst), rule->dl_delay_at); @@ -861,9 +861,9 @@ lnet_delay_rule_add(struct lnet_fault_attr *attr) rule->dl_time_base = ktime_get_seconds() + attr->u.delay.la_interval; rule->dl_delay_time = ktime_get_seconds() + - prandom_u32_max(attr->u.delay.la_interval); + get_random_u32_below(attr->u.delay.la_interval); } else { - rule->dl_delay_at = prandom_u32_max(attr->u.delay.la_rate); + rule->dl_delay_at = get_random_u32_below(attr->u.delay.la_rate); } rule->dl_msg_send = -1; @@ -1007,10 +1007,10 @@ lnet_delay_rule_reset(void) memset(&rule->dl_stat, 0, sizeof(rule->dl_stat)); if (attr->u.delay.la_rate != 0) { - rule->dl_delay_at = prandom_u32_max(attr->u.delay.la_rate); + rule->dl_delay_at = get_random_u32_below(attr->u.delay.la_rate); } else { rule->dl_delay_time = ktime_get_seconds() + - prandom_u32_max(attr->u.delay.la_interval); + get_random_u32_below(attr->u.delay.la_interval); rule->dl_time_base = ktime_get_seconds() + attr->u.delay.la_interval; } diff --git a/lnet/lnet/router.c b/lnet/lnet/router.c index 026b337..12e507d 100644 --- a/lnet/lnet/router.c +++ b/lnet/lnet/router.c @@ -633,7 +633,7 @@ lnet_add_route_to_rnet(struct lnet_remotenet *rnet, struct lnet_route *route) * different nodes are using the same list of routers, they end up * preferring different routers. */ - offset = prandom_u32_max(len + 1); + offset = get_random_u32_below(len + 1); list_for_each(e, &rnet->lrn_routes) { if (offset == 0) break; diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 6e9d041..17e058c 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -911,10 +911,11 @@ AC_DEFUN([LC_SRC_IOPS_RENAME_WITH_FLAGS], [ LB2_LINUX_TEST_SRC([iops_rename_with_flags], [ #include ],[ + struct inode_operations *iops = NULL; struct inode *i1 = NULL, *i2 = NULL; struct dentry *d1 = NULL, *d2 = NULL; - int rc; - rc = ((struct inode_operations *)0)->rename(i1, d1, i2, d2, 0); + + iops->rename(i1, d1, i2, d2, 0); ]) ]) # LC_IOPS_RENAME_WITH_FLAGS AC_DEFUN([LC_IOPS_RENAME_WITH_FLAGS], [ @@ -1382,10 +1383,11 @@ AC_DEFUN([LC_SRC_SYMLINK_OPS_USE_NAMEIDATA], [ #include #include ],[ + struct inode_operations *iops = NULL; struct nameidata *nd = NULL; - ((struct inode_operations *)0)->follow_link(NULL, nd); - ((struct inode_operations *)0)->put_link(NULL, nd, NULL); + iops->follow_link(NULL, nd); + iops->put_link(NULL, nd, NULL); ]) ]) AC_DEFUN([LC_SYMLINK_OPS_USE_NAMEIDATA], [ @@ -2247,9 +2249,10 @@ AC_DEFUN([LC_SRC_INODEOPS_ENHANCED_GETATTR], [ LB2_LINUX_TEST_SRC([getattr_path], [ #include ],[ + struct inode_operations *iops = NULL; struct path path; - ((struct inode_operations *)1)->getattr(&path, NULL, 0, 0); + iops->getattr(&path, NULL, 0, 0); ]) ]) AC_DEFUN([LC_INODEOPS_ENHANCED_GETATTR], [ @@ -2985,7 +2988,9 @@ AC_DEFUN([LC_SRC_HAVE_GET_ACL_RCU_ARG], [ LB2_LINUX_TEST_SRC([get_acl_rcu_argument], [ #include ],[ - ((struct inode_operations *)1)->get_acl((struct inode *)NULL, 0, false); + struct inode_operations *iops = NULL; + + iops->get_acl((struct inode *)NULL, 0, false); ],[-Werror]) ]) AC_DEFUN([LC_HAVE_GET_ACL_RCU_ARG], [ @@ -3711,8 +3716,9 @@ AC_DEFUN([LC_SRC_HAVE_MNT_IDMAP_ARG], [ #include #include ],[ - ((struct inode_operations *)1)->getattr((struct mnt_idmap *)NULL, - NULL, NULL, 0, 0); + struct inode_operations *iops = NULL; + + iops->getattr((struct mnt_idmap *)NULL, NULL, NULL, 0, 0); ],[-Werror]) ]) AC_DEFUN([LC_HAVE_MNT_IDMAP_ARG], [ @@ -3728,6 +3734,58 @@ AC_DEFUN([LC_HAVE_MNT_IDMAP_ARG], [ ]) # LC_HAVE_MNT_IDMAP_ARG # +# LC_HAVE_GET_RANDOM_U32_BELOW +# +# Linux commit v6.1-13825-g3c202d14a9d7 +# prandom: remove prandom_u32_max() +# +AC_DEFUN([LC_SRC_HAVE_GET_RANDOM_U32_BELOW], [ + LB2_LINUX_TEST_SRC([get_random_u32_below], [ + #include + ],[ + u32 rand32 = get_random_u32_below(99); + (void)rand32; + ],[-Werror]) +]) +AC_DEFUN([LC_HAVE_GET_RANDOM_U32_BELOW], [ + AC_MSG_CHECKING([if get_random_u32_below()is available]) + LB2_LINUX_TEST_RESULT([get_random_u32_below], [ + AC_DEFINE(HAVE_GET_RANDOM_U32_BELOW, 1, + [get_random_u32_below() is available]) + ],[ + AC_DEFINE([get_random_u32_below(v)], [prandom_u32_max(v)], + [get_random_u32_below() is not available]) + ]) +]) # LC_HAVE_GET_RANDOM_U32_BELOW + +# +# LC_HAVE_ACL_WITH_DENTRY +# +# Linux commit v6.1-rc1-2-g138060ba92b3 +# fs: pass dentry to set acl method +# Linux commit v6.1-rc1-4-g7420332a6ff4 +# fs: add new get acl method +# +AC_DEFUN([LC_SRC_HAVE_ACL_WITH_DENTRY], [ + LB2_LINUX_TEST_SRC([acl_with_dentry], [ + #include + ],[ + struct inode_operations *iops = NULL; + struct dentry *dentry = NULL; + + iops->get_acl(NULL, dentry, 0); + (void)dentry; + ],[-Werror]) +]) +AC_DEFUN([LC_HAVE_ACL_WITH_DENTRY], [ + AC_MSG_CHECKING([if 'get_acl' and 'set_acl' use dentry argument]) + LB2_LINUX_TEST_RESULT([acl_with_dentry], [ + AC_DEFINE(HAVE_ACL_WITH_DENTRY, 1, + ['get_acl' and 'set_acl' use dentry argument]) + ]) +]) # LC_HAVE_ACL_WITH_DENTRY + +# # LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK # # Linux commit v6.2-rc3-9-g5970e15dbcfe @@ -3891,6 +3949,28 @@ AC_DEFUN([LC_HAVE_STRUCT_PAGEVEC], [ ]) # LC_HAVE_STRUCT_PAGEVEC # +# LC_IOP_GET_INODE_ACL +# +# linux kernel v6.1-rc1-3-gcac2f8b8d8 +# fs: rename current get acl method +# +AC_DEFUN([LC_SRC_IOP_GET_INODE_ACL], [ + LB2_LINUX_TEST_SRC([inode_ops_get_inode_acl], [ + #include + ],[ + struct inode_operations iop; + iop.get_inode_acl = NULL; + ]) +]) +AC_DEFUN([LC_IOP_GET_INODE_ACL], [ + AC_MSG_CHECKING([if inode_operations has .get_inode_acl member function]) + LB2_LINUX_TEST_RESULT([inode_ops_get_inode_acl], [ + AC_DEFINE(HAVE_IOP_GET_INODE_ACL, 1, + [inode_operations has .get_inode_acl member function]) + ]) +]) # LC_IOP_GET_INODE_ACL + +# # LC_PROG_LINUX # # Lustre linux kernel checks @@ -4124,6 +4204,7 @@ AC_DEFUN([LC_PROG_LINUX_SRC], [ LC_SRC_HAVE_GET_RANDOM_U32_AND_U64 LC_SRC_NFS_FILLDIR_USE_CTX_RETURN_BOOL LC_SRC_HAVE_FILEMAP_GET_FOLIOS_CONTIG + LC_SRC_IOP_GET_INODE_ACL # 6.6 LC_SRC_HAVE_FLUSH___WORKQUEUE @@ -4144,6 +4225,10 @@ AC_DEFUN([LC_PROG_LINUX_SRC], [ LC_SRC_HAVE_FOLIO_BATCH LC_SRC_HAVE_STRUCT_PAGEVEC + # 6.2 + LC_SRC_HAVE_GET_RANDOM_U32_BELOW + LC_SRC_HAVE_ACL_WITH_DENTRY + # kernel patch to extend integrity interface LC_SRC_BIO_INTEGRITY_PREP_FN ]) @@ -4391,6 +4476,7 @@ AC_DEFUN([LC_PROG_LINUX_RESULTS], [ LC_HAVE_GET_RANDOM_U32_AND_U64 LC_NFS_FILLDIR_USE_CTX_RETURN_BOOL LC_HAVE_FILEMAP_GET_FOLIOS_CONTIG + LC_IOP_GET_INODE_ACL # 6.6 LC_HAVE_FLUSH___WORKQUEUE @@ -4411,6 +4497,10 @@ AC_DEFUN([LC_PROG_LINUX_RESULTS], [ LC_HAVE_FOLIO_BATCH LC_HAVE_STRUCT_PAGEVEC + # 6.2 + LC_HAVE_GET_RANDOM_U32_BELOW + LC_HAVE_ACL_WITH_DENTRY + # kernel patch to extend integrity interface LC_BIO_INTEGRITY_PREP_FN ]) diff --git a/lustre/llite/acl.c b/lustre/llite/acl.c index 8304f97..bd7186c 100644 --- a/lustre/llite/acl.c +++ b/lustre/llite/acl.c @@ -38,33 +38,112 @@ #include "llite_internal.h" -struct posix_acl *ll_get_acl(struct inode *inode, int type -#ifdef HAVE_GET_ACL_RCU_ARG - , bool rcu -#endif /* HAVE_GET_ACL_RCU_ARG */ - ) +static struct posix_acl * +ll_get_acl_common(struct inode *inode, int type, bool rcu) { struct ll_inode_info *lli = ll_i2info(inode); struct posix_acl *acl = NULL; + char *value = NULL; + int len, xtype; + char buf[200]; + char *xname; ENTRY; -#ifdef HAVE_GET_ACL_RCU_ARG if (rcu) return ERR_PTR(-ECHILD); -#endif + if (type == ACL_TYPE_ACCESS && lli->lli_posix_acl) + goto lli_acl; + + switch (type) { + case ACL_TYPE_ACCESS: + xname = XATTR_NAME_ACL_ACCESS; + xtype = XATTR_ACL_ACCESS_T; + break; + case ACL_TYPE_DEFAULT: + xname = XATTR_NAME_ACL_DEFAULT; + xtype = XATTR_ACL_DEFAULT_T; + break; + default: + return ERR_PTR(-EINVAL); + } + + len = ll_xattr_list(inode, xname, xtype, NULL, 0, OBD_MD_FLXATTR); + if (len > 0) { + if (len > sizeof(buf)) + value = kmalloc(len, GFP_NOFS); + else + value = buf; + if (!value) + return ERR_PTR(-ENOMEM); + len = ll_xattr_list(inode, xname, xtype, value, len, + OBD_MD_FLXATTR); + } + if (len > 0) + acl = posix_acl_from_xattr(&init_user_ns, value, len); + else if (len == -ENODATA || len == -ENOSYS || len == -EOPNOTSUPP) + acl = NULL; + else + acl = ERR_PTR(len); + if (value && value != buf) + kfree(value); + + if (IS_ERR_OR_NULL(acl)) + goto out; + if (type == ACL_TYPE_DEFAULT) { + acl = posix_acl_dup(acl); + goto out; + } + if (type == ACL_TYPE_ACCESS) + lli_replace_acl(lli, acl); + +lli_acl: read_lock(&lli->lli_lock); /* VFS' acl_permission_check->check_acl will release the refcount */ acl = posix_acl_dup(lli->lli_posix_acl); read_unlock(&lli->lli_lock); +out: RETURN(acl); } +/* v6.1-rc1-3-gcac2f8b8d8b5 */ +struct posix_acl *ll_get_inode_acl(struct inode *inode, int type, bool rcu) +{ + return ll_get_acl_common(inode, type, rcu); +} + +struct posix_acl *ll_get_acl( +#ifdef HAVE_ACL_WITH_DENTRY + struct mnt_idmap *map, struct dentry *dentry, int type) +#elif defined HAVE_GET_ACL_RCU_ARG + struct inode *inode, int type, bool rcu) +#else + struct inode *inode, int type) +#endif /* HAVE_GET_ACL_RCU_ARG */ +{ +#ifdef HAVE_ACL_WITH_DENTRY + struct inode *inode = dentry->d_inode; +#endif +#ifndef HAVE_GET_ACL_RCU_ARG + bool rcu = false; +#endif + + return ll_get_acl_common(inode, type, rcu); +} + #ifdef HAVE_IOP_SET_ACL -int ll_set_acl(struct mnt_idmap *map, struct inode *inode, +int ll_set_acl(struct mnt_idmap *map, +#ifdef HAVE_ACL_WITH_DENTRY + struct dentry *dentry, +#else + struct inode *inode, +#endif struct posix_acl *acl, int type) { +#ifdef HAVE_ACL_WITH_DENTRY + struct inode *inode = dentry->d_inode; +#endif struct ll_sb_info *sbi = ll_i2sbi(inode); struct ptlrpc_request *req = NULL; const char *name = NULL; @@ -76,9 +155,6 @@ int ll_set_acl(struct mnt_idmap *map, struct inode *inode, switch (type) { case ACL_TYPE_ACCESS: name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) - rc = posix_acl_update_mode(map, inode, - &inode->i_mode, &acl); break; case ACL_TYPE_DEFAULT: diff --git a/lustre/llite/file.c b/lustre/llite/file.c index fd02819..382ccef 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -5810,6 +5810,9 @@ const struct inode_operations ll_file_inode_operations = { #endif .listxattr = ll_listxattr, .fiemap = ll_fiemap, +#ifdef HAVE_IOP_GET_INODE_ACL + .get_inode_acl = ll_get_inode_acl, +#endif .get_acl = ll_get_acl, #ifdef HAVE_IOP_SET_ACL .set_acl = ll_set_acl, diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 6902742..fd2e73d 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -395,12 +395,16 @@ static inline void lli_clear_acl(struct ll_inode_info *lli) } static inline void lli_replace_acl(struct ll_inode_info *lli, - struct lustre_md *md) + struct posix_acl *acl) { write_lock(&lli->lli_lock); if (lli->lli_posix_acl) posix_acl_release(lli->lli_posix_acl); - lli->lli_posix_acl = md->posix_acl; + lli->lli_posix_acl = acl; + if (!acl) { + forget_cached_acl(&lli->lli_vfs_inode, ACL_TYPE_ACCESS); + forget_cached_acl(&lli->lli_vfs_inode, ACL_TYPE_DEFAULT); + } write_unlock(&lli->lli_lock); } #else @@ -409,7 +413,7 @@ static inline void lli_clear_acl(struct ll_inode_info *lli) } static inline void lli_replace_acl(struct ll_inode_info *lli, - struct lustre_md *md) + struct posix_acl *acl) { } #endif @@ -1181,12 +1185,24 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat); int ll_getattr_dentry(struct dentry *de, struct kstat *stat, u32 request_mask, unsigned int flags, bool foreign); #ifdef CONFIG_LUSTRE_FS_POSIX_ACL -struct posix_acl *ll_get_acl(struct inode *inode, int type -#ifdef HAVE_GET_ACL_RCU_ARG - , bool rcu -#endif /* HAVE_GET_ACL_RCU_ARG */ - ); -int ll_set_acl(struct mnt_idmap *mnt_userns, struct inode *inode, +struct posix_acl *ll_get_acl( + #ifdef HAVE_ACL_WITH_DENTRY + struct mnt_idmap *, struct dentry *, int); + #elif defined HAVE_GET_ACL_RCU_ARG + struct inode *inode, int type, bool rcu); + #else + struct inode *inode, int type); + #endif /* HAVE_GET_ACL_RCU_ARG */ + +struct posix_acl * +ll_get_inode_acl(struct inode *inode, int type, bool rcu); + +int ll_set_acl(struct mnt_idmap *mnt_userns, + #ifdef HAVE_ACL_WITH_DENTRY + struct dentry *dentry, + #else + struct inode *inode, + #endif struct posix_acl *acl, int type); #else /* !CONFIG_LUSTRE_FS_POSIX_ACL */ #define ll_get_acl NULL diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 23441de..489c6df 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2665,7 +2665,7 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) } if (body->mbo_valid & OBD_MD_FLACL) - lli_replace_acl(lli, md); + lli_replace_acl(lli, md->posix_acl); api32 = test_bit(LL_SBI_32BIT_API, sbi->ll_flags); inode->i_ino = cl_fid_build_ino(&body->mbo_fid1, api32); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index f9b2537..a3de735 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -2183,6 +2183,9 @@ const struct inode_operations ll_dir_inode_operations = { .removexattr = ll_removexattr, #endif .listxattr = ll_listxattr, +#ifdef HAVE_IOP_GET_INODE_ACL + .get_inode_acl = ll_get_inode_acl, +#endif .get_acl = ll_get_acl, #ifdef HAVE_IOP_SET_ACL .set_acl = ll_set_acl, @@ -2199,6 +2202,9 @@ const struct inode_operations ll_special_inode_operations = { .removexattr = ll_removexattr, #endif .listxattr = ll_listxattr, +#ifdef HAVE_IOP_GET_INODE_ACL + .get_inode_acl = ll_get_inode_acl, +#endif .get_acl = ll_get_acl, #ifdef HAVE_IOP_SET_ACL .set_acl = ll_set_acl, diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index c036497..a713654 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -782,7 +782,7 @@ static int lod_ost_alloc_rr(const struct lu_env *env, struct lod_object *lo, spin_lock(&lqr->lqr_alloc); if (--lqr->lqr_start_count <= 0) { atomic_set(&lqr->lqr_start_idx, - prandom_u32_max(osts->op_count)); + get_random_u32_below(osts->op_count)); lqr->lqr_start_count = (LOV_CREATE_RESEED_MIN / max(osts->op_count, 1U) + LOV_CREATE_RESEED_MULT) * max(osts->op_count, 1U); @@ -976,7 +976,7 @@ int lod_mdt_alloc_rr(const struct lu_env *env, struct lod_object *lo, spin_lock(&lqr->lqr_alloc); if (--lqr->lqr_start_count <= 0) { atomic_set(&lqr->lqr_start_idx, - prandom_u32_max(pool->op_count)); + get_random_u32_below(pool->op_count)); lqr->lqr_start_count = (LOV_CREATE_RESEED_MIN / max(pool->op_count, 1U) + LOV_CREATE_RESEED_MULT) * max(pool->op_count, 1U); diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index b5bddd0..39df17e 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -649,7 +649,7 @@ static int mgc_requeue_thread(void *data) */ to = mgc_requeue_timeout_min == 0 ? 1 : mgc_requeue_timeout_min; to = cfs_time_seconds(mgc_requeue_timeout_min) + - prandom_u32_max(cfs_time_seconds(to)); + get_random_u32_below(cfs_time_seconds(to)); wait_event_idle_timeout(rq_waitq, rq_state & (RQ_STOP | RQ_PRECLEANUP), to); diff --git a/lustre/obdclass/lu_tgt_descs.c b/lustre/obdclass/lu_tgt_descs.c index 02476e0..f070169 100644 --- a/lustre/obdclass/lu_tgt_descs.c +++ b/lustre/obdclass/lu_tgt_descs.c @@ -66,10 +66,10 @@ u64 lu_prandom_u64_max(u64 ep_ro) * 32 bits (truncated to the upper limit, if needed) */ if (ep_ro > 0xffffffffULL) - rand = (u64)prandom_u32_max((u32)(ep_ro >> 32)) << 32; + rand = (u64)get_random_u32_below((u32)(ep_ro >> 32)) << 32; if (rand == (ep_ro & 0xffffffff00000000ULL)) - rand |= prandom_u32_max((u32)ep_ro); + rand |= get_random_u32_below((u32)ep_ro); else rand |= get_random_u32(); #else diff --git a/lustre/ptlrpc/nrs_delay.c b/lustre/ptlrpc/nrs_delay.c index a39a9cf..c09dd7e 100644 --- a/lustre/ptlrpc/nrs_delay.c +++ b/lustre/ptlrpc/nrs_delay.c @@ -255,11 +255,11 @@ static int nrs_delay_req_add(struct ptlrpc_nrs_policy *policy, if (delay_data->delay_pct == 0 || /* Not delaying anything */ (delay_data->delay_pct != 100 && - delay_data->delay_pct < prandom_u32_max(100))) + delay_data->delay_pct < get_random_u32_below(100))) return 1; nrq->nr_u.delay.req_start_time = ktime_get_real_seconds() + - prandom_u32_max(delay_data->max_delay - delay_data->min_delay + 1) + + get_random_u32_below(delay_data->max_delay - delay_data->min_delay + 1) + delay_data->min_delay; return binheap_insert(delay_data->delay_binheap, &nrq->nr_node); diff --git a/lustre/tests/acceptance-small.sh b/lustre/tests/acceptance-small.sh index 72825bc..c262d0f 100755 --- a/lustre/tests/acceptance-small.sh +++ b/lustre/tests/acceptance-small.sh @@ -10,4 +10,4 @@ for SUB in $DEFAULT_SUITES; do [ "$(eval echo \$$ENV)" = "no" ] && continue SUITES="$SUITES $SUB" done -sh auster -r -R -v -f ${NAME:-lustre} $SUITES +./auster -r -R -v -f ${NAME:-lustre} $SUITES diff --git a/lustre/tests/ost_oos.sh b/lustre/tests/ost_oos.sh index 73d1ec0..fecca77 100644 --- a/lustre/tests/ost_oos.sh +++ b/lustre/tests/ost_oos.sh @@ -6,7 +6,7 @@ export OSTSIZE=10000 MOUNT=${MOUNT:-/mnt/lustre} echo "mnt.." -sh llmount.sh +./llmount.sh echo "done" echo "" @@ -38,4 +38,4 @@ rm -f /tmp/oosfile echo "" echo "cln.." -sh llmountcleanup.sh +./llmountcleanup.sh diff --git a/lustre/tests/parallel-scale-nfs.sh b/lustre/tests/parallel-scale-nfs.sh index ab88f37..ffc2937 100755 --- a/lustre/tests/parallel-scale-nfs.sh +++ b/lustre/tests/parallel-scale-nfs.sh @@ -101,6 +101,48 @@ get_mpiuser_id $MPI_USER MPI_RUNAS=${MPI_RUNAS:-"runas -u $MPI_USER_UID -g $MPI_USER_GID"} $GSS_KRB5 && refresh_krb5_tgt $MPI_USER_UID $MPI_USER_GID $MPI_RUNAS +test_1() { + local src_file=/tmp/testfile.txt + local dst_file=$TESTDIR/$tfile + local native_file=$MOUNT/${dst_file#$NFS_CLIMNTPT} + local mode=644 + local got + local ver + + ver=$(version_code $(lustre_build_version_node $LUSTRE_CLIENT_NFSSRV)) + (( $ver >= $(version_code v2_15_6-17-g3e831582991c) )) || + skip "Need lustre client version of nfs server (MDS1 by default) >= 2.15.7 for NFS ACL handling fix" + + touch $src_file + chmod $mode $src_file + + cp -p $src_file $dst_file || error "copy $src_file->$dst_file failed" + + stat $dst_file + got="$(stat -c %a $dst_file)" + [[ "$got" == "$mode" ]] || error "permissions mismatch on '$dst_file'" + + local xattr=system.posix_acl_access + local lustre_xattrs=$(do_node $LUSTRE_CLIENT_NFSSRV \ + "getfattr -d -m - -e hex $native_file") + + echo $lustre_xattrs + # If this fails then the mountpoint is non-Lustre or does + # not exist because we failed to find a native mountpoint + [[ "$lustre_xattrs" =~ "trusted.link" ]] || + error "no trusted.link xattr in '$native_file'" + + [[ "$lustre_xattrs" =~ "$xattr" ]] && + error "found unexpected $xattr in '$native_file'" + + do_node $LUSTRE_CLIENT_NFSSRV "stat $native_file" + got=$(do_node $LUSTRE_CLIENT_NFSSRV "stat -c %a $native_file") + [[ "$got" == "$mode" ]] || error "permission mismatch on '$native_file'" + + rm -f $src_file $dst_file +} +run_test 1 "test copy with attributes" + test_compilebench() { if [[ "$TESTSUITE" =~ "parallel-scale-nfs" ]]; then skip "LU-12957 and LU-13068: compilebench for $TESTSUITE" diff --git a/lustre/tests/parallel-scale-nfsv4.sh b/lustre/tests/parallel-scale-nfsv4.sh index de9afd9..6ee8a10 100755 --- a/lustre/tests/parallel-scale-nfsv4.sh +++ b/lustre/tests/parallel-scale-nfsv4.sh @@ -7,4 +7,4 @@ init_test_env $@ export ALWAYS_EXCEPT="$PARALLEL_SCALE_NFSV4_EXCEPT " always_except LU-17154 racer_on_nfs -sh $LUSTRE/tests/parallel-scale-nfs.sh 4 +$LUSTRE/tests/parallel-scale-nfs.sh 4 diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index 0c9ba01..8789488 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -1806,13 +1806,14 @@ test_23a() { run_test 23a "test mapped regular ACLs" test_23b() { #LU-9929 - [ $num_clients -lt 2 ] && skip "Need 2 clients at least" - [ "$MGS_VERSION" -lt $(version_code 2.10.53) ] && + (( num_clients >= 2 )) || skip "Need 2 clients at least" + (( $MGS_VERSION >= $(version_code 2.10.53) )) || skip "Need MGS >= 2.10.53" + stack_trap "export SK_UNIQUE_NM=$SK_UNIQUE_NM" export SK_UNIQUE_NM=true nodemap_test_setup - trap nodemap_test_cleanup EXIT + stack_trap nodemap_test_cleanup EXIT local testdir=$DIR/$tdir local fs_id=$((IDBASE+10)) @@ -1836,26 +1837,38 @@ test_23b() { #LU-9929 # set/getfacl default acl on client 1 (unmapped gid=500) do_node ${clients_arr[0]} rm -rf $testdir do_node ${clients_arr[0]} mkdir -p $testdir + echo "$testdir ACLs after mkdir:" + do_node ${clients_arr[0]} getfacl $testdir # Here, USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1) do_node ${clients_arr[0]} setfacl -R -d -m group:$USER0:rwx $testdir || error "setfacl $testdir on ${clients_arr[0]} failed" + do_node ${clients_arr[0]} "sync && stat $testdir > /dev/null" + do_node ${clients_arr[0]} \ + $LCTL set_param -t4 -n "ldlm.namespaces.*.lru_size=clear" + echo "$testdir ACLs after setfacl, on ${clients_arr[0]}:" + do_node ${clients_arr[0]} getfacl $testdir unmapped_id=$(do_node ${clients_arr[0]} getfacl $testdir | - grep -E "default:group:.*:rwx" | awk -F: '{print $3}') - [ "$unmapped_id" = "$USER0" ] || + grep -E "default:group:.+:rwx" | awk -F: '{print $3}') + echo unmapped_id=$unmapped_id + (( unmapped_id == USER0 )) || error "gid=$ID0 was not unmapped correctly on ${clients_arr[0]}" # getfacl default acl on client 2 (mapped gid=60010) + do_node ${clients_arr[1]} \ + $LCTL set_param -t4 -n "ldlm.namespaces.*.lru_size=clear" + do_node ${clients_arr[1]} "sync && stat $testdir > /dev/null" + echo "$testdir ACLs after setfacl, on ${clients_arr[1]}:" + do_node ${clients_arr[1]} getfacl $testdir mapped_id=$(do_node ${clients_arr[1]} getfacl $testdir | - grep -E "default:group:.*:rwx" | awk -F: '{print $3}') + grep -E "default:group:.+:rwx" | awk -F: '{print $3}') + echo mapped_id=$mapped_id + [[ -n "$mapped_id" ]] || error "mapped_id empty" fs_user=$(do_node ${clients_arr[1]} getent passwd | grep :$fs_id:$fs_id: | cut -d: -f1) - [ -z "$fs_user" ] && fs_user=$fs_id - [ $mapped_id -eq $fs_id -o "$mapped_id" = "$fs_user" ] || - error "Should return gid=$fs_id or $fs_user on client2" - - rm -rf $testdir - nodemap_test_cleanup - export SK_UNIQUE_NM=false + [[ -n "$fs_user" ]] || fs_user=$fs_id + echo fs_user=$fs_user + (( mapped_id == fs_id || mapped_id == fs_user )) || + error "Should return user $fs_user id $fs_id on client2" } run_test 23b "test mapped default ACLs" diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 3150d9a..3279334 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -11554,7 +11554,7 @@ test_103a() { SAVE_UMASK=$(umask) umask 0022 - mkdir -p $DIR/$tdir + $LFS mkdir -c1 -i0 $DIR/$tdir cd $DIR/$tdir run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 31ebdc9..9a385a2 100755 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -468,7 +468,7 @@ export LINUX_VERSION_CODE=$(version_code ${LINUX_VERSION//\./ }) # Report the Lustre build version string (e.g. 1.8.7.3 or 2.4.1). # -# usage: lustre_build_version +# usage: lustre_build_version_node # # All Lustre versions support "lctl get_param" to report the version of the # code running in the kernel (what our tests are interested in), but it @@ -495,21 +495,19 @@ export LINUX_VERSION_CODE=$(version_code ${LINUX_VERSION//\./ }) # lctl --version: lctl 2.6.50 # # output: prints version string to stdout in (up to 4) dotted-decimal values -lustre_build_version() { - local facet=${1:-client} - local facet_version=${facet}_VERSION - - # if the global variable is already set, then use that - [ -n "${!facet_version}" ] && echo ${!facet_version} && return +lustre_build_version_node() { + local node=$1 + local ver + local lver # this is the currently-running version of the kernel modules - local ver=$(do_facet $facet "$LCTL get_param -n version 2>/dev/null") + ver=$(do_node $node "$LCTL get_param -n version 2>/dev/null") # we mostly test 2.10+ systems, only try others if the above fails if [ -z "$ver" ]; then - ver=$(do_facet $facet "$LCTL lustre_build_version 2>/dev/null") + ver=$(do_node $node "$LCTL lustre_build_version 2>/dev/null") fi if [ -z "$ver" ]; then - ver=$(do_facet $facet "$LCTL --version 2>/dev/null" | + ver=$(do_node $node "$LCTL --version 2>/dev/null" | cut -d' ' -f2) fi local lver=$(egrep -i "lustre: |version: " <<<"$ver" | head -n 1) @@ -518,6 +516,19 @@ lustre_build_version() { lver=$(sed -e 's/[^:]*: //' -e 's/^v//' -e 's/[ -].*//' <<<$ver | tr _ . | cut -d. -f1-4) + echo $lver +} + +lustre_build_version() { + local facet=${1:-client} + local node=$(facet_active_host $facet) + local facet_version=${facet}_VERSION + local lver + + # if the global variable is already set, then use that + [ -n "${!facet_version}" ] && echo ${!facet_version} && return + + lver=$(lustre_build_version_node $node) # save in global variable for the future export $facet_version=$lver -- 1.8.3.1