Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Wed, 14 Aug 2002 16:51:03 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Wed, 14 Aug 2002 16:50:26 -0400 Received: from berzerk.gpcc.itd.umich.edu ([141.211.2.162]:56535 "EHLO berzerk.gpcc.itd.umich.edu") by vger.kernel.org with ESMTP id ; Wed, 14 Aug 2002 16:48:50 -0400 Date: Wed, 14 Aug 2002 16:52:38 -0400 (EDT) From: "Kendrick M. Smith" X-X-Sender: kmsmith@vanguard.gpcc.itd.umich.edu To: linux-kernel@vger.kernel.org, Subject: REPOST patch 33/38: SERVER: tweak nfsd_readdir() for NFSv4 Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4016 Lines: 112 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. --- old/fs/nfsd/nfs3proc.c Sun Aug 11 23:09:50 2002 +++ new/fs/nfsd/nfs3proc.c Sun Aug 11 23:10:29 2002 @@ -460,7 +460,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqst 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 * 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; --- old/fs/nfsd/nfsproc.c Thu Aug 1 16:16:18 2002 +++ new/fs/nfsd/nfsproc.c Sun Aug 11 23:10:29 2002 @@ -492,7 +492,7 @@ nfsd_proc_readdir(struct svc_rqst *rqstp /* 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); --- old/fs/nfsd/vfs.c Sun Aug 11 23:09:50 2002 +++ new/fs/nfsd/vfs.c Sun Aug 11 23:10:29 2002 @@ -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, str 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, str 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; --- old/include/linux/nfsd/nfsd.h Sun Aug 11 23:09:50 2002 +++ new/include/linux/nfsd/nfsd.h Sun Aug 11 23:10:29 2002 @@ -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 *, st 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 *); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/