summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Kelly <mike@weatherwax.co.uk>2025-07-14 18:06:12 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-07-14 18:06:12 +0200
commit385d2c7da8df05f4a0d6a7f97e9b07f19482406b (patch)
treeeb7f642531988095b57c1d81a85c56325fc382f4
parent4951192cd25c2e1a7058046289d234eedcd39d70 (diff)
nfs: lookup root node handle specified by the mount server
to retrieve the true identity.
-rw-r--r--nfs/mount.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/nfs/mount.c b/nfs/mount.c
index 75a6f9b3..44a29180 100644
--- a/nfs/mount.c
+++ b/nfs/mount.c
@@ -207,10 +207,9 @@ mount_root (char *name, char *host)
goto error_with_rpcbuf;
}
- /* Create the node for root */
- xdr_decode_fhandle (p, &np);
+ mount_fhandle.size = NFS2_FHSIZE;
+ memcpy(&mount_fhandle.data, p, mount_fhandle.size);
free (rpcbuf);
- pthread_mutex_unlock (&np->lock);
if (nfs_port_override)
port = nfs_port;
@@ -262,7 +261,47 @@ mount_root (char *name, char *host)
mounted_hostname = host;
mounted_nfs_port = port;
- return np;
+ /* The handle returned by the mount server is always NFS2_FHSIZE.
+ The handle on NFSv3 can be larger. An NFS server lookup for
+ the root node succeeds with the handle from the mount server
+ but a longer handle is returned as the true identity. This is
+ the one that must be maintained by the root node.
+ So refetch it here... */
+ p = initialize_rpc(nfs_program,
+ nfs_version,
+ NFSPROC_LOOKUP (protocol_version),
+ 0, &rpcbuf,
+ 0, 0, -1);
+ if (! p)
+ {
+ error (0, errno, "rpc");
+ goto error_with_rpcbuf;
+ }
+
+ p = xdr_encode_fhandle(p, &mount_fhandle);
+ p = xdr_encode_string (p, ".");
+
+ err = conduct_rpc (&rpcbuf, &p);
+
+ if (!err) {
+ err = nfs_error_trans (ntohl (*p));
+ p++;
+ }
+ else
+ {
+ error (0, errno, "rpc");
+ goto error_with_rpcbuf;
+ }
+
+ if (!err)
+ {
+ /* Create the node for root */
+ xdr_decode_fhandle (p, &np);
+ pthread_mutex_unlock (&np->lock);
+ free(rpcbuf);
+
+ return np;
+ }
error_with_rpcbuf:
free (rpcbuf);