From db667a40a524ed6b14468d2335a8a99c01b65cba Mon Sep 17 00:00:00 2001 From: Paul Saab Date: Mon, 1 May 2000 15:03:52 +0000 Subject: [PATCH] Add readdir support to the NFS filesystem in libstand. --- lib/libstand/nfs.c | 81 +++++++++++++++++++++++++++++++++++++++++++- lib/libstand/nfsv2.h | 2 ++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/lib/libstand/nfs.c b/lib/libstand/nfs.c index 5669973c9bda..a02ca580c135 100644 --- a/lib/libstand/nfs.c +++ b/lib/libstand/nfs.c @@ -91,6 +91,23 @@ struct nfs_readlnk_repl { }; #endif +struct nfs_readdir_args { + u_char fh[NFS_FHSIZE]; + n_long cookie; + n_long count; +}; + +struct nfs_readdir_data { + n_long fileid; + n_long len; + char name[0]; +}; + +struct nfs_readdir_off { + n_long cookie; + n_long follows; +}; + struct nfs_iodesc { struct iodesc *iodesc; off_t off; @@ -108,6 +125,7 @@ static int nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); static int nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t nfs_seek(struct open_file *f, off_t offset, int where); static int nfs_stat(struct open_file *f, struct stat *sb); +static int nfs_readdir(struct open_file *f, struct dirent *d); static struct nfs_iodesc nfs_root_node; @@ -119,7 +137,7 @@ struct fs_ops nfs_fsops = { nfs_write, nfs_seek, nfs_stat, - null_readdir + nfs_readdir }; /* @@ -665,3 +683,64 @@ nfs_stat(f, sb) return (0); } + +static int +nfs_readdir(struct open_file *f, struct dirent *d) +{ + register struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; + struct nfs_readdir_args *args; + struct nfs_readdir_data *rd; + struct nfs_readdir_off *roff = NULL; + static char *buf; + static n_long cookie = 0; + size_t cc; + n_long eof; + + struct { + n_long h[RPC_HEADER_WORDS]; + struct nfs_readdir_args d; + } sdata; + static struct { + n_long h[RPC_HEADER_WORDS]; + u_char d[NFS_READDIRSIZE]; + } rdata; + + if (cookie == 0) { + refill: + args = &sdata.d; + bzero(args, sizeof(*args)); + + bcopy(fp->fh, args->fh, NFS_FHSIZE); + args->cookie = htonl(cookie); + args->count = htonl(NFS_READDIRSIZE); + + cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READDIR, + args, sizeof(*args), + rdata.d, sizeof(rdata.d)); + buf = rdata.d; + roff = (struct nfs_readdir_off *)buf; + if (ntohl(roff->cookie) != 0) + return 1; + } + roff = (struct nfs_readdir_off *)buf; + + if (ntohl(roff->follows) == 0) { + eof = ntohl((roff+1)->cookie); + if (eof) { + cookie = 0; + return 1; + } + goto refill; + } + + buf += sizeof(struct nfs_readdir_off); + rd = (struct nfs_readdir_data *)buf; + d->d_namlen = ntohl(rd->len); + bcopy(rd->name, d->d_name, d->d_namlen); + d->d_name[d->d_namlen] = '\0'; + + buf += (sizeof(struct nfs_readdir_data) + roundup(htonl(rd->len),4)); + roff = (struct nfs_readdir_off *)buf; + cookie = ntohl(roff->cookie); + return 0; +} diff --git a/lib/libstand/nfsv2.h b/lib/libstand/nfsv2.h index 1d7d9d4c8f91..398a1576e7b3 100644 --- a/lib/libstand/nfsv2.h +++ b/lib/libstand/nfsv2.h @@ -1,3 +1,4 @@ +/* $FreeBSD$ /* $NetBSD: nfsv2.h,v 1.2 1996/02/26 23:05:23 gwr Exp $ */ /* @@ -59,6 +60,7 @@ #define NFS_MAXPACKET (NFS_MAXPKTHDR+NFS_MAXDATA) #define NFS_MINPACKET 20 #define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ +#define NFS_READDIRSIZE 1024 /* Stat numbers for rpc returns */ #define NFS_OK 0