Index: nfsclient/nfs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/nfsclient/nfs_vfsops.c,v retrieving revision 1.139 diff -u -r1.139 nfs_vfsops.c --- nfsclient/nfs_vfsops.c 5 Oct 2003 06:47:56 -0000 1.139 +++ nfsclient/nfs_vfsops.c 24 Oct 2003 18:34:35 -0000 @@ -94,7 +94,14 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, ""); #endif -static int nfs_iosize(struct nfsmount *nmp); +/* + * Tunable to determine the Read/Write unit size. Maximum + * value is NFS_MAXDATA (default). + */ +static int nfs_io_size = NFS_MAXDATA; +SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_io_size, CTLFLAG_RW, &nfs_io_size, 0, + "NFS optimal I/O unit size"); + static void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp); static int mountnfs(struct nfs_args *, struct mount *, struct sockaddr *, char *, char *, struct vnode **, @@ -150,7 +157,7 @@ static void nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs); -static int +static __inline int nfs_iosize(struct nfsmount *nmp) { int iosize; @@ -161,8 +168,21 @@ * that it is at least one VM page to avoid wasting buffer * space. */ - iosize = max(nmp->nm_rsize, nmp->nm_wsize); - if (iosize < PAGE_SIZE) iosize = PAGE_SIZE; + + /* + * Also make sure that nfs_io_size does not exceeed + * NFS_MAXDATA. No point having a SYSCTL_PROC() as it + * adds lot of unwanted overhead. + */ + if (nfs_io_size > NFS_MAXDATA) + iosize = NFS_MAXDATA; + else + iosize = nfs_io_size; + + /* iosize = max(nmp->nm_rsize, nmp->nm_wsize); */ + if (nfs_io_size < PAGE_SIZE) + iosize = PAGE_SIZE; + return iosize; } @@ -251,6 +271,14 @@ sbp->f_flags = nmp->nm_flag; sbp->f_iosize = nfs_iosize(nmp); if (v3) { + if (nmp->nm_sotype == SOCK_STREAM) + sbp->f_iosize = nfs_iosize(nmp); + else + sbp->f_iosize = NFS_MAXDGRAMDATA; + } else + sbp->f_iosize = NFS_V2MAXDATA; + + if (v3) { for (bsize = NFS_FABLKSIZE; ; bsize *= 2) { sbp->f_bsize = bsize; tquad = fxdr_hyper(&sfp->sf_tbytes); @@ -568,7 +596,7 @@ if (argp->sotype == SOCK_DGRAM) maxio = NFS_MAXDGRAMDATA; else - maxio = NFS_MAXDATA; + maxio = nfs_iosize(nmp); /* SOCK_STREAM case */ } else maxio = NFS_V2MAXDATA; @@ -759,7 +787,6 @@ struct nfsmount *nmp; struct nfsnode *np; int error; - struct vattr attrs; if (mp->mnt_flag & MNT_UPDATE) { nmp = VFSTONFS(mp); @@ -792,8 +819,16 @@ nmp->nm_timeo = NFS_TIMEO; nmp->nm_retry = NFS_RETRANS; - nmp->nm_wsize = NFS_WSIZE; - nmp->nm_rsize = NFS_RSIZE; + if (argp->flags & NFSMNT_NFSV3) { + if (argp->sotype == SOCK_STREAM) { + nmp->nm_wsize = nmp->nm_rsize = nfs_iosize(nmp); + } else { + nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDGRAMDATA; + } + } else { + nmp->nm_wsize = NFS_WSIZE; + nmp->nm_rsize = NFS_RSIZE; + } nmp->nm_readdirsize = NFS_READDIRSIZE; nmp->nm_numgrps = NFS_MAXGRPS; nmp->nm_readahead = NFS_DEFRAHEAD; @@ -835,13 +870,18 @@ error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np); if (error) goto bad; - *vpp = NFSTOV(np); /* - * Get file attributes for the mountpoint. This has the side - * effect of filling in (*vpp)->v_type with the correct value. + * Retrieval of mountpoint attributes is delayed until nfs_rot + * or nfs_statfs are first called. This will happen either when + * we first traverse the mount point or if somebody does a df(1). + * + * NFSSTA_GOTFSINFO is used to flag if we have successfully + * retreived mountpoint attributes. In the case of NFSv3 we + * also flag static fsinfo. */ - VOP_GETATTR(*vpp, &attrs, curthread->td_ucred, curthread); + if (*vpp != NULL) + (*vpp)->v_type = VNON; /* * Lose the lock but keep the ref. @@ -911,6 +951,23 @@ if (error) return (error); vp = NFSTOV(np); + /* + * Get transfer parameters and root vnode attributes. + */ + if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { + if (nmp->nm_flag & NFSMNT_NFSV3) { + nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread); + if (nmp->nm_sotype == SOCK_STREAM) + mp->mnt_stat.f_iosize = nfs_iosize(nmp); + else + mp->mnt_stat.f_iosize = NFS_MAXDGRAMDATA; + } else { + struct vattr attrs; + error = VOP_GETATTR(vp, &attrs, curthread->td_ucred, curthread); + if (!error) + nmp->nm_state |= NFSSTA_GOTFSINFO; + } + } if (vp->v_type == VNON) vp->v_type = VDIR; vp->v_vflag |= VV_ROOT;