diff options
author | dfr <dfr@FreeBSD.org> | 1994-09-28 16:45:22 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 1994-09-28 16:45:22 +0000 |
commit | 57b6c0c34c7d3130b7c00e4293686bd588419fe6 (patch) | |
tree | 31a9fd0d25f683274b252c0f76348271e04406c4 /sys/ufs | |
parent | c49750310fc7779d5e19ee11d35ae43d4a9d4548 (diff) | |
download | FreeBSD-src-57b6c0c34c7d3130b7c00e4293686bd588419fe6.zip FreeBSD-src-57b6c0c34c7d3130b7c00e4293686bd588419fe6.tar.gz |
Make NFS ask the filesystems for directory cookies instead of making them
itself.
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index f7eeacf..ae8a14c 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_vnops.c 8.10 (Berkeley) 4/1/94 - * $Id: ufs_vnops.c,v 1.5 1994/09/22 19:38:41 wollman Exp $ + * $Id: ufs_vnops.c,v 1.6 1994/09/27 20:33:37 phk Exp $ */ #include <sys/param.h> @@ -1353,11 +1353,21 @@ ufs_readdir(ap) struct vnode *a_vp; struct uio *a_uio; struct ucred *a_cred; + int *a_ncookies; + u_int **cookies; } */ *ap; { register struct uio *uio = ap->a_uio; + off_t off; int count, lost, error; + if (ap->a_ncookies != NULL) + /* + * Ensure that the block is aligned. The caller can use + * the cookies to determine where in the block to start. + */ + uio->uio_offset &= ~(DIRBLKSIZ - 1); + off = uio->uio_offset; count = uio->uio_resid; count &= ~(DIRBLKSIZ - 1); lost = uio->uio_resid - count; @@ -1407,6 +1417,36 @@ ufs_readdir(ap) # else error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred); # endif + if (!error && ap->a_ncookies != NULL) { + struct dirent* dpStart; + struct dirent* dpEnd; + struct dirent* dp; + int ncookies; + u_int *cookies; + u_int *cookiep; + + if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) + panic("ufs_readdir: unexpected uio from NFS server"); + dpStart = (struct dirent *) + (uio->uio_iov->iov_base - (uio->uio_offset - off)); + dpEnd = (struct dirent *) uio->uio_iov->iov_base; + for (dp = dpStart, ncookies = 0; + dp < dpEnd; + dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) + ncookies++; + MALLOC(cookies, u_int *, ncookies * sizeof(u_int), + M_TEMP, M_WAITOK); + for (dp = dpStart, cookiep = cookies; + dp < dpEnd; + dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) { + off += dp->d_reclen; + *cookiep++ = (u_int) off; + } + *ap->a_ncookies = ncookies; + *ap->a_cookies = cookies; + } + if (ap->a_eofflag) + *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset; uio->uio_resid += lost; return (error); } |