- 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.
 nrubsig.kpaste.net RSS