summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/gnu/ext2fs/ext2_lookup.c26
-rw-r--r--sys/i386/ibcs2/ibcs2_misc.c128
-rw-r--r--sys/i386/linux/linux_file.c63
-rw-r--r--sys/kern/vfs_cluster.c5
-rw-r--r--sys/nfs/nfs.h19
-rw-r--r--sys/nfs/nfs_bio.c20
-rw-r--r--sys/nfs/nfs_node.c8
-rw-r--r--sys/nfs/nfs_serv.c23
-rw-r--r--sys/nfs/nfs_socket.c6
-rw-r--r--sys/nfs/nfs_srvcache.c6
-rw-r--r--sys/nfs/nfs_syscalls.c15
-rw-r--r--sys/nfs/nfs_vfsops.c15
-rw-r--r--sys/nfs/nfs_vnops.c51
-rw-r--r--sys/nfs/nfsmount.h18
14 files changed, 310 insertions, 93 deletions
diff --git a/sys/gnu/ext2fs/ext2_lookup.c b/sys/gnu/ext2fs/ext2_lookup.c
index baeaa52775ff..b781fda58896 100644
--- a/sys/gnu/ext2fs/ext2_lookup.c
+++ b/sys/gnu/ext2fs/ext2_lookup.c
@@ -156,6 +156,7 @@ ext2_readdir(ap)
int count, error;
struct ext2_dir_entry *edp, *dp;
+ int ncookies;
struct dirent dstdp;
struct uio auio;
struct iovec aiov;
@@ -183,6 +184,7 @@ printf("ext2_readdir called uio->uio_offset %d uio->uio_resid %d count %d \n",
if (error == 0) {
readcnt = count - auio.uio_resid;
edp = (struct ext2_dir_entry *)&dirbuf[readcnt];
+ ncookies = 0;
for (dp = (struct ext2_dir_entry *)dirbuf;
!error && uio->uio_resid > 0 && dp < edp; ) {
ext2_dirconv2ffs(dp, &dstdp);
@@ -194,6 +196,8 @@ printf("ext2_readdir called uio->uio_offset %d uio->uio_resid %d count %d \n",
error =
uiomove((caddr_t)&dstdp,
dstdp.d_reclen, uio);
+ if (!error)
+ ncookies++;
} else
break;
} else {
@@ -203,8 +207,30 @@ printf("ext2_readdir called uio->uio_offset %d uio->uio_resid %d count %d \n",
}
/* we need to correct uio_offset */
uio->uio_offset = startoffset + (caddr_t)dp - dirbuf;
+
+ if (!error && ap->a_ncookies != NULL) {
+ u_int *cookies;
+ u_int *cookiep;
+ off_t off;
+
+ if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
+ panic("ext2fs_readdir: unexpected uio from NFS server");
+ MALLOC(cookies, u_int *, ncookies * sizeof(u_long), M_TEMP,
+ M_WAITOK);
+ off = startoffset;
+ for (dp = (struct ext2_dir_entry *)dirbuf, cookiep = cookies;
+ dp < edp;
+ dp = (struct ext2_dir_entry *)((caddr_t) dp + dp->rec_len)) {
+ off += dp->rec_len;
+ *cookiep++ = (u_int) off;
+ }
+ *ap->a_ncookies = ncookies;
+ *ap->a_cookies = cookies;
+ }
}
FREE(dirbuf, M_TEMP);
+ if (ap->a_eofflag)
+ *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
return (error);
}
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c
index 863f5b087197..423d4c600c5b 100644
--- a/sys/i386/ibcs2/ibcs2_misc.c
+++ b/sys/i386/ibcs2/ibcs2_misc.c
@@ -45,7 +45,7 @@
*
* @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
*
- * $Id: ibcs2_misc.c,v 1.12 1996/12/05 03:14:14 nate Exp $
+ * $Id: ibcs2_misc.c,v 1.10.2.1 1996/12/12 19:39:18 jkh Exp $
*/
/*
@@ -71,6 +71,7 @@
#include <sys/resourcevar.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/dirent.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/vnode.h>
@@ -79,8 +80,6 @@
#include <sys/utsname.h>
#include <sys/unistd.h>
-#include <ufs/ufs/dir.h>
-
#include <netinet/in.h>
#include <sys/sysproto.h>
@@ -337,8 +336,10 @@ ibcs2_getdents(p, uap, retval)
struct iovec aiov;
struct ibcs2_dirent idb;
off_t off; /* true file offset */
- int buflen, error, eofflag, blockoff;
-#define BSD_DIRENT(cp) ((struct direct *)(cp))
+ int buflen, error, eofflag;
+ u_int *cookies = NULL, *cookiep;
+ int ncookies;
+#define BSD_DIRENT(cp) ((struct dirent *)(cp))
#define IBCS2_RECLEN(reclen) (reclen + sizeof(u_short))
if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
@@ -350,8 +351,8 @@ ibcs2_getdents(p, uap, retval)
return (EINVAL);
off = fp->f_offset;
- blockoff = off % DIRBLKSIZ;
- buflen = max(DIRBLKSIZ, SCARG(uap, nbytes) + blockoff);
+#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */
+ buflen = max(DIRBLKSIZ, SCARG(uap, nbytes));
buflen = min(buflen, MAXBSIZE);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
@@ -364,29 +365,59 @@ again:
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = p;
auio.uio_resid = buflen;
- auio.uio_offset = off - (off_t)blockoff;
+ auio.uio_offset = off;
+
+ if (cookies) {
+ free(cookies, M_TEMP);
+ cookies = NULL;
+ }
+
/*
* First we read into the malloc'ed buffer, then
* we massage it into user space, one record at a time.
*/
- if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL))
+ if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies))
goto out;
inp = buf;
- inp += blockoff;
outp = SCARG(uap, buf);
resid = SCARG(uap, nbytes);
- if ((len = buflen - auio.uio_resid - blockoff) == 0)
+ if ((len = buflen - auio.uio_resid) <= 0)
goto eof;
+
+ cookiep = cookies;
+
+ if (cookies) {
+ /*
+ * When using cookies, the vfs has the option of reading from
+ * a different offset than that supplied (UFS truncates the
+ * offset to a block boundary to make sure that it never reads
+ * partway through a directory entry, even if the directory
+ * has been compacted).
+ */
+ while (len > 0 && ncookies > 0 && *cookiep <= off) {
+ len -= BSD_DIRENT(inp)->d_reclen;
+ inp += BSD_DIRENT(inp)->d_reclen;
+ cookiep++;
+ ncookies--;
+ }
+ }
+
for (; len > 0; len -= reclen) {
+ if (cookiep && ncookies == 0)
+ break;
reclen = BSD_DIRENT(inp)->d_reclen;
if (reclen & 3) {
printf("ibcs2_getdents: reclen=%d\n", reclen);
error = EFAULT;
goto out;
}
- if (BSD_DIRENT(inp)->d_ino == 0) {
+ if (BSD_DIRENT(inp)->d_fileno == 0) {
inp += reclen; /* it is a hole; squish it out */
- off += reclen;
+ if (cookiep) {
+ off = *cookiep++;
+ ncookies--;
+ } else
+ off += reclen;
continue;
}
if (reclen > len || resid < IBCS2_RECLEN(reclen)) {
@@ -399,7 +430,7 @@ again:
* we have to worry about touching user memory outside of
* the copyout() call).
*/
- idb.d_ino = (ibcs2_ino_t)BSD_DIRENT(inp)->d_ino;
+ idb.d_ino = (ibcs2_ino_t)BSD_DIRENT(inp)->d_fileno;
idb.d_off = (ibcs2_off_t)off;
idb.d_reclen = (u_short)IBCS2_RECLEN(reclen);
if ((error = copyout((caddr_t)&idb, outp, 10)) != 0 ||
@@ -407,7 +438,11 @@ again:
BSD_DIRENT(inp)->d_namlen + 1)) != 0)
goto out;
/* advance past this real entry */
- off += reclen;
+ if (cookiep) {
+ off = *cookiep++;
+ ncookies--;
+ } else
+ off += reclen;
inp += reclen;
/* advance output past iBCS2-shaped entry */
outp += IBCS2_RECLEN(reclen);
@@ -420,6 +455,8 @@ again:
eof:
*retval = SCARG(uap, nbytes) - resid;
out:
+ if (cookies)
+ free(cookies, M_TEMP);
VOP_UNLOCK(vp);
free(buf, M_TEMP);
return (error);
@@ -444,7 +481,9 @@ ibcs2_read(p, uap, retval)
char name[14];
} idb;
off_t off; /* true file offset */
- int buflen, error, eofflag, size, blockoff;
+ int buflen, error, eofflag, size;
+ u_int *cookies = NULL, *cookiep;
+ int ncookies;
if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) {
if (error == EINVAL)
@@ -461,8 +500,7 @@ ibcs2_read(p, uap, retval)
DPRINTF(("ibcs2_read: read directory\n"));
off = fp->f_offset;
- blockoff = off % DIRBLKSIZ;
- buflen = max(DIRBLKSIZ, SCARG(uap, nbytes) + blockoff);
+ buflen = max(DIRBLKSIZ, SCARG(uap, nbytes));
buflen = min(buflen, MAXBSIZE);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
@@ -475,31 +513,61 @@ again:
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = p;
auio.uio_resid = buflen;
- auio.uio_offset = off - (off_t)blockoff;
+ auio.uio_offset = off;
+
+ if (cookies) {
+ free(cookies, M_TEMP);
+ cookies = NULL;
+ }
+
/*
* First we read into the malloc'ed buffer, then
* we massage it into user space, one record at a time.
*/
- if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 0, 0)) {
+ if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies)) {
DPRINTF(("VOP_READDIR failed: %d\n", error));
goto out;
}
inp = buf;
- inp += blockoff;
outp = SCARG(uap, buf);
resid = SCARG(uap, nbytes);
- if ((len = buflen - auio.uio_resid - blockoff) == 0)
+ if ((len = buflen - auio.uio_resid) <= 0)
goto eof;
+
+ cookiep = cookies;
+
+ if (cookies) {
+ /*
+ * When using cookies, the vfs has the option of reading from
+ * a different offset than that supplied (UFS truncates the
+ * offset to a block boundary to make sure that it never reads
+ * partway through a directory entry, even if the directory
+ * has been compacted).
+ */
+ while (len > 0 && ncookies > 0 && *cookiep <= off) {
+ len -= BSD_DIRENT(inp)->d_reclen;
+ inp += BSD_DIRENT(inp)->d_reclen;
+ cookiep++;
+ ncookies--;
+ }
+ }
+
for (; len > 0 && resid > 0; len -= reclen) {
+ if (cookiep && ncookies == 0)
+ break;
reclen = BSD_DIRENT(inp)->d_reclen;
if (reclen & 3) {
printf("ibcs2_read: reclen=%d\n", reclen);
error = EFAULT;
goto out;
}
- if (BSD_DIRENT(inp)->d_ino == 0) {
+ if (BSD_DIRENT(inp)->d_fileno == 0) {
inp += reclen; /* it is a hole; squish it out */
- off += reclen;
+ if (cookiep) {
+ off = *cookiep++;
+ ncookies--;
+ } else
+ off += reclen;
continue;
}
if (reclen > len || resid < sizeof(struct ibcs2_direct)) {
@@ -515,14 +583,18 @@ again:
* TODO: if length(filename) > 14, then break filename into
* multiple entries and set inode = 0xffff except last
*/
- idb.ino = (BSD_DIRENT(inp)->d_ino > 0xfffe) ? 0xfffe :
- BSD_DIRENT(inp)->d_ino;
+ idb.ino = (BSD_DIRENT(inp)->d_fileno > 0xfffe) ? 0xfffe :
+ BSD_DIRENT(inp)->d_fileno;
(void)copystr(BSD_DIRENT(inp)->d_name, idb.name, 14, &size);
bzero(idb.name + size, 14 - size);
if (error = copyout(&idb, outp, sizeof(struct ibcs2_direct)))
goto out;
/* advance past this real entry */
- off += reclen;
+ if (cookiep) {
+ off = *cookiep++;
+ ncookies--;
+ } else
+ off += reclen;
inp += reclen;
/* advance output past iBCS2-shaped entry */
outp += sizeof(struct ibcs2_direct);
@@ -535,6 +607,8 @@ again:
eof:
*retval = SCARG(uap, nbytes) - resid;
out:
+ if (cookies)
+ free(cookies, M_TEMP);
VOP_UNLOCK(vp);
free(buf, M_TEMP);
return (error);
diff --git a/sys/i386/linux/linux_file.c b/sys/i386/linux/linux_file.c
index bf28b2c552cf..357e587c124b 100644
--- a/sys/i386/linux/linux_file.c
+++ b/sys/i386/linux/linux_file.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: linux_file.c,v 1.6 1996/03/02 19:37:53 peter Exp $
+ * $Id: linux_file.c,v 1.7 1996/03/10 22:27:51 peter Exp $
*/
#include <sys/param.h>
@@ -36,17 +36,12 @@
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
-#include <sys/stat.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
-#include <sys/exec.h>
#include <sys/dirent.h>
-#include <sys/sysproto.h>
#include <sys/conf.h>
#include <sys/tty.h>
-#include <ufs/ufs/dir.h>
-
#include <i386/linux/linux.h>
#include <i386/linux/linux_proto.h>
#include <i386/linux/linux_util.h>
@@ -415,7 +410,9 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
struct vattr va;
off_t off;
struct linux_dirent linux_dirent;
- int buflen, error, eofflag, nbytes, justone, blockoff;
+ int buflen, error, eofflag, nbytes, justone;
+ u_int *cookies = NULL, *cookiep;
+ int ncookies;
#ifdef DEBUG
printf("Linux-emul(%d): getdents(%d, *, %d)\n",
@@ -446,8 +443,8 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
justone = 0;
off = fp->f_offset;
- blockoff = off % DIRBLKSIZ;
- buflen = max(DIRBLKSIZ, nbytes + blockoff);
+#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */
+ buflen = max(DIRBLKSIZ, nbytes);
buflen = min(buflen, MAXBSIZE);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
@@ -460,23 +457,47 @@ again:
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = p;
auio.uio_resid = buflen;
- auio.uio_offset = off - (off_t)blockoff;
+ auio.uio_offset = off;
+
+ if (cookies) {
+ free(cookies, M_TEMP);
+ cookies = NULL;
+ }
- error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (int *) NULL,
- (u_int **) NULL);
+ error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies);
if (error) {
goto out;
}
inp = buf;
- inp += blockoff;
outp = (caddr_t) args->dent;
resid = nbytes;
- if ((len = buflen - auio.uio_resid - blockoff) == 0) {
+ if ((len = buflen - auio.uio_resid) <= 0) {
goto eof;
}
+ cookiep = cookies;
+
+ if (cookies) {
+ /*
+ * When using cookies, the vfs has the option of reading from
+ * a different offset than that supplied (UFS truncates the
+ * offset to a block boundary to make sure that it never reads
+ * partway through a directory entry, even if the directory
+ * has been compacted).
+ */
+ while (len > 0 && ncookies > 0 && *cookiep <= off) {
+ bdp = (struct dirent *) inp;
+ len -= bdp->d_reclen;
+ inp += bdp->d_reclen;
+ cookiep++;
+ ncookies--;
+ }
+ }
+
while (len > 0) {
+ if (cookiep && ncookies == 0)
+ break;
bdp = (struct dirent *) inp;
reclen = bdp->d_reclen;
if (reclen & 3) {
@@ -487,7 +508,11 @@ again:
if (bdp->d_fileno == 0) {
inp += reclen;
- off += reclen;
+ if (cookiep) {
+ off = *cookiep++;
+ ncookies--;
+ } else
+ off += reclen;
len -= reclen;
continue;
}
@@ -512,7 +537,11 @@ again:
goto out;
}
inp += reclen;
- off += reclen;
+ if (cookiep) {
+ off = *cookiep++;
+ ncookies--;
+ } else
+ off += reclen;
outp += linuxreclen;
resid -= linuxreclen;
len -= reclen;
@@ -529,6 +558,8 @@ again:
eof:
*retval = nbytes - resid;
+ if (cookies)
+ free(cookies, M_TEMP);
out:
VOP_UNLOCK(vp);
free(buf, M_TEMP);
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index d45663ad6a37..0563a2fe6d85 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94
- * $Id: vfs_cluster.c,v 1.38 1996/10/06 07:50:04 dyson Exp $
+ * $Id: vfs_cluster.c,v 1.38.2.1 1996/12/15 09:54:11 davidg Exp $
*/
#include <sys/param.h>
@@ -425,7 +425,8 @@ cluster_callback(bp)
if (error) {
tbp->b_flags |= B_ERROR;
tbp->b_error = error;
- }
+ } else
+ tbp->b_dirtyoff = tbp->b_dirtyend = 0;
biodone(tbp);
}
relpbuf(bp);
diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h
index 36e3d5ca2219..c22c9987aed6 100644
--- a/sys/nfs/nfs.h
+++ b/sys/nfs/nfs.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.1 (Berkeley) 6/10/93
- * $Id: nfs.h,v 1.18.2.1 1996/11/09 21:10:44 phk Exp $
+ * $Id: nfs.h,v 1.18.2.2 1997/03/27 20:04:00 guido Exp $
*/
#ifndef _NFS_NFS_H_
@@ -597,6 +597,23 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct proc *procp, struct mbuf **mrq));
+#ifdef NFS_DEBUG
+
+extern int nfs_debug;
+#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */
+#define NFS_DEBUG_WG 2 /* server write gathering */
+#define NFS_DEBUG_RC 4 /* server request caching */
+
+#define NFS_DPF(cat, args) \
+ do { \
+ if (nfs_debug & NFS_DEBUG_##cat) printf args; \
+ } while (0)
+
+#else
+
+#define NFS_DPF(cat, args)
+
+#endif
#endif /* KERNEL */
diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c
index 37a7a00d6c7a..2f86141a87ae 100644
--- a/sys/nfs/nfs_bio.c
+++ b/sys/nfs/nfs_bio.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_bio.c 8.5 (Berkeley) 1/4/94
- * $Id: nfs_bio.c,v 1.28.2.2 1996/11/12 09:09:27 phk Exp $
+ * $Id: nfs_bio.c,v 1.28.2.3 1997/03/04 17:59:41 dfr Exp $
*/
#include <sys/param.h>
@@ -305,6 +305,10 @@ again:
break;
case VDIR:
nfsstats.biocache_readdirs++;
+ if (np->n_direofoffset
+ && uio->uio_offset >= np->n_direofoffset) {
+ return (0);
+ }
lbn = uio->uio_offset / NFS_DIRBLKSIZ;
on = uio->uio_offset & (NFS_DIRBLKSIZ - 1);
bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, p);
@@ -327,6 +331,9 @@ again:
* offset cookies.
*/
for (i = 0; i <= lbn && !error; i++) {
+ if (np->n_direofoffset
+ && (i * NFS_DIRBLKSIZ) >= np->n_direofoffset)
+ return (0);
bp = nfs_getcacheblk(vp, i, NFS_DIRBLKSIZ, p);
if (!bp)
return (EINTR);
@@ -511,6 +518,7 @@ nfs_write(ap)
again:
if (uio->uio_offset + n > np->n_size) {
np->n_size = uio->uio_offset + n;
+ np->n_flag |= NMODIFIED;
vnode_pager_setsize(vp, (u_long)np->n_size);
}
bufsize = biosize;
@@ -756,6 +764,7 @@ again:
nmp->nm_bufqiods++;
wakeup((caddr_t)&nfs_iodwant[i]);
gotiod = TRUE;
+ break;
}
/*
@@ -971,9 +980,12 @@ nfs_doio(bp, cr, p)
iomode = NFSV3WRITE_FILESYNC;
bp->b_flags |= B_WRITEINPROG;
error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
- if (!error && iomode == NFSV3WRITE_UNSTABLE)
- bp->b_flags |= B_NEEDCOMMIT | B_CLUSTEROK;
- else
+ if (!error && iomode == NFSV3WRITE_UNSTABLE) {
+ bp->b_flags |= B_NEEDCOMMIT;
+ if (bp->b_dirtyoff == 0
+ && bp->b_dirtyend == bp->b_bufsize)
+ bp->b_flags |= B_CLUSTEROK;
+ } else
bp->b_flags &= ~B_NEEDCOMMIT;
bp->b_flags &= ~B_WRITEINPROG;
diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c
index be3155ca6477..57472319d038 100644
--- a/sys/nfs/nfs_node.c
+++ b/sys/nfs/nfs_node.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_node.c 8.2 (Berkeley) 12/30/93
- * $Id: nfs_node.c,v 1.12 1995/10/29 15:32:50 phk Exp $
+ * $Id: nfs_node.c,v 1.13 1996/06/12 03:37:46 davidg Exp $
*/
#include <sys/param.h>
@@ -196,11 +196,11 @@ nfs_inactive(ap)
np = VTONFS(ap->a_vp);
if (prtactive && ap->a_vp->v_usecount != 0)
vprint("nfs_inactive: pushing active", ap->a_vp);
- if (ap->a_vp->v_type != VDIR)
+ if (ap->a_vp->v_type != VDIR) {
sp = np->n_sillyrename;
- else
+ np->n_sillyrename = (struct sillyrename *)0;
+ } else
sp = (struct sillyrename *)0;
- np->n_sillyrename = (struct sillyrename *)0;
if (sp) {
/*
* Remove the silly file that was rename'd earlier
diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c
index 9f2010e922e0..4a579e4636e5 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.33 1996/09/05 07:58:04 davidg Exp $
+ * $Id: nfs_serv.c,v 1.34 1996/09/19 18:20:56 nate Exp $
*/
/*
@@ -97,6 +97,7 @@ extern enum vtype nv3tov_type[8];
extern struct nfsstats nfsstats;
int nfsrvw_procrastinate = NFS_GATHERDELAY * 1000;
+int nfsrvw_procrastinate_v3 = 0;
int nfs_async;
SYSCTL_INT(_vfs_nfs, OID_AUTO, async, CTLFLAG_RW, &nfs_async, 0, "");
@@ -930,7 +931,8 @@ nfsrv_writegather(ndp, slp, procp, mrq)
nfsd->nd_mreq = NULL;
nfsd->nd_stable = NFSV3WRITE_FILESYNC;
cur_usec = (u_quad_t)time.tv_sec * 1000000 + (u_quad_t)time.tv_usec;
- nfsd->nd_time = cur_usec + nfsrvw_procrastinate;
+ nfsd->nd_time = cur_usec +
+ (v3 ? nfsrvw_procrastinate_v3 : nfsrvw_procrastinate);
/*
* Now, get the write header..
@@ -1000,6 +1002,7 @@ nfsmout:
owp = wp;
wp = wp->nd_tq.le_next;
}
+ NFS_DPF(WG, ("Q%03x", nfsd->nd_retxid & 0xfff));
if (owp) {
LIST_INSERT_AFTER(owp, nfsd, nd_tq);
} else {
@@ -1051,6 +1054,7 @@ loop1:
break;
if (nfsd->nd_mreq)
continue;
+ NFS_DPF(WG, ("P%03x", nfsd->nd_retxid & 0xfff));
LIST_REMOVE(nfsd, nd_tq);
LIST_REMOVE(nfsd, nd_hash);
splx(s);
@@ -1127,6 +1131,7 @@ loop1:
*/
swp = nfsd;
do {
+ NFS_DPF(WG, ("R%03x", nfsd->nd_retxid & 0xfff));
if (error) {
nfsm_writereply(NFSX_WCCDATA(v3), v3);
if (v3) {
@@ -1186,6 +1191,7 @@ loop1:
s = splsoftclock();
for (nfsd = slp->ns_tq.lh_first; nfsd; nfsd = nfsd->nd_tq.le_next)
if (nfsd->nd_mreq) {
+ NFS_DPF(WG, ("X%03x", nfsd->nd_retxid & 0xfff));
LIST_REMOVE(nfsd, nd_tq);
*mrq = nfsd->nd_mreq;
*ndp = nfsd;
@@ -1210,7 +1216,10 @@ nfsrvw_coalesce(owp, nfsd)
{
register int overlap;
register struct mbuf *mp;
+ struct nfsrv_descript *p;
+ NFS_DPF(WG, ("C%03x-%03x",
+ nfsd->nd_retxid & 0xfff, owp->nd_retxid & 0xfff));
LIST_REMOVE(nfsd, nd_hash);
LIST_REMOVE(nfsd, nd_tq);
if (owp->nd_eoff < nfsd->nd_eoff) {
@@ -1233,6 +1242,16 @@ nfsrvw_coalesce(owp, nfsd)
owp->nd_stable == NFSV3WRITE_UNSTABLE)
owp->nd_stable = NFSV3WRITE_DATASYNC;
LIST_INSERT_HEAD(&owp->nd_coalesce, nfsd, nd_tq);
+
+ /*
+ * If nfsd had anything else coalesced into it, transfer them
+ * to owp, otherwise their replies will never get sent.
+ */
+ for (p = nfsd->nd_coalesce.lh_first; p;
+ p = nfsd->nd_coalesce.lh_first) {
+ LIST_REMOVE(p, nd_tq);
+ LIST_INSERT_HEAD(&owp->nd_coalesce, p, nd_tq);
+ }
}
/*
diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c
index 6cafa8af98ac..93d716a3f8f1 100644
--- a/sys/nfs/nfs_socket.c
+++ b/sys/nfs/nfs_socket.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94
- * $Id: nfs_socket.c,v 1.17 1996/07/11 16:32:45 wollman Exp $
+ * $Id: nfs_socket.c,v 1.18 1996/10/11 10:15:33 dfr Exp $
*/
/*
@@ -270,8 +270,8 @@ nfs_connect(nmp, rep)
so->so_snd.sb_timeo = 0;
}
if (nmp->nm_sotype == SOCK_DGRAM) {
- sndreserve = nmp->nm_wsize + NFS_MAXPKTHDR;
- rcvreserve = nmp->nm_rsize + NFS_MAXPKTHDR;
+ sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * 2;
+ rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR) * 2;
} else if (nmp->nm_sotype == SOCK_SEQPACKET) {
sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * 2;
rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR) * 2;
diff --git a/sys/nfs/nfs_srvcache.c b/sys/nfs/nfs_srvcache.c
index 44aaf83933ad..ae44d4c942fa 100644
--- a/sys/nfs/nfs_srvcache.c
+++ b/sys/nfs/nfs_srvcache.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_srvcache.c 8.1 (Berkeley) 6/10/93
- * $Id: nfs_srvcache.c,v 1.7 1995/12/17 21:12:27 phk Exp $
+ * $Id: nfs_srvcache.c,v 1.8 1996/01/13 23:27:55 phk Exp $
*/
#ifndef NFS_NOSERVER
@@ -184,6 +184,7 @@ loop:
rp = rp->rc_hash.le_next) {
if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nd->nd_nam)) {
+ NFS_DPF(RC, ("H%03x", rp->rc_xid & 0xfff));
if ((rp->rc_flag & RC_LOCKED) != 0) {
rp->rc_flag |= RC_WANTED;
(void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0);
@@ -224,6 +225,7 @@ loop:
}
}
nfsstats.srvcache_misses++;
+ NFS_DPF(RC, ("M%03x", nd->nd_retxid & 0xfff));
if (numnfsrvcache < desirednfsrvcache) {
rp = (struct nfsrvcache *)malloc((u_long)sizeof *rp,
M_NFSD, M_WAITOK);
@@ -289,6 +291,7 @@ loop:
rp = rp->rc_hash.le_next) {
if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nd->nd_nam)) {
+ NFS_DPF(RC, ("U%03x", rp->rc_xid & 0xfff));
if ((rp->rc_flag & RC_LOCKED) != 0) {
rp->rc_flag |= RC_WANTED;
(void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0);
@@ -319,6 +322,7 @@ loop:
return;
}
}
+ NFS_DPF(RC, ("L%03x", nd->nd_retxid & 0xfff));
}
/*
diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c
index 451727e7e0ef..68dbe3b1be0e 100644
--- a/sys/nfs/nfs_syscalls.c
+++ b/sys/nfs/nfs_syscalls.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_syscalls.c,v 1.14.2.2 1996/11/12 09:09:30 phk Exp $
+ * $Id: nfs_syscalls.c,v 1.14.2.3 1997/03/27 20:04:04 guido Exp $
*/
#include <sys/param.h>
@@ -86,6 +86,7 @@ extern int nqsrv_writeslack;
extern int nfsrtton;
extern struct nfsstats nfsstats;
extern int nfsrvw_procrastinate;
+extern int nfsrvw_procrastinate_v3;
struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock;
static int nuidhash_max = NFS_MAXUIDHASH;
@@ -111,6 +112,8 @@ static int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t,struct proc *));
static int nfs_privport = 0;
SYSCTL_INT(_vfs_nfs, NFS_NFSPRIVPORT, nfs_privport, CTLFLAG_RW, &nfs_privport, 0, "");
+SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay, CTLFLAG_RW, &nfsrvw_procrastinate, 0, "");
+SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate_v3, 0, "");
/*
* NFS server system calls
@@ -455,6 +458,7 @@ nfssvc_nfsd(nsd, argp, p)
struct nfsrv_descript *nd = NULL;
struct mbuf *mreq;
int error = 0, cacherep, s, sotype, writes_todo;
+ int procrastinate;
u_quad_t cur_usec;
#ifndef nolint
@@ -606,7 +610,8 @@ nfssvc_nfsd(nsd, argp, p)
sin = mtod(nam, struct sockaddr_in *);
port = ntohs(sin->sin_port);
- if (port >= IPPORT_RESERVED) {
+ if (port >= IPPORT_RESERVED &&
+ nd->nd_procnum != NFSPROC_NULL) {
nd->nd_procnum = NFSPROC_NOOP;
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK);
cacherep = RC_DOIT;
@@ -624,8 +629,12 @@ nfssvc_nfsd(nsd, argp, p)
do {
switch (cacherep) {
case RC_DOIT:
+ if (nd && (nd->nd_flag & ND_NFSV3))
+ procrastinate = nfsrvw_procrastinate_v3;
+ else
+ procrastinate = nfsrvw_procrastinate;
if (writes_todo || (nd->nd_procnum == NFSPROC_WRITE &&
- nfsrvw_procrastinate > 0 && !notstarted))
+ procrastinate > 0 && !notstarted))
error = nfsrv_writegather(&nd, slp,
nfsd->nfsd_procp, &mreq);
else
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c
index 06bb7ba74fc2..767f34f9109a 100644
--- a/sys/nfs/nfs_vfsops.c
+++ b/sys/nfs/nfs_vfsops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_vfsops.c,v 1.30.2.2 1997/05/11 18:01:24 tegge Exp $
+ * $Id: nfs_vfsops.c,v 1.30.2.3 1997/05/12 18:56:19 tegge Exp $
*/
#include <sys/param.h>
@@ -333,12 +333,9 @@ nfs_fsinfo(nmp, vp, cred, p)
}
pref = fxdr_unsigned(u_long, fsp->fs_dtpref);
if (pref < nmp->nm_readdirsize)
- nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
- ~(NFS_DIRBLKSIZ - 1);
+ nmp->nm_readdirsize = pref;
if (max < nmp->nm_readdirsize) {
- nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
- if (nmp->nm_readdirsize == 0)
- nmp->nm_readdirsize = max;
+ nmp->nm_readdirsize = max;
}
nmp->nm_flag |= NFSMNT_GOTFSINFO;
}
@@ -713,13 +710,11 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
nmp->nm_readdirsize = argp->readdirsize;
- /* Round down to multiple of blocksize */
- nmp->nm_readdirsize &= ~(NFS_DIRBLKSIZ - 1);
- if (nmp->nm_readdirsize < NFS_DIRBLKSIZ)
- nmp->nm_readdirsize = NFS_DIRBLKSIZ;
}
if (nmp->nm_readdirsize > maxio)
nmp->nm_readdirsize = maxio;
+ if (nmp->nm_readdirsize > nmp->nm_rsize)
+ nmp->nm_readdirsize = nmp->nm_rsize;
if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 &&
argp->maxgrouplist <= NFS_MAXGRPS)
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index c779a99503f9..5e7aa4c3c061 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
- * $Id: nfs_vnops.c,v 1.36.2.2 1997/01/07 06:18:27 wpaul Exp $
+ * $Id: nfs_vnops.c,v 1.36.2.3 1997/03/04 17:59:42 dfr Exp $
*/
/*
@@ -422,8 +422,49 @@ nfs_access(ap)
}
nfsm_reqdone;
return (error);
- } else
- return (nfsspec_access(ap));
+ } else {
+ if (error = nfsspec_access(ap))
+ return (error);
+
+ /*
+ * Attempt to prevent a mapped root from accessing a file
+ * which it shouldn't. We try to read a byte from the file
+ * if the user is root and the file is not zero length.
+ * After calling nfsspec_access, we should have the correct
+ * file size cached.
+ */
+ if (ap->a_cred->cr_uid == 0 && (ap->a_mode & VREAD)
+ && VTONFS(vp)->n_size > 0) {
+ struct iovec aiov;
+ struct uio auio;
+ char buf[1];
+
+ aiov.iov_base = buf;
+ aiov.iov_len = 1;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ auio.uio_resid = 1;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_rw = UIO_READ;
+ auio.uio_procp = ap->a_p;
+
+ if (vp->v_type == VREG)
+ error = nfs_readrpc(vp, &auio, ap->a_cred);
+ else if (vp->v_type == VDIR) {
+ char* buf;
+ buf = malloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK);
+ aiov.iov_base = buf;
+ aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ;
+ error = nfs_readdirrpc(vp, &auio, ap->a_cred);
+ free(buf, M_TEMP);
+ } else if (vp->v_type = VLNK)
+ error = nfs_readlinkrpc(vp, &auio, ap->a_cred);
+ else
+ error = EACCES;
+ }
+ return (error);
+ }
}
/*
@@ -826,6 +867,7 @@ nfs_lookup(ap)
struct nfsnode *np;
int lockparent, wantparent, error = 0, attrflag, fhsize;
int v3 = NFS_ISV3(dvp);
+ struct proc *p = cnp->cn_proc;
if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
@@ -841,6 +883,9 @@ nfs_lookup(ap)
struct vattr vattr;
int vpid;
+ if (error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, p))
+ return (error);
+
newvp = *vpp;
vpid = newvp->v_id;
/*
diff --git a/sys/nfs/nfsmount.h b/sys/nfs/nfsmount.h
index a1c3b385f8a0..cca2b2db772b 100644
--- a/sys/nfs/nfsmount.h
+++ b/sys/nfs/nfsmount.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfsmount.h 8.1 (Berkeley) 6/10/93
- * $Id: nfsmount.h,v 1.7 1995/12/17 21:12:36 phk Exp $
+ * $Id: nfsmount.h,v 1.7.4.1 1996/11/09 21:11:17 phk Exp $
*/
#ifndef _NFS_NFSMOUNT_H_
@@ -94,22 +94,6 @@ struct nfsmount {
*/
#define VFSTONFS(mp) ((struct nfsmount *)((mp)->mnt_data))
-#ifdef NFS_DEBUG
-
-extern int nfs_debug;
-#define NFS_DEBUG_ASYNCIO 1
-
-#define NFS_DPF(cat, args) \
- do { \
- if (nfs_debug & NFS_DEBUG_##cat) printf args; \
- } while (0)
-
-#else
-
-#define NFS_DPF(cat, args)
-
-#endif
-
#endif /* KERNEL */
#endif