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