]> git.hungrycats.org Git - linux/commitdiff
[PATCH] kNFSd: NFSv4: tweak nfsd_readdir() for NFSv4
authorKendrick M. Smith <kmsmith@umich.edu>
Fri, 23 Aug 2002 04:38:37 +0000 (21:38 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 23 Aug 2002 04:38:37 +0000 (21:38 -0700)
This patch makes three small changes to nfsd_readdir().

First, the 'filldir' routine for NFSv4 may return an arbitrary error,
which should become the return value for nfsd_readdir().  I implemented
this by adding an 'nfserr' field to the 'struct readdir_cd'.

Second, in NFSv4 the caller of nfsd_readdir() will specify an attribute
bitmap, which must be communicated to the 'filldir' routine.  I implemented
this by adding a @bitmap parameter to nfsd_readdir() and a corresponding
field in the 'struct readdir_cd'.  (The bitmap is not interpreted in any
way by nfsd_readdir().)

Finally, NFSv4 defines a new error nfserr_readdir_nospc, which indicates
that there was not enough buffer space to encode a single entry.

fs/nfsd/nfs3proc.c
fs/nfsd/nfsproc.c
fs/nfsd/vfs.c
include/linux/nfsd/nfsd.h

index 65f4d7109f981f86f5058c028fc20823edc7611b..eb7d94e0927b705bfe6bdd3640e5779787655475 100644 (file)
@@ -460,7 +460,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
        fh_copy(&resp->fh, &argp->fh);
        nfserr = nfsd_readdir(rqstp, &resp->fh, (loff_t) argp->cookie, 
                                        nfs3svc_encode_entry,
-                                       buffer, &count, argp->verf);
+                                       buffer, &count, argp->verf, NULL);
        memcpy(resp->verf, argp->verf, 8);
        resp->count = count;
 
@@ -495,7 +495,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
        fh_copy(&resp->fh, &argp->fh);
        nfserr = nfsd_readdir(rqstp, &resp->fh, (loff_t) argp->cookie, 
                                        nfs3svc_encode_entry_plus,
-                                       buffer, &count, argp->verf);
+                                       buffer, &count, argp->verf, NULL);
        memcpy(resp->verf, argp->verf, 8);
        resp->count = count;
 
index 139a76099c7de2c6da66a3d907262abcc2515ad0..5a56ed7dbb1f6fc136b5d4b73d8d38aa11646c7c 100644 (file)
@@ -492,7 +492,7 @@ nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp,
        /* Read directory and encode entries on the fly */
        nfserr = nfsd_readdir(rqstp, &argp->fh, (loff_t) argp->cookie, 
                              nfssvc_encode_entry,
-                             buffer, &count, NULL);
+                             buffer, &count, NULL, NULL);
        resp->count = count;
 
        fh_put(&argp->fh);
index 118e3532affb3ce3f907c90d91465ddd2e822606..ee34768f474cb28bfa2e96c01d69627819d6cfa0 100644 (file)
@@ -1381,7 +1381,7 @@ out_nfserr:
  */
 int
 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, 
-             encode_dent_fn func, u32 *buffer, int *countp, u32 *verf)
+             encode_dent_fn func, u32 *buffer, int *countp, u32 *verf, u32 *bmval)
 {
        u32             *p;
        int             oldlen, eof, err;
@@ -1402,6 +1402,10 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
        cd.buffer = buffer;
        cd.buflen = *countp; /* count of words */
        cd.dirfh  = fhp;
+       if (bmval) {
+               cd.bmval[0] = bmval[0];
+               cd.bmval[1] = bmval[1];
+       }
 
        /*
         * Read the directory entries. This silly loop is necessary because
@@ -1417,8 +1421,15 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
                if (err < 0)
                        goto out_nfserr;
 
+               err = cd.nfserr;
+               if (err)
+                       goto out_close;
        } while (oldlen != cd.buflen && !cd.eob);
 
+       err = nfserr_readdir_nospc;
+       if (rqstp->rq_vers == 4 && cd.eob && cd.buffer == buffer)
+               goto out_close;
+
        /* If we didn't fill the buffer completely, we're at EOF */
        eof = !cd.eob;
 
index badb54a83eb322b103803e592e7e4e42c26b7ea6..7849dece16ac5775ddd66033d238ef3331745392 100644 (file)
@@ -55,6 +55,8 @@ struct readdir_cd {
        char                    plus;           /* readdirplus */
        char                    eob;            /* end of buffer */
        char                    dotonly;
+       int                     nfserr;         /* v4 only */
+       u32                     bmval[2];       /* v4 only */
 };
 typedef int            (*encode_dent_fn)(struct readdir_cd *, const char *,
                                                int, loff_t, ino_t, unsigned int);
@@ -119,7 +121,8 @@ int         nfsd_truncate(struct svc_rqst *, struct svc_fh *,
                                unsigned long size);
 int            nfsd_readdir(struct svc_rqst *, struct svc_fh *,
                                loff_t, encode_dent_fn,
-                               u32 *buffer, int *countp, u32 *verf);
+                               u32 *buffer, int *countp, u32 *verf,
+                               u32 *bmval);
 int            nfsd_statfs(struct svc_rqst *, struct svc_fh *,
                                struct statfs *);