- diff --git a/cygwin/devel/msnfs41client.bash b/cygwin/devel/msnfs41client.bash
- index 4a391dd..8c7bfa4 100755
- --- a/cygwin/devel/msnfs41client.bash
- +++ b/cygwin/devel/msnfs41client.bash
- @@ -467,7 +467,7 @@ function nfsclient_rundeamon
- "${nfsd_args[@]}"
- )
- "${nfsd_args[@]}"
- - elif false ; then
- + elif true ; then
- export _NT_ALT_SYMBOL_PATH="$(cygpath -w "$PWD");srv*https://msdl.microsoft.com/download/symbols"
- #
- # Useful cdb cmds:
- @@ -601,7 +601,7 @@ function nfsclient_system_rundeamon
- )
- "${nfsd_args[@]}"
- - elif false ; then
- + elif true ; then
- export _NT_ALT_SYMBOL_PATH="$(cygpath -w "$PWD");srv*https://msdl.microsoft.com/download/symbols"
- # - heap tests (eats lots of memory):
- # '-c' '!gflag +full;g' for heap tests
- diff --git a/daemon/acl.c b/daemon/acl.c
- index 370f2d3..4e3c0f9 100644
- --- a/daemon/acl.c
- +++ b/daemon/acl.c
- @@ -331,8 +331,53 @@ static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
- DPRINTF(ACLLVL1, ("--> handle_getacl(state->path.path='%s')\n",
- state->path.path));
- - if (args->query & DACL_SECURITY_INFORMATION) {
- -use_nfs41_getattr:
- + (void)memset(&info, 0, sizeof(nfs41_file_info));
- + info.owner = owner;
- + info.owner_group = group;
- + info.acl = &acl;
- +
- + status = nfs41_cached_getattr(state->session, &state->file, &info);
- + if (status) {
- + eprintf("handle_getacl: nfs41_cached_getattr() failed with %d\n",
- + status);
- + goto out;
- + }
- +
- + EASSERT(info.attrmask.count > 1);
- + bool do_full_lookup = false;
- +
- + /*
- + * In rare cases owner/owner_group are not in the cache
- + * (usually for new files). In this case do a full
- + * roundtrip to the NFS server to get the data...
- + */
- + if ((bitmap_isset(&info.attrmask, 1,
- + FATTR4_WORD1_OWNER) == false) ||
- + (bitmap_isset(&info.attrmask, 1,
- + FATTR4_WORD1_OWNER_GROUP) == false)) {
- + DPRINTF(ACLLVL2,
- + ("handle_getattr: "
- + "owner/owner_group not in cache, doing full lookup...\n"));
- + do_full_lookup = true;
- + }
- +
- + if ((args->query & DACL_SECURITY_INFORMATION) &&
- + (bitmap_isset(&info.attrmask, 0, FATTR4_WORD0_ACL) == false)) {
- + DPRINTF(0,
- + ("handle_getattr: "
- + "ACL information not in cache, doing full lookup...\n"));
- + do_full_lookup = true;
- + }
- +
- +#if 1
- + /* debug */
- + if ((args->query & DACL_SECURITY_INFORMATION) &&
- + (do_full_lookup == false)) {
- + DPRINTF(0, ("handle_getacl: cached ACL used\n"));
- + }
- +#endif
- +
- + if (do_full_lookup) {
- bitmap4 attr_request = { 0 };
- (void)memset(&info, 0, sizeof(nfs41_file_info));
- info.owner = owner;
- @@ -349,40 +394,11 @@ use_nfs41_getattr:
- goto out;
- }
- }
- - else {
- - (void)memset(&info, 0, sizeof(nfs41_file_info));
- - info.owner = owner;
- - info.owner_group = group;
- - status = nfs41_cached_getattr(state->session, &state->file, &info);
- - if (status) {
- - eprintf("handle_getacl: nfs41_cached_getattr() failed with %d\n",
- - status);
- - goto out;
- - }
- -
- - EASSERT(info.attrmask.count > 1);
- -
- - /*
- - * In rare cases owner/owner_group are not in the cache
- - * (usually for new files). In this case do a full
- - * roundtrip to the NFS server to get the data...
- - */
- - if ((bitmap_isset(&info.attrmask, 1,
- - FATTR4_WORD1_OWNER) == false) ||
- - (bitmap_isset(&info.attrmask, 1,
- - FATTR4_WORD1_OWNER_GROUP) == false)) {
- - DPRINTF(ACLLVL2, ("handle_getattr: owner/owner_group not in cache, doing full lookup...\n"));
- - goto use_nfs41_getattr;
- - }
- - }
- EASSERT(info.attrmask.count > 1);
- EASSERT(bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_OWNER) &&
- bitmap_isset(&info.attrmask, 1, FATTR4_WORD1_OWNER_GROUP));
- - if (args->query & DACL_SECURITY_INFORMATION) {
- - EASSERT(bitmap_isset(&info.attrmask, 0, FATTR4_WORD0_ACL));
- - }
- status = InitializeSecurityDescriptor(&sec_desc,
- SECURITY_DESCRIPTOR_REVISION);
- diff --git a/daemon/getattr.c b/daemon/getattr.c
- index 7c8b2d1..7501f39 100644
- --- a/daemon/getattr.c
- +++ b/daemon/getattr.c
- @@ -98,7 +98,7 @@ static int handle_getattr(void *daemon_context, nfs41_upcall *upcall)
- }
- if (info.type == NF4LNK) {
- - nfs41_file_info target_info;
- + nfs41_file_info target_info = { 0 };
- int target_status = nfs41_symlink_follow(upcall->root_ref,
- state->session, &state->file, &target_info);
- if (target_status == NO_ERROR) {
- diff --git a/daemon/name_cache.c b/daemon/name_cache.c
- index 950c188..24b69d6 100644
- --- a/daemon/name_cache.c
- +++ b/daemon/name_cache.c
- @@ -87,11 +87,12 @@ static __inline bool_t is_delegation(
- #define NC_ATTR_NUMLINKS (1 << 8)
- #define NC_ATTR_OWNER (1 << 9)
- #define NC_ATTR_OWNER_GROUP (1 << 10)
- -#define NC_ATTR_TIME_ACCESS (1 << 11)
- -#define NC_ATTR_TIME_CREATE (1 << 12)
- -#define NC_ATTR_TIME_MODIFY (1 << 13)
- -#define NC_ATTR_SYSTEM (1 << 14)
- -#define NC_ATTR_CLONE_BLKSIZE (1 << 15)
- +#define NC_ATTR_ACL (1 << 11)
- +#define NC_ATTR_TIME_ACCESS (1 << 12)
- +#define NC_ATTR_TIME_CREATE (1 << 13)
- +#define NC_ATTR_TIME_MODIFY (1 << 14)
- +#define NC_ATTR_SYSTEM (1 << 15)
- +#define NC_ATTR_CLONE_BLKSIZE (1 << 16)
- /* attribute cache */
- struct attr_cache_entry {
- @@ -123,6 +124,7 @@ struct attr_cache_entry {
- unsigned delegated : 1;
- char owner[NFS4_FATTR4_OWNER_LIMIT+1];
- char owner_group[NFS4_FATTR4_OWNER_LIMIT+1];
- + nfsacl41 acl;
- };
- #define ATTR_ENTRY_SIZE sizeof(struct attr_cache_entry)
- @@ -169,6 +171,7 @@ static int attr_cache_entry_create(
- entry->fsid_minor = 0ULL;
- entry->invalidated = FALSE;
- entry->delegated = FALSE;
- + (void)memset(&entry->acl, 0, sizeof(nfsacl41));
- *entry_out = entry;
- out:
- return status;
- @@ -180,6 +183,12 @@ static __inline void attr_cache_entry_free(
- {
- DPRINTF(NCLVL1, ("attr_cache_entry_free(%llu)\n", entry->fileid));
- RB_REMOVE(attr_tree, &cache->head, entry);
- +
- + if (entry->acl.aces) {
- + free(entry->acl.aces);
- + entry->acl.aces = NULL;
- + }
- +
- /* add it back to free_entries */
- list_add_tail(&cache->free_entries, &entry->free_entry);
- }
- @@ -344,6 +353,20 @@ static void attr_cache_update(
- entry->nc_attrs |= NC_ATTR_ARCHIVE;
- entry->archive = info->archive;
- }
- + if (info->attrmask.arr[0] & FATTR4_WORD0_ACL) {
- + if (entry->acl.aces) {
- + free(entry->acl.aces);
- + entry->acl.aces = NULL;
- + }
- +
- + entry->nc_attrs &= ~NC_ATTR_ACL;
- +
- + if (info->acl) {
- + entry->nc_attrs |= NC_ATTR_ACL;
- + (void)dup_nfsacl41aces(&entry->acl, info->acl);
- + EASSERT(entry->acl.aces != NULL);
- + }
- + }
- }
- if (info->attrmask.count > 1) {
- if (info->attrmask.arr[1] & FATTR4_WORD1_MODE) {
- @@ -463,6 +486,18 @@ static void copy_attrs(
- /* this should only happen for newly created files/dirs */
- dst->owner_group = NULL;
- }
- + if (src->nc_attrs & NC_ATTR_ACL) {
- + /*
- + * Only copy attribute if |dst| provides a pointer to an ACL struct
- + * This implicitly solves the issue who will free |dst->acl.aces|,
- + * because only who provides a |dst->acl| will get ACL/ACE data,
- + * but then also has to free the |dst->acl.aces| data.
- + */
- + if (dst->acl) {
- + dst->attrmask.arr[0] |= FATTR4_WORD0_ACL;
- + (void)dup_nfsacl41aces(dst->acl, &src->acl);
- + }
- + }
- if (src->nc_attrs & NC_ATTR_FSID) {
- dst->attrmask.arr[0] |= FATTR4_WORD0_FSID;
- dst->fsid.major = src->fsid_major;
- diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c
- index 862ce0e..485811b 100644
- --- a/daemon/nfs41_ops.c
- +++ b/daemon/nfs41_ops.c
- @@ -1478,28 +1478,31 @@ int nfs41_setattr(
- nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
- - if (info->attrmask.count >= 2) {
- - /*
- - * If we set owner and/or owner_group make sure we ask
- - * the server to send the values back for two reasons:
- - * 1, Handle cases like "all_squash" (e.g. nfsd turns
- - * owner/owner_group always into "nobody"/"nogroup")
- - * 2. Make sure we update the name cache with the new
- - * owner/owner_group
- - *
- - * Note that this can be a bit tricky as we might pass
- - * a "name@domain" string to the server, but get a numeric
- - * uid/gid as strings back, which means the name cache
- - * might have both representations.
- - */
- - if (info->attrmask.arr[1] & FATTR4_WORD1_OWNER) {
- - attr_request.count = 2;
- - attr_request.arr[1] |= FATTR4_WORD1_OWNER;
- - }
- - if (info->attrmask.arr[1] & FATTR4_WORD1_OWNER_GROUP) {
- - attr_request.count = 2;
- - attr_request.arr[1] |= FATTR4_WORD1_OWNER_GROUP;
- - }
- + /*
- + * If we set owner, owner_group and/or ACLs make sure we ask
- + * the server to send the values back for two reasons:
- + * 1, Handle cases like "all_squash" (e.g. nfsd turns
- + * owner/owner_group always into "nobody"/"nogroup")
- + * 2. Make sure we update the name cache with the new
- + * owner/owner_group/ACLs
- + *
- + * Note that this can be a bit tricky as we might pass
- + * a "name@domain" string to the server, but get a numeric
- + * uid/gid as strings back, which means the name cache
- + * might have both representations.
- + */
- + if (bitmap_isset(&info->attrmask, 1, FATTR4_WORD1_OWNER)) {
- + attr_request.count = 2;
- + attr_request.arr[1] |= FATTR4_WORD1_OWNER;
- + }
- + if (bitmap_isset(&info->attrmask, 1, FATTR4_WORD1_OWNER_GROUP)) {
- + attr_request.count = 2;
- + attr_request.arr[1] |= FATTR4_WORD1_OWNER_GROUP;
- + }
- + if (bitmap_isset(&info->attrmask, 0, FATTR4_WORD0_ACL)) {
- + if (attr_request.count == 0)
- + attr_request.count = 1;
- + attr_request.arr[0] |= FATTR4_WORD0_ACL;
- }
- compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
- diff --git a/daemon/readdir.c b/daemon/readdir.c
- index f3564bf..5282cd3 100644
- --- a/daemon/readdir.c
- +++ b/daemon/readdir.c
- @@ -515,7 +515,7 @@ static int lookup_symlink(
- {
- nfs41_abs_path path;
- nfs41_path_fh file;
- - nfs41_file_info info;
- + nfs41_file_info info = { 0 };
- int status;
- status = format_abs_path(parent->path, name, &path);
- diff --git a/daemon/util.c b/daemon/util.c
- index 3a56b7c..4d396c1 100644
- --- a/daemon/util.c
- +++ b/daemon/util.c
- @@ -638,3 +638,22 @@ bool getwinntversionnnumbers(
- return false;
- #endif /* _WIN64 */
- }
- +
- +bool dup_nfsacl41aces(
- + nfsacl41 *restrict out_acl,
- + const nfsacl41 *restrict in_acl)
- +{
- + size_t acemem_size = in_acl->count * sizeof(nfsace4);
- +
- + out_acl->aces = malloc(acemem_size);
- + if (out_acl->aces == NULL) {
- + free(out_acl);
- + return false;
- + }
- +
- + out_acl->count = in_acl->count;
- + out_acl->flag = in_acl->flag;
- + (void)memcpy(out_acl->aces, in_acl->aces, acemem_size);
- +
- + return true;
- +}
- diff --git a/daemon/util.h b/daemon/util.h
- index 011d411..d4f5c2c 100644
- --- a/daemon/util.h
- +++ b/daemon/util.h
- @@ -364,4 +364,6 @@ bool_t waitcriticalsection(LPCRITICAL_SECTION cs);
- bool getwinntversionnnumbers(DWORD *MajorVersionPtr, DWORD *MinorVersionPtr, DWORD *BuildNumberPtr);
- +bool dup_nfsacl41aces(nfsacl41 *restrict out_acl, const nfsacl41 *restrict in_acl);
- +
- #endif /* !__NFS41_DAEMON_UTIL_H__ */
- diff --git a/tests/sparsefiles/multisparsefiletest.ksh b/tests/sparsefiles/multisparsefiletest.ksh
- index b62f577..d6cdf8a 100644
- --- a/tests/sparsefiles/multisparsefiletest.ksh
- +++ b/tests/sparsefiles/multisparsefiletest.ksh
- @@ -329,7 +329,7 @@ builtin wc
- # - verify file sizes (original vs copy/clone)
- # - tests for sparse files >= 2GB, 4GB, 16GB
- #
- -typeset test_cloning=false
- +typeset test_cloning=true
- multisparsefiletest1
ACL support in name cache
Posted by Anonymous on Mon 23rd Jun 2025 20:24
raw | new post
view followups (newest first): ACL support in name cache by Anonymous
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.