summaryrefslogtreecommitdiff
path: root/nfs/ops.c
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 /nfs/ops.c
parent09860e8f80d095e94bc15d9b67e708cc77fab16f (diff)
nfs: add support for NFSv3 in 'fetch_directory'
Diffstat (limited to 'nfs/ops.c')
-rw-r--r--nfs/ops.c56
1 files changed, 47 insertions, 9 deletions
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++;
}