diff options
-rw-r--r-- | sys/fs/cd9660/cd9660_vnops.c | 39 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_vnops.c | 74 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_vnops.c | 39 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 8 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 8 | ||||
-rw-r--r-- | sys/kern/vnode_if.src | 5 | ||||
-rw-r--r-- | sys/msdosfs/msdosfs_vnops.c | 74 | ||||
-rw-r--r-- | sys/nfs/nfs_serv.c | 104 | ||||
-rw-r--r-- | sys/nfsserver/nfs_serv.c | 104 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 42 |
10 files changed, 313 insertions, 184 deletions
diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index eaac2a8..280f5f5 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)cd9660_vnops.c 8.3 (Berkeley) 1/23/94 - * $Id: cd9660_vnops.c,v 1.8 1994/09/22 19:37:46 wollman Exp $ + * $Id: cd9660_vnops.c,v 1.9 1994/09/26 00:32:59 gpalmer Exp $ */ #include <sys/param.h> @@ -480,6 +480,8 @@ cd9660_readdir(ap) struct iso_node *ip; struct buf *bp = NULL; u_short tmplen; + int ncookies = 0; + u_int *cookies = NULL; ip = VTOI(ap->a_vp); imp = ip->i_mnt; @@ -488,13 +490,17 @@ cd9660_readdir(ap) idp->saveent.d_namlen = 0; idp->assocent.d_namlen = 0; idp->uio = uio; -#if 0 - idp->cookiep = cookies; - idp->ncookies = ncookies; - idp->eof = 1; -#else - idp->cookiep = 0; -#endif + if (ap->a_ncookies != NULL) { + /* + * Guess the number of cookies needed. + */ + ncookies = uio->uio_resid / 16; + MALLOC(cookies, u_int *, ncookies * sizeof(u_int), M_TEMP, M_WAITOK); + idp->cookiep = cookies; + idp->ncookies = ncookies; + } else + idp->cookiep = 0; + idp->eof = 0; idp->curroff = uio->uio_offset; entryoffsetinblock = iso_blkoff(imp, idp->curroff); @@ -610,14 +616,25 @@ cd9660_readdir(ap) } if (error < 0) error = 0; + + if (ap->a_ncookies != NULL) { + if (error) + FREE(cookies, M_TEMP); + else { + /* + * Work out the number of cookies actually used. + */ + *ap->a_ncookies = ncookies - idp->ncookies; + *ap->a_cookies = cookies; + } + } if (bp) brelse (bp); uio->uio_offset = idp->uio_off; -#if 0 - *eofflagp = idp->eof; -#endif + if (ap->a_eofflag) + *ap->a_eofflag = idp->eof; FREE(idp,M_TEMP); diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 5235e2d..033c23a 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -1,4 +1,4 @@ -/* $Id: msdosfs_vnops.c,v 1.2 1994/09/21 03:47:17 wollman Exp $ */ +/* $Id: msdosfs_vnops.c,v 1.3 1994/09/27 20:42:56 phk Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */ /*- @@ -1444,19 +1444,14 @@ msdosfs_readdir(ap) struct dirent *crnt; u_char dirbuf[512]; /* holds converted dos directories */ struct uio *uio = ap->a_uio; - int ncookies = 1; - u_int* cookies = NULL; + off_t off; + int ncookies = 0; #ifdef MSDOSFS_DEBUG printf("msdosfs_readdir(): vp %08x, uio %08x, cred %08x, eofflagp %08x\n", ap->a_vp, uio, ap->a_cred, ap->a_eofflag); #endif -#if 0 - if (!ap->a_cookies) - ncookies = 1; -#endif - /* * msdosfs_readdir() won't operate properly on regular files since * it does i/o only with the the filesystem vnode, and hence can @@ -1478,6 +1473,7 @@ msdosfs_readdir(ap) return EINVAL; uio->uio_resid = count; uio->uio_iov->iov_len = count; + off = uio->uio_offset; /* * If they are reading from the root directory then, we simulate @@ -1501,23 +1497,14 @@ msdosfs_readdir(ap) n = 1; if (!uio->uio_offset) { n = 2; - if (cookies) { - *cookies++ = sizeof(struct direntry); - ncookies--; - } + ncookies++; } - if (cookies) { - if (ncookies-- <= 0) - n--; - else - *cookies++ = 2 * sizeof(struct direntry); - } - + ncookies++; error = uiomove((char *) rootdots + uio->uio_offset, n * sizeof(struct direntry), uio); } } - while (!error && uio->uio_resid > 0 && ncookies > 0) { + while (!error && uio->uio_resid > 0) { lbn = (uio->uio_offset - bias) >> pmp->pm_cnshift; on = (uio->uio_offset - bias) & pmp->pm_crbomask; n = min((u_long) (pmp->pm_bpcluster - on), uio->uio_resid); @@ -1561,10 +1548,6 @@ msdosfs_readdir(ap) (dentp->deAttributes & ATTR_VOLUME)) { if (prev) { prev->d_reclen += sizeof(struct direntry); - if (cookies) { - ncookies++; - cookies--; - } } else { prev = crnt; prev->d_fileno = 0; @@ -1572,6 +1555,7 @@ msdosfs_readdir(ap) prev->d_type = DT_UNKNOWN; prev->d_namlen = 0; prev->d_name[0] = 0; + ncookies++; } } else { /* @@ -1606,13 +1590,9 @@ msdosfs_readdir(ap) * dentp->deStartCluster); */ prev = crnt; + ncookies++; } dentp++; - if (cookies) { - *cookies++ = (u_int)((char *)dentp - bp->b_data - on) - + uio->uio_offset; - ncookies--; - } crnt = (struct dirent *) ((char *) crnt + sizeof(struct direntry)); pushout = 1; @@ -1634,8 +1614,6 @@ msdosfs_readdir(ap) prev = 0; crnt = (struct dirent *) dirbuf; } - if (ncookies <= 0) - break; } if (pushout) { pushout = 0; @@ -1659,18 +1637,40 @@ msdosfs_readdir(ap) } out: ; uio->uio_resid += lost; + if (!error && ap->a_ncookies != NULL) { + struct dirent* dpStart; + struct dirent* dpEnd; + struct dirent* dp; + u_int *cookies; + u_int *cookiep; + + if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) + panic("msdosfs_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; + 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 0 /* * I don't know why we bother setting this eofflag, getdirentries() * in vfs_syscalls.c doesn't bother to look at it when we return. * (because NFS uses it in nfs_serv.c -- JMP) */ - if (dep->de_FileSize - uio->uio_offset - bias <= 0) - *ap->a_eofflag = 1; - else - *ap->a_eofflag = 0; -#endif + if (ap->a_eofflag) + if (dep->de_FileSize - uio->uio_offset - bias <= 0) + *ap->a_eofflag = 1; + else + *ap->a_eofflag = 0; return error; } diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c index eaac2a8..280f5f5 100644 --- a/sys/isofs/cd9660/cd9660_vnops.c +++ b/sys/isofs/cd9660/cd9660_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)cd9660_vnops.c 8.3 (Berkeley) 1/23/94 - * $Id: cd9660_vnops.c,v 1.8 1994/09/22 19:37:46 wollman Exp $ + * $Id: cd9660_vnops.c,v 1.9 1994/09/26 00:32:59 gpalmer Exp $ */ #include <sys/param.h> @@ -480,6 +480,8 @@ cd9660_readdir(ap) struct iso_node *ip; struct buf *bp = NULL; u_short tmplen; + int ncookies = 0; + u_int *cookies = NULL; ip = VTOI(ap->a_vp); imp = ip->i_mnt; @@ -488,13 +490,17 @@ cd9660_readdir(ap) idp->saveent.d_namlen = 0; idp->assocent.d_namlen = 0; idp->uio = uio; -#if 0 - idp->cookiep = cookies; - idp->ncookies = ncookies; - idp->eof = 1; -#else - idp->cookiep = 0; -#endif + if (ap->a_ncookies != NULL) { + /* + * Guess the number of cookies needed. + */ + ncookies = uio->uio_resid / 16; + MALLOC(cookies, u_int *, ncookies * sizeof(u_int), M_TEMP, M_WAITOK); + idp->cookiep = cookies; + idp->ncookies = ncookies; + } else + idp->cookiep = 0; + idp->eof = 0; idp->curroff = uio->uio_offset; entryoffsetinblock = iso_blkoff(imp, idp->curroff); @@ -610,14 +616,25 @@ cd9660_readdir(ap) } if (error < 0) error = 0; + + if (ap->a_ncookies != NULL) { + if (error) + FREE(cookies, M_TEMP); + else { + /* + * Work out the number of cookies actually used. + */ + *ap->a_ncookies = ncookies - idp->ncookies; + *ap->a_cookies = cookies; + } + } if (bp) brelse (bp); uio->uio_offset = idp->uio_off; -#if 0 - *eofflagp = idp->eof; -#endif + if (ap->a_eofflag) + *ap->a_eofflag = idp->eof; FREE(idp,M_TEMP); diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 4607112..21fc5ee 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.7 1994/09/21 03:46:49 wollman Exp $ + * $Id: vfs_syscalls.c,v 1.8 1994/09/22 19:37:56 wollman Exp $ */ #include <sys/param.h> @@ -1970,7 +1970,7 @@ ogetdirentries(p, uap, retval) loff = auio.uio_offset = fp->f_offset; # if (BYTE_ORDER != LITTLE_ENDIAN) if (vp->v_mount->mnt_maxsymlinklen <= 0) { - error = VOP_READDIR(vp, &auio, fp->f_cred); + error = VOP_READDIR(vp, &auio, fp->f_cred, NULL, NULL, NULL); fp->f_offset = auio.uio_offset; } else # endif @@ -1981,7 +1981,7 @@ ogetdirentries(p, uap, retval) kiov.iov_len = uap->count; MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK); kiov.iov_base = dirbuf; - error = VOP_READDIR(vp, &kuio, fp->f_cred); + error = VOP_READDIR(vp, &kuio, fp->f_cred, NULL, NULL, NULL); fp->f_offset = kuio.uio_offset; if (error == 0) { readcnt = uap->count - kuio.uio_resid; @@ -2066,7 +2066,7 @@ unionread: auio.uio_resid = uap->count; VOP_LOCK(vp); loff = auio.uio_offset = fp->f_offset; - error = VOP_READDIR(vp, &auio, fp->f_cred); + error = VOP_READDIR(vp, &auio, fp->f_cred, NULL, NULL, NULL); fp->f_offset = auio.uio_offset; VOP_UNLOCK(vp); if (error) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 4607112..21fc5ee 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.7 1994/09/21 03:46:49 wollman Exp $ + * $Id: vfs_syscalls.c,v 1.8 1994/09/22 19:37:56 wollman Exp $ */ #include <sys/param.h> @@ -1970,7 +1970,7 @@ ogetdirentries(p, uap, retval) loff = auio.uio_offset = fp->f_offset; # if (BYTE_ORDER != LITTLE_ENDIAN) if (vp->v_mount->mnt_maxsymlinklen <= 0) { - error = VOP_READDIR(vp, &auio, fp->f_cred); + error = VOP_READDIR(vp, &auio, fp->f_cred, NULL, NULL, NULL); fp->f_offset = auio.uio_offset; } else # endif @@ -1981,7 +1981,7 @@ ogetdirentries(p, uap, retval) kiov.iov_len = uap->count; MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK); kiov.iov_base = dirbuf; - error = VOP_READDIR(vp, &kuio, fp->f_cred); + error = VOP_READDIR(vp, &kuio, fp->f_cred, NULL, NULL, NULL); fp->f_offset = kuio.uio_offset; if (error == 0) { readcnt = uap->count - kuio.uio_resid; @@ -2066,7 +2066,7 @@ unionread: auio.uio_resid = uap->count; VOP_LOCK(vp); loff = auio.uio_offset = fp->f_offset; - error = VOP_READDIR(vp, &auio, fp->f_cred); + error = VOP_READDIR(vp, &auio, fp->f_cred, NULL, NULL, NULL); fp->f_offset = auio.uio_offset; VOP_UNLOCK(vp); if (error) diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index c2b012e..4e36675 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -31,7 +31,7 @@ # SUCH DAMAGE. # # @(#)vnode_if.src 8.3 (Berkeley) 2/3/94 -# $Id$ +# $Id: vnode_if.src,v 1.2 1994/08/02 07:43:37 davidg Exp $ # vop_lookup { IN struct vnode *dvp; @@ -188,6 +188,9 @@ vop_readdir { IN struct vnode *vp; INOUT struct uio *uio; IN struct ucred *cred; + INOUT int *eofflag; + INOUT int *ncookies; + INOUT u_int **cookies; }; vop_readlink { diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c index 5235e2d..033c23a 100644 --- a/sys/msdosfs/msdosfs_vnops.c +++ b/sys/msdosfs/msdosfs_vnops.c @@ -1,4 +1,4 @@ -/* $Id: msdosfs_vnops.c,v 1.2 1994/09/21 03:47:17 wollman Exp $ */ +/* $Id: msdosfs_vnops.c,v 1.3 1994/09/27 20:42:56 phk Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */ /*- @@ -1444,19 +1444,14 @@ msdosfs_readdir(ap) struct dirent *crnt; u_char dirbuf[512]; /* holds converted dos directories */ struct uio *uio = ap->a_uio; - int ncookies = 1; - u_int* cookies = NULL; + off_t off; + int ncookies = 0; #ifdef MSDOSFS_DEBUG printf("msdosfs_readdir(): vp %08x, uio %08x, cred %08x, eofflagp %08x\n", ap->a_vp, uio, ap->a_cred, ap->a_eofflag); #endif -#if 0 - if (!ap->a_cookies) - ncookies = 1; -#endif - /* * msdosfs_readdir() won't operate properly on regular files since * it does i/o only with the the filesystem vnode, and hence can @@ -1478,6 +1473,7 @@ msdosfs_readdir(ap) return EINVAL; uio->uio_resid = count; uio->uio_iov->iov_len = count; + off = uio->uio_offset; /* * If they are reading from the root directory then, we simulate @@ -1501,23 +1497,14 @@ msdosfs_readdir(ap) n = 1; if (!uio->uio_offset) { n = 2; - if (cookies) { - *cookies++ = sizeof(struct direntry); - ncookies--; - } + ncookies++; } - if (cookies) { - if (ncookies-- <= 0) - n--; - else - *cookies++ = 2 * sizeof(struct direntry); - } - + ncookies++; error = uiomove((char *) rootdots + uio->uio_offset, n * sizeof(struct direntry), uio); } } - while (!error && uio->uio_resid > 0 && ncookies > 0) { + while (!error && uio->uio_resid > 0) { lbn = (uio->uio_offset - bias) >> pmp->pm_cnshift; on = (uio->uio_offset - bias) & pmp->pm_crbomask; n = min((u_long) (pmp->pm_bpcluster - on), uio->uio_resid); @@ -1561,10 +1548,6 @@ msdosfs_readdir(ap) (dentp->deAttributes & ATTR_VOLUME)) { if (prev) { prev->d_reclen += sizeof(struct direntry); - if (cookies) { - ncookies++; - cookies--; - } } else { prev = crnt; prev->d_fileno = 0; @@ -1572,6 +1555,7 @@ msdosfs_readdir(ap) prev->d_type = DT_UNKNOWN; prev->d_namlen = 0; prev->d_name[0] = 0; + ncookies++; } } else { /* @@ -1606,13 +1590,9 @@ msdosfs_readdir(ap) * dentp->deStartCluster); */ prev = crnt; + ncookies++; } dentp++; - if (cookies) { - *cookies++ = (u_int)((char *)dentp - bp->b_data - on) - + uio->uio_offset; - ncookies--; - } crnt = (struct dirent *) ((char *) crnt + sizeof(struct direntry)); pushout = 1; @@ -1634,8 +1614,6 @@ msdosfs_readdir(ap) prev = 0; crnt = (struct dirent *) dirbuf; } - if (ncookies <= 0) - break; } if (pushout) { pushout = 0; @@ -1659,18 +1637,40 @@ msdosfs_readdir(ap) } out: ; uio->uio_resid += lost; + if (!error && ap->a_ncookies != NULL) { + struct dirent* dpStart; + struct dirent* dpEnd; + struct dirent* dp; + u_int *cookies; + u_int *cookiep; + + if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) + panic("msdosfs_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; + 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 0 /* * I don't know why we bother setting this eofflag, getdirentries() * in vfs_syscalls.c doesn't bother to look at it when we return. * (because NFS uses it in nfs_serv.c -- JMP) */ - if (dep->de_FileSize - uio->uio_offset - bias <= 0) - *ap->a_eofflag = 1; - else - *ap->a_eofflag = 0; -#endif + if (ap->a_eofflag) + if (dep->de_FileSize - uio->uio_offset - bias <= 0) + *ap->a_eofflag = 1; + else + *ap->a_eofflag = 0; return error; } diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c index 55897c4..d43a86e 100644 --- a/sys/nfs/nfs_serv.c +++ b/sys/nfs/nfs_serv.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_serv.c 8.3 (Berkeley) 1/12/94 - * $Id: nfs_serv.c,v 1.4 1994/08/29 06:09:06 davidg Exp $ + * $Id: nfs_serv.c,v 1.5 1994/09/22 19:38:25 wollman Exp $ */ /* @@ -1382,14 +1382,15 @@ nfsrv_readdir(nfsd, mrep, md, dpos, cred, nam, mrq) int len, nlen, rem, xfer, tsiz, i, error = 0; int siz, cnt, fullsiz, eofflag, rdonly, cache; u_quad_t frev; - u_long on, off, toff; + u_long off, toff; + int ncookies; + u_int *cookies; + u_int *cookiep; fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); - toff = fxdr_unsigned(u_long, *tl++); - off = (toff & ~(NFS_DIRBLKSIZ-1)); - on = (toff & (NFS_DIRBLKSIZ-1)); + off = toff = fxdr_unsigned(u_long, *tl++); cnt = fxdr_unsigned(int, *tl); siz = ((cnt+NFS_DIRBLKSIZ-1) & ~(NFS_DIRBLKSIZ-1)); if (cnt > NFS_MAXREADDIR) @@ -1414,17 +1415,27 @@ again: io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_procp = (struct proc *)0; - error = VOP_READDIR(vp, &io, cred); + cookies = NULL; + eofflag = 0; + error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies); off = (off_t)io.uio_offset; if (error) { vrele(vp); free((caddr_t)rbuf, M_TEMP); nfsm_reply(0); } - if (io.uio_resid < fullsiz) - eofflag = 0; - else - eofflag = 1; + if (cookies == NULL) { + /* + * If the filesystem doen't support cookies, return eof. + */ + vrele(vp); + nfsm_reply(2*NFSX_UNSIGNED); + nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); + *tl++ = nfs_false; + *tl = nfs_true; + FREE((caddr_t)rbuf, M_TEMP); + return (0); + } if (io.uio_resid) { siz -= io.uio_resid; @@ -1439,6 +1450,7 @@ again: *tl++ = nfs_false; *tl = nfs_true; FREE((caddr_t)rbuf, M_TEMP); + FREE(cookies, M_TEMP); return (0); } } @@ -1447,23 +1459,24 @@ again: * Check for degenerate cases of nothing useful read. * If so go try again */ - cpos = rbuf + on; + cpos = rbuf; cend = rbuf + siz; dp = (struct dirent *)cpos; - while (cpos < cend && dp->d_fileno == 0) { + cookiep = cookies; + while (cpos < cend && ncookies > 0 + && (*cookiep <= toff || dp->d_fileno == 0)) { cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; + ncookies--; } if (cpos >= cend) { toff = off; siz = fullsiz; - on = 0; + FREE(cookies, M_TEMP); goto again; } - cpos = rbuf + on; - cend = rbuf + siz; - dp = (struct dirent *)cpos; len = 3*NFSX_UNSIGNED; /* paranoia, probably can be 0 */ nfsm_reply(siz); mp = mp2 = mb; @@ -1515,13 +1528,12 @@ again: nfsm_clget; /* Finish off the record */ - toff += dp->d_reclen; - *tl = txdr_unsigned(toff); + *tl = txdr_unsigned(*cookiep); bp += NFSX_UNSIGNED; - } else - toff += dp->d_reclen; + } cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; } vrele(vp); nfsm_clget; @@ -1539,6 +1551,7 @@ again: } else mp->m_len += bp - bpos; FREE(rbuf, M_TEMP); + FREE(cookies, M_TEMP); nfsm_srvdone; } @@ -1570,14 +1583,15 @@ nqnfsrv_readdirlook(nfsd, mrep, md, dpos, cred, nam, mrq) int len, nlen, rem, xfer, tsiz, i, error = 0, duration2, cache2; int siz, cnt, fullsiz, eofflag, rdonly, cache; u_quad_t frev, frev2; - u_long on, off, toff; + u_long off, toff; + int ncookies; + u_int *cookies; + u_int *cookiep; fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_dissect(tl, u_long *, 3*NFSX_UNSIGNED); - toff = fxdr_unsigned(u_long, *tl++); - off = (toff & ~(NFS_DIRBLKSIZ-1)); - on = (toff & (NFS_DIRBLKSIZ-1)); + toff = off = fxdr_unsigned(u_long, *tl++); cnt = fxdr_unsigned(int, *tl++); duration2 = fxdr_unsigned(int, *tl); siz = ((cnt+NFS_DIRBLKSIZ-1) & ~(NFS_DIRBLKSIZ-1)); @@ -1603,17 +1617,27 @@ again: io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_procp = (struct proc *)0; - error = VOP_READDIR(vp, &io, cred); + cookies = NULL; + eofflag = 0; + error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies); off = (u_long)io.uio_offset; if (error) { vrele(vp); free((caddr_t)rbuf, M_TEMP); nfsm_reply(0); } - if (io.uio_resid < fullsiz) - eofflag = 0; - else - eofflag = 1; + if (cookies == NULL) { + /* + * If the filesystem doen't support cookies, return eof. + */ + vrele(vp); + nfsm_reply(2*NFSX_UNSIGNED); + nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); + *tl++ = nfs_false; + *tl = nfs_true; + FREE((caddr_t)rbuf, M_TEMP); + return (0); + } if (io.uio_resid) { siz -= io.uio_resid; @@ -1628,6 +1652,7 @@ again: *tl++ = nfs_false; *tl = nfs_true; FREE((caddr_t)rbuf, M_TEMP); + FREE(cookies, M_TEMP); return (0); } } @@ -1636,23 +1661,24 @@ again: * Check for degenerate cases of nothing useful read. * If so go try again */ - cpos = rbuf + on; + cpos = rbuf; cend = rbuf + siz; dp = (struct dirent *)cpos; - while (cpos < cend && dp->d_fileno == 0) { + cookiep = cookies; + while (cpos < cend && ncookies > 0 + && (*cookiep <= toff || dp->d_fileno == 0)) { cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; + ncookies--; } if (cpos >= cend) { toff = off; siz = fullsiz; - on = 0; + FREE(cookies, M_TEMP); goto again; } - cpos = rbuf + on; - cend = rbuf + siz; - dp = (struct dirent *)cpos; len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */ nfsm_reply(siz); mp = mp2 = mb; @@ -1752,14 +1778,13 @@ again: nfsm_clget; /* Finish off the record */ - toff += dp->d_reclen; - *tl = txdr_unsigned(toff); + *tl = txdr_unsigned(*cookiep); bp += NFSX_UNSIGNED; - } else + } invalid: - toff += dp->d_reclen; cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; } vrele(vp); nfsm_clget; @@ -1777,6 +1802,7 @@ invalid: } else mp->m_len += bp - bpos; FREE(rbuf, M_TEMP); + FREE(cookies, M_TEMP); nfsm_srvdone; } diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 55897c4..d43a86e 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_serv.c 8.3 (Berkeley) 1/12/94 - * $Id: nfs_serv.c,v 1.4 1994/08/29 06:09:06 davidg Exp $ + * $Id: nfs_serv.c,v 1.5 1994/09/22 19:38:25 wollman Exp $ */ /* @@ -1382,14 +1382,15 @@ nfsrv_readdir(nfsd, mrep, md, dpos, cred, nam, mrq) int len, nlen, rem, xfer, tsiz, i, error = 0; int siz, cnt, fullsiz, eofflag, rdonly, cache; u_quad_t frev; - u_long on, off, toff; + u_long off, toff; + int ncookies; + u_int *cookies; + u_int *cookiep; fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); - toff = fxdr_unsigned(u_long, *tl++); - off = (toff & ~(NFS_DIRBLKSIZ-1)); - on = (toff & (NFS_DIRBLKSIZ-1)); + off = toff = fxdr_unsigned(u_long, *tl++); cnt = fxdr_unsigned(int, *tl); siz = ((cnt+NFS_DIRBLKSIZ-1) & ~(NFS_DIRBLKSIZ-1)); if (cnt > NFS_MAXREADDIR) @@ -1414,17 +1415,27 @@ again: io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_procp = (struct proc *)0; - error = VOP_READDIR(vp, &io, cred); + cookies = NULL; + eofflag = 0; + error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies); off = (off_t)io.uio_offset; if (error) { vrele(vp); free((caddr_t)rbuf, M_TEMP); nfsm_reply(0); } - if (io.uio_resid < fullsiz) - eofflag = 0; - else - eofflag = 1; + if (cookies == NULL) { + /* + * If the filesystem doen't support cookies, return eof. + */ + vrele(vp); + nfsm_reply(2*NFSX_UNSIGNED); + nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); + *tl++ = nfs_false; + *tl = nfs_true; + FREE((caddr_t)rbuf, M_TEMP); + return (0); + } if (io.uio_resid) { siz -= io.uio_resid; @@ -1439,6 +1450,7 @@ again: *tl++ = nfs_false; *tl = nfs_true; FREE((caddr_t)rbuf, M_TEMP); + FREE(cookies, M_TEMP); return (0); } } @@ -1447,23 +1459,24 @@ again: * Check for degenerate cases of nothing useful read. * If so go try again */ - cpos = rbuf + on; + cpos = rbuf; cend = rbuf + siz; dp = (struct dirent *)cpos; - while (cpos < cend && dp->d_fileno == 0) { + cookiep = cookies; + while (cpos < cend && ncookies > 0 + && (*cookiep <= toff || dp->d_fileno == 0)) { cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; + ncookies--; } if (cpos >= cend) { toff = off; siz = fullsiz; - on = 0; + FREE(cookies, M_TEMP); goto again; } - cpos = rbuf + on; - cend = rbuf + siz; - dp = (struct dirent *)cpos; len = 3*NFSX_UNSIGNED; /* paranoia, probably can be 0 */ nfsm_reply(siz); mp = mp2 = mb; @@ -1515,13 +1528,12 @@ again: nfsm_clget; /* Finish off the record */ - toff += dp->d_reclen; - *tl = txdr_unsigned(toff); + *tl = txdr_unsigned(*cookiep); bp += NFSX_UNSIGNED; - } else - toff += dp->d_reclen; + } cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; } vrele(vp); nfsm_clget; @@ -1539,6 +1551,7 @@ again: } else mp->m_len += bp - bpos; FREE(rbuf, M_TEMP); + FREE(cookies, M_TEMP); nfsm_srvdone; } @@ -1570,14 +1583,15 @@ nqnfsrv_readdirlook(nfsd, mrep, md, dpos, cred, nam, mrq) int len, nlen, rem, xfer, tsiz, i, error = 0, duration2, cache2; int siz, cnt, fullsiz, eofflag, rdonly, cache; u_quad_t frev, frev2; - u_long on, off, toff; + u_long off, toff; + int ncookies; + u_int *cookies; + u_int *cookiep; fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_dissect(tl, u_long *, 3*NFSX_UNSIGNED); - toff = fxdr_unsigned(u_long, *tl++); - off = (toff & ~(NFS_DIRBLKSIZ-1)); - on = (toff & (NFS_DIRBLKSIZ-1)); + toff = off = fxdr_unsigned(u_long, *tl++); cnt = fxdr_unsigned(int, *tl++); duration2 = fxdr_unsigned(int, *tl); siz = ((cnt+NFS_DIRBLKSIZ-1) & ~(NFS_DIRBLKSIZ-1)); @@ -1603,17 +1617,27 @@ again: io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_procp = (struct proc *)0; - error = VOP_READDIR(vp, &io, cred); + cookies = NULL; + eofflag = 0; + error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies); off = (u_long)io.uio_offset; if (error) { vrele(vp); free((caddr_t)rbuf, M_TEMP); nfsm_reply(0); } - if (io.uio_resid < fullsiz) - eofflag = 0; - else - eofflag = 1; + if (cookies == NULL) { + /* + * If the filesystem doen't support cookies, return eof. + */ + vrele(vp); + nfsm_reply(2*NFSX_UNSIGNED); + nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); + *tl++ = nfs_false; + *tl = nfs_true; + FREE((caddr_t)rbuf, M_TEMP); + return (0); + } if (io.uio_resid) { siz -= io.uio_resid; @@ -1628,6 +1652,7 @@ again: *tl++ = nfs_false; *tl = nfs_true; FREE((caddr_t)rbuf, M_TEMP); + FREE(cookies, M_TEMP); return (0); } } @@ -1636,23 +1661,24 @@ again: * Check for degenerate cases of nothing useful read. * If so go try again */ - cpos = rbuf + on; + cpos = rbuf; cend = rbuf + siz; dp = (struct dirent *)cpos; - while (cpos < cend && dp->d_fileno == 0) { + cookiep = cookies; + while (cpos < cend && ncookies > 0 + && (*cookiep <= toff || dp->d_fileno == 0)) { cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; + ncookies--; } if (cpos >= cend) { toff = off; siz = fullsiz; - on = 0; + FREE(cookies, M_TEMP); goto again; } - cpos = rbuf + on; - cend = rbuf + siz; - dp = (struct dirent *)cpos; len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */ nfsm_reply(siz); mp = mp2 = mb; @@ -1752,14 +1778,13 @@ again: nfsm_clget; /* Finish off the record */ - toff += dp->d_reclen; - *tl = txdr_unsigned(toff); + *tl = txdr_unsigned(*cookiep); bp += NFSX_UNSIGNED; - } else + } invalid: - toff += dp->d_reclen; cpos += dp->d_reclen; dp = (struct dirent *)cpos; + cookiep++; } vrele(vp); nfsm_clget; @@ -1777,6 +1802,7 @@ invalid: } else mp->m_len += bp - bpos; FREE(rbuf, M_TEMP); + FREE(cookies, M_TEMP); nfsm_srvdone; } 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); } |