summaryrefslogtreecommitdiffstats
path: root/lib/libstand
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2000-05-01 15:03:52 +0000
committerps <ps@FreeBSD.org>2000-05-01 15:03:52 +0000
commit222439bc50eba6251adfdfbf06fc7474d33911ad (patch)
tree5dbb3e9a288a2a9645a04a5419f210f3bbe72f55 /lib/libstand
parentece3cbbe3962c04d0ca1218fa02284dc721ee6bd (diff)
downloadFreeBSD-src-222439bc50eba6251adfdfbf06fc7474d33911ad.zip
FreeBSD-src-222439bc50eba6251adfdfbf06fc7474d33911ad.tar.gz
Add readdir support to the NFS filesystem in libstand.
Diffstat (limited to 'lib/libstand')
-rw-r--r--lib/libstand/nfs.c81
-rw-r--r--lib/libstand/nfsv2.h2
2 files changed, 82 insertions, 1 deletions
diff --git a/lib/libstand/nfs.c b/lib/libstand/nfs.c
index 5669973..a02ca58 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 1d7d9d4..398a157 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
OpenPOWER on IntegriCloud