diff options
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/gnu/ext2fs/ext2_lookup.c | 26 | ||||
| -rw-r--r-- | sys/i386/ibcs2/ibcs2_misc.c | 128 | ||||
| -rw-r--r-- | sys/i386/linux/linux_file.c | 63 | ||||
| -rw-r--r-- | sys/kern/vfs_cluster.c | 5 | ||||
| -rw-r--r-- | sys/nfs/nfs.h | 19 | ||||
| -rw-r--r-- | sys/nfs/nfs_bio.c | 20 | ||||
| -rw-r--r-- | sys/nfs/nfs_node.c | 8 | ||||
| -rw-r--r-- | sys/nfs/nfs_serv.c | 23 | ||||
| -rw-r--r-- | sys/nfs/nfs_socket.c | 6 | ||||
| -rw-r--r-- | sys/nfs/nfs_srvcache.c | 6 | ||||
| -rw-r--r-- | sys/nfs/nfs_syscalls.c | 15 | ||||
| -rw-r--r-- | sys/nfs/nfs_vfsops.c | 15 | ||||
| -rw-r--r-- | sys/nfs/nfs_vnops.c | 51 | ||||
| -rw-r--r-- | sys/nfs/nfsmount.h | 18 | 
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 | 
