diff options
author | Michael Kelly <mike@weatherwax.co.uk> | 2025-07-13 12:49:57 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-07-13 12:49:57 +0200 |
commit | a274f474d8464b902ed342aea83440abd8ed5b38 (patch) | |
tree | 6b1f8418a368f6cb008a3c5ff197c90c6ef60509 | |
parent | 84caaeb826ea6c5e8bfb30ea74c67401c220f324 (diff) |
nfs: Fix netfs_attempt_create_file for nfsv3
The v3 netfs_attempt_create_file() uses the 'exclusive' creation protocol
which cannot specify the file permission bits or uid/gid. These need to be
applied post-creation using SETATTR3. There was a missing call to do the chmod
part which I've added. Previously the call to chown that was present did not
consider the return value. I have done so.
-rw-r--r-- | nfs/ops.c | 43 |
1 files changed, 21 insertions, 22 deletions
@@ -1286,37 +1286,36 @@ netfs_attempt_create_file (struct iouser *cred, struct node *np, p = xdr_encode_create_state (p, mode, owner); err = conduct_rpc (&rpcbuf, &p); - - pthread_mutex_unlock (&np->lock); + *newnp = 0; if (!err) { - err = nfs_error_trans (ntohl (*p)); - p++; - if (!err) + if (protocol_version == 2) { - p = xdr_decode_fhandle (p, newnp); - p = process_returned_stat (*newnp, p, 1); + err = nfs_error_trans (ntohl (*p)); + p++; + if (!err) + { + p = xdr_decode_fhandle (p, newnp); + p = process_returned_stat (*newnp, p, 1); + } } - if (err) - *newnp = 0; - if (protocol_version == 3) + else + err = process_create_reply (cred, np, name, newnp, p); + + pthread_mutex_unlock (&np->lock); + + if (*newnp && !netfs_validate_stat (*newnp, (struct iouser *) -1)) { - if (*newnp) - pthread_mutex_unlock (&(*newnp)->lock); - pthread_mutex_lock (&np->lock); - p = process_wcc_stat (np, p, 1); - pthread_mutex_unlock (&np->lock); - if (*newnp) - pthread_mutex_lock (&(*newnp)->lock); - } + if ((*newnp)->nn_stat.st_uid != owner) + err = netfs_attempt_chown ((struct iouser *) -1, *newnp, owner, (*newnp)->nn_stat.st_gid); - if (*newnp && !netfs_validate_stat (*newnp, (struct iouser *) -1) - && (*newnp)->nn_stat.st_uid != owner) - netfs_attempt_chown ((struct iouser *) -1, *newnp, owner, (*newnp)->nn_stat.st_gid); + if (!err && (*newnp)->nn_stat.st_mode != mode) + err = netfs_attempt_chmod (cred, *newnp, mode); + } } else - *newnp = 0; + pthread_mutex_unlock (&np->lock); free (rpcbuf); return err; |