summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Kelly <mike@weatherwax.co.uk>2025-07-12 11:36:35 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-07-12 11:36:35 +0200
commit6e02392b5d5db9f16f4e1316d8097573361bf637 (patch)
tree6d7a150b51f7872d21bd56ff7ca2e1d72306e61d
parent09860e8f80d095e94bc15d9b67e708cc77fab16f (diff)
nfs: add support for NFSv3 in 'fetch_directory'
-rw-r--r--nfs/nfs-spec.h4
-rw-r--r--nfs/ops.c56
2 files changed, 50 insertions, 10 deletions
diff --git a/nfs/nfs-spec.h b/nfs/nfs-spec.h
index bed03874..4f7f5354 100644
--- a/nfs/nfs-spec.h
+++ b/nfs/nfs-spec.h
@@ -7,7 +7,9 @@
#define NFS_MAXNAMLEN 255
#define NFS2_FHSIZE 32
#define NFS3_FHSIZE 64
-#define NFS_COOKIESIZE 4
+#define NFS2_COOKIESIZE 4
+#define NFS3_COOKIESIZE 8
+#define NFS_MAXCOOKIESIZE NFS3_COOKIESIZE
#define NFS_FIFO_DEV -1
#define NFS3_COOKIEVERFSIZE 8
#define NFS3_CREATEVERFSIZE 8
diff --git a/nfs/ops.c b/nfs/ops.c
index 6e5bfeb1..78e51cf4 100644
--- a/nfs/ops.c
+++ b/nfs/ops.c
@@ -1702,7 +1702,6 @@ fetch_directory (struct iouser *cred, struct node *dir,
void **bufp, size_t *bufsizep, int *totalentries)
{
void *buf;
- int cookie;
int *p;
void *rpcbuf;
struct dirent *entry;
@@ -1712,6 +1711,12 @@ fetch_directory (struct iouser *cred, struct node *dir,
error_t err;
int isnext;
+ /* Treat all cookies as opaque data of the appropriate size */
+ char cookieverf[NFS3_COOKIEVERFSIZE];
+ char cookie[NFS_MAXCOOKIESIZE];
+ const unsigned int cookie_size =
+ (protocol_version == 2 ? NFS2_COOKIESIZE : NFS3_COOKIESIZE);
+
bufmalloced = read_size;
buf = malloc (bufmalloced);
@@ -1719,7 +1724,9 @@ fetch_directory (struct iouser *cred, struct node *dir,
return ENOMEM;
bp = buf;
- cookie = 0;
+ memset (cookie, 0, cookie_size);
+ if (protocol_version == 3)
+ memset (cookieverf, 0, sizeof (cookieverf));
eof = 0;
*totalentries = 0;
@@ -1735,20 +1742,44 @@ fetch_directory (struct iouser *cred, struct node *dir,
}
p = xdr_encode_fhandle (p, &dir->nn->handle);
- *(p++) = cookie;
+ memcpy (p, cookie, cookie_size);
+ p += INTSIZE (cookie_size);
+
+ if (protocol_version == 3)
+ {
+ memcpy (p, cookieverf, sizeof (cookieverf));
+ p += INTSIZE (sizeof (cookieverf));
+ }
+
*(p++) = ntohl (read_size);
err = conduct_rpc (&rpcbuf, &p);
- if (!err)
+ if (err)
{
- err = nfs_error_trans (ntohl (*p));
- p++;
+ free (rpcbuf);
+ free (buf);
+ return err;
}
+
+ err = nfs_error_trans (ntohl (*p));
+ p++;
+
+ if (protocol_version == 3)
+ /* 'post_op_attr' is present for any value of 'err' */
+ p = process_returned_stat (dir, p, 1);
+
if (err)
{
+ free (rpcbuf);
free (buf);
return err;
}
+ if (protocol_version == 3)
+ {
+ memcpy (cookieverf, p, sizeof (cookieverf));
+ p += INTSIZE (sizeof (cookieverf));
+ }
+
isnext = ntohl (*p);
p++;
@@ -1759,8 +1790,14 @@ fetch_directory (struct iouser *cred, struct node *dir,
int namlen;
int reclen;
- fileno = ntohl (*p);
- p++;
+ if (protocol_version == 2)
+ {
+ fileno = ntohl (*p);
+ p++;
+ }
+ else
+ p = xdr_decode_64bit(p, &fileno);
+
namlen = ntohl (*p);
p++;
@@ -1795,7 +1832,8 @@ fetch_directory (struct iouser *cred, struct node *dir,
++*totalentries;
- cookie = *(p++);
+ memcpy (cookie, p, cookie_size);
+ p += INTSIZE (cookie_size);
isnext = ntohl (*p);
p++;
}