summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Kelly <mike@weatherwax.co.uk>2025-07-13 12:49:57 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-07-13 12:49:57 +0200
commita274f474d8464b902ed342aea83440abd8ed5b38 (patch)
tree6b1f8418a368f6cb008a3c5ff197c90c6ef60509
parent84caaeb826ea6c5e8bfb30ea74c67401c220f324 (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.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/nfs/ops.c b/nfs/ops.c
index a9c4da49..8dd19e55 100644
--- a/nfs/ops.c
+++ b/nfs/ops.c
@@ -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;