diff options
author | Michael Kelly <mike@weatherwax.co.uk> | 2025-07-12 11:36:35 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-07-12 11:36:35 +0200 |
commit | 6e02392b5d5db9f16f4e1316d8097573361bf637 (patch) | |
tree | 6d7a150b51f7872d21bd56ff7ca2e1d72306e61d | |
parent | 09860e8f80d095e94bc15d9b67e708cc77fab16f (diff) |
nfs: add support for NFSv3 in 'fetch_directory'
-rw-r--r-- | nfs/nfs-spec.h | 4 | ||||
-rw-r--r-- | nfs/ops.c | 56 |
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 @@ -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++; } |