From: Matthew Dillon Date: Fri, 7 Apr 2006 06:38:33 +0000 (+0000) Subject: Due to continuing issues with VOP_READ/VOP_WRITE ops being called without X-Git-Tag: v2.0.1~5119 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/1c843a13b38e87670f8169e750b2406c3eb6e68e Due to continuing issues with VOP_READ/VOP_WRITE ops being called without a VOP_OPEN, particularly by NFS, redo the way VM objects are associated with vnodes. * The size of the object is now passed to vinitvmio(). vinitvmio() no longer calls VOP_GETATTR(). * Instead of trying to call vinitvmio() conditionally in various places, we now call it unconditionally when a vnode is instantiated if the filesystem at any time in the future intends to use the buffer cache to access that vnode's dataspace. * Specfs 'disk' devices are an exception. Since we cannot safely do I/O on such vnodes if they have not been VOP_OPEN()'ed anyhow, the VM objects for those vnodes are still only associated on open. The performance impact is limited to the case where large numbers of vnodes are being created and destroyed. This case only occurs when a large directory topology (number of files > kernel's vnode cache) is traversed and all related inodes are cached by the system. Being a pure-cpu case the slight loss of performance due to the VM object allocations is not really a big dael. --- diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 5d85f24eec..5058585a48 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -37,7 +37,7 @@ * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_subr.c,v 1.74 2006/04/01 20:46:47 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_subr.c,v 1.75 2006/04/07 06:38:27 dillon Exp $ */ /* @@ -1323,38 +1323,20 @@ vcount(struct vnode *vp) } /* - * Initialize VMIO for a vnode. This routine MUST be called from a VFS's - * VOP_OPEN function for any vnode on which buffer cache access or memory - * mapping will be allowed. + * Initialize VMIO for a vnode. This routine MUST be called before a + * VFS can issue buffer cache ops on a vnode. It is typically called + * when a vnode is initialized from its inode. */ int -vinitvmio(struct vnode *vp) +vinitvmio(struct vnode *vp, off_t filesize) { thread_t td = curthread; - struct vattr vat; vm_object_t object; int error = 0; retry: if ((object = vp->v_object) == NULL) { - if (vp->v_type == VREG || vp->v_type == VDIR) { - if ((error = VOP_GETATTR(vp, &vat, td)) != 0) - goto retn; - object = vnode_pager_alloc(vp, vat.va_size, 0, 0); - } else if (vp->v_type == VLNK) { - object = vnode_pager_alloc(vp, MAXPATHLEN, 0, 0); - } else if (vp->v_rdev && dev_is_good(vp->v_rdev)) { - /* - * XXX v_rdev uses NULL/non-NULL instead of NODEV - * - * This simply allocates the biggest object possible - * for a disk vnode. This should be fixed, but doesn't - * cause any problems (yet). - */ - object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0, 0); - } else { - goto retn; - } + object = vnode_pager_alloc(vp, filesize, 0, 0); /* * Dereference the reference we just created. This assumes * that the object is associated with the vp. diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 57585163fd..d084d5b5b2 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -32,7 +32,7 @@ * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/sys/vnode.h,v 1.46 2006/04/01 20:46:49 dillon Exp $ + * $DragonFly: src/sys/sys/vnode.h,v 1.47 2006/04/07 06:38:29 dillon Exp $ */ #ifndef _SYS_VNODE_H_ @@ -598,7 +598,7 @@ int vtruncbuf (struct vnode *vp, struct thread *td, int vfsync(struct vnode *vp, int waitfor, int passes, off_t loffset, int (*checkdef)(struct buf *), int (*waitoutput)(struct vnode *, struct thread *)); -int vinitvmio(struct vnode *vp); +int vinitvmio(struct vnode *vp, off_t filesize); void vprint (char *label, struct vnode *vp); int vrecycle (struct vnode *vp, struct thread *td); void vn_strategy(struct vnode *vp, struct bio *bio); diff --git a/sys/vfs/gnu/ext2fs/ext2_inode.c b/sys/vfs/gnu/ext2fs/ext2_inode.c index 260e4b7e56..c4927d7d4b 100644 --- a/sys/vfs/gnu/ext2fs/ext2_inode.c +++ b/sys/vfs/gnu/ext2fs/ext2_inode.c @@ -38,7 +38,7 @@ * * @(#)ext2_inode.c 8.5 (Berkeley) 12/30/93 * $FreeBSD: src/sys/gnu/ext2fs/ext2_inode.c,v 1.24.2.1 2000/08/03 00:52:57 peter Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_inode.c,v 1.14 2006/04/05 21:06:22 dillon Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_inode.c,v 1.15 2006/04/07 06:38:30 dillon Exp $ */ #include "opt_quota.h" @@ -163,14 +163,6 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length); if ((error = ext2_getinoquota(oip)) != 0) return (error); #endif - /* - * truncation can occur for a variety of reasons where an OPEN has - * not been performed. truncate(), rmdir(), and remove() being - * examples. Vnode-based buffer cache ops require a VM object. - */ - if (vp->v_object == NULL) - vinitvmio(vp); - fs = oip->i_e2fs; osize = oip->i_size; ext2_discard_prealloc(oip); diff --git a/sys/vfs/gnu/ext2fs/ext2_vnops.c b/sys/vfs/gnu/ext2fs/ext2_vnops.c index bbe3962b14..38ca528a24 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vnops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vnops.c @@ -44,7 +44,7 @@ * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 * @(#)ext2_vnops.c 8.7 (Berkeley) 2/3/94 * $FreeBSD: src/sys/gnu/ext2fs/ext2_vnops.c,v 1.51.2.2 2003/01/02 17:26:18 bde Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vnops.c,v 1.28 2006/04/06 17:04:30 swildner Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vnops.c,v 1.29 2006/04/07 06:38:30 dillon Exp $ */ #include "opt_quota.h" @@ -942,7 +942,7 @@ ext2_mkdir(struct vop_old_mkdir_args *ap) * The vnode must have a VM object in order to issue buffer cache * ops on it. */ - vinitvmio(tvp); + vinitvmio(tvp, 0); /* * Bump link count in parent directory @@ -1105,7 +1105,7 @@ ext2_symlink(struct vop_old_symlink_args *ap) * the buffer cache. */ if (vp->v_object == NULL) - vinitvmio(vp); + vinitvmio(vp, 0); error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0, @@ -1205,6 +1205,13 @@ ext2_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, if (cnp->cn_flags & CNP_ISWHITEOUT) ip->i_flags |= UF_OPAQUE; + /* + * Regular files and directories need VM objects. Softlinks do + * not (not immediately anyway). + */ + if (tvp->v_type == VREG || tvp->v_type == VDIR) + vinitvmio(tvp, 0); + /* * Make sure inode goes to disk before directory entry. */ @@ -1309,13 +1316,6 @@ ext2_open(struct vop_open_args *ap) (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE) { return (EPERM); } - - /* - * The buffer cache is used for VREG and VDIR files - */ - if (vp->v_type == VREG || vp->v_type == VDIR) - vinitvmio(vp); - return (vop_stdopen(ap)); } @@ -1760,13 +1760,6 @@ ext2_readlink(struct vop_readlink_args *ap) uiomove((char *)ip->i_shortlink, isize, ap->a_uio); return (0); } - - /* - * Perform the equivalent of an OPEN on vp so we can issue a - * VOP_READ. - */ - if (vp->v_object == NULL) - vinitvmio(vp); return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred)); } @@ -2063,7 +2056,15 @@ ext2_vinit(struct mount *mntp, struct vnode **vpp) vp->v_ops = &mntp->mnt_vn_fifo_ops; break; case VDIR: - vinitvmio(vp); + case VREG: + vinitvmio(vp, ip->i_size); + break; + case VLNK: + if ((ip->i_size >= vp->v_mount->mnt_maxsymlinklen) && + ip->i_din.di_blocks != 0 + ) { + vinitvmio(vp, ip->i_size); + } break; default: break; diff --git a/sys/vfs/isofs/cd9660/cd9660_lookup.c b/sys/vfs/isofs/cd9660/cd9660_lookup.c index aa96e2d07e..962437b8e7 100644 --- a/sys/vfs/isofs/cd9660/cd9660_lookup.c +++ b/sys/vfs/isofs/cd9660/cd9660_lookup.c @@ -39,7 +39,7 @@ * * @(#)cd9660_lookup.c 8.2 (Berkeley) 1/23/94 * $FreeBSD: src/sys/isofs/cd9660/cd9660_lookup.c,v 1.23.2.2 2001/11/04 06:19:47 dillon Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_lookup.c,v 1.20 2006/04/01 21:55:13 dillon Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_lookup.c,v 1.21 2006/04/07 06:38:31 dillon Exp $ */ #include @@ -131,11 +131,6 @@ cd9660_lookup(struct vop_old_lookup_args *ap) wantparent = flags & (CNP_LOCKPARENT | CNP_WANTPARENT); cnp->cn_flags &= ~CNP_PDIRUNLOCK; - /* - * We use the buffer cache on the directory vnode - */ - vinitvmio(vdp); - /* * We now have a segment name to search for, and a directory to search. */ diff --git a/sys/vfs/isofs/cd9660/cd9660_vfsops.c b/sys/vfs/isofs/cd9660/cd9660_vfsops.c index fab78ece26..fe88b06774 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vfsops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vfsops.c @@ -37,7 +37,7 @@ * * @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95 * $FreeBSD: src/sys/isofs/cd9660/cd9660_vfsops.c,v 1.74.2.7 2002/04/08 09:39:29 bde Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.32 2006/04/01 21:55:13 dillon Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.33 2006/04/07 06:38:31 dillon Exp $ */ #include @@ -853,6 +853,10 @@ again: vp->v_ops = &mp->mnt_vn_spec_ops; addaliasu(vp, ip->inode.iso_rdev); break; + case VREG: + case VDIR: + vinitvmio(vp, ip->i_size); + break; default: break; } diff --git a/sys/vfs/isofs/cd9660/cd9660_vnops.c b/sys/vfs/isofs/cd9660/cd9660_vnops.c index 7273b2a97b..dec49ca0e5 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vnops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vnops.c @@ -37,7 +37,7 @@ * * @(#)cd9660_vnops.c 8.19 (Berkeley) 5/27/95 * $FreeBSD: src/sys/isofs/cd9660/cd9660_vnops.c,v 1.62 1999/12/15 23:01:51 eivind Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.23 2006/04/01 21:55:13 dillon Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.24 2006/04/07 06:38:31 dillon Exp $ */ #include @@ -277,13 +277,6 @@ cd9660_ioctl(struct vop_ioctl_args *ap) static int cd9660_open(struct vop_open_args *ap) { - struct vnode *vp = ap->a_vp; - - /* - * Both regular file and directory operations use the buffer cache. - */ - if (vp->v_type == VREG || vp->v_type == VDIR) - vinitvmio(vp); return(vop_stdopen(ap)); } diff --git a/sys/vfs/msdosfs/msdosfs_denode.c b/sys/vfs/msdosfs/msdosfs_denode.c index b51f83211a..880bdc9edd 100644 --- a/sys/vfs/msdosfs/msdosfs_denode.c +++ b/sys/vfs/msdosfs/msdosfs_denode.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/msdosfs_denode.c,v 1.47.2.3 2002/08/22 16:20:15 trhodes Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_denode.c,v 1.22 2006/03/24 22:39:22 dillon Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_denode.c,v 1.23 2006/04/07 06:38:32 dillon Exp $ */ /* $NetBSD: msdosfs_denode.c,v 1.28 1998/02/10 14:10:00 mrg Exp $ */ /*- @@ -419,6 +419,7 @@ again: SETLOW(ldep->de_modrev, tv.tv_usec * 4294); ldep->de_devvp = pmp->pm_devvp; vref(ldep->de_devvp); + vinitvmio(nvp, ldep->de_FileSize); /* * Leave nvp locked and refd so the returned inode is effectively * locked and refd. diff --git a/sys/vfs/msdosfs/msdosfs_vnops.c b/sys/vfs/msdosfs/msdosfs_vnops.c index 362ea28d1c..b9fbb50b41 100644 --- a/sys/vfs/msdosfs/msdosfs_vnops.c +++ b/sys/vfs/msdosfs/msdosfs_vnops.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/msdosfs_vnops.c,v 1.95.2.4 2003/06/13 15:05:47 trhodes Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.33 2006/04/01 20:46:53 dillon Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.34 2006/04/07 06:38:32 dillon Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */ /*- @@ -216,10 +216,6 @@ msdosfs_mknod(struct vop_old_mknod_args *ap) static int msdosfs_open(struct vop_open_args *ap) { - struct vnode *vp = ap->a_vp; - - if (vp->v_type == VREG || vp->v_type == VDIR) - vinitvmio(vp); return(vop_stdopen(ap)); } diff --git a/sys/vfs/nfs/nfs_serv.c b/sys/vfs/nfs/nfs_serv.c index 7337208209..02766620ee 100644 --- a/sys/vfs/nfs/nfs_serv.c +++ b/sys/vfs/nfs/nfs_serv.c @@ -35,7 +35,7 @@ * * @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95 * $FreeBSD: src/sys/nfs/nfs_serv.c,v 1.93.2.6 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.31 2006/03/29 18:45:00 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.32 2006/04/07 06:38:33 dillon Exp $ */ /* @@ -1665,8 +1665,6 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; error = VOP_NCREATE(nd.nl_ncp, &vp, nd.nl_cred, vap); if (error == 0) { - if (vap->va_type == VREG) - vinitvmio(vp); if (exclusive_flag) { exclusive_flag = 0; VATTR_NULL(vap); diff --git a/sys/vfs/nfs/nfs_subs.c b/sys/vfs/nfs/nfs_subs.c index 7544fe3279..b61a3f1a2f 100644 --- a/sys/vfs/nfs/nfs_subs.c +++ b/sys/vfs/nfs/nfs_subs.c @@ -35,7 +35,7 @@ * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_subs.c,v 1.128 2004/04/14 23:23:55 peadar Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.36 2006/03/29 18:45:00 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.37 2006/04/07 06:38:33 dillon Exp $ */ /* @@ -1184,7 +1184,7 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, */ np = VTONFS(vp); if (vp->v_type != vtyp) { - vp->v_type = vtyp; + nfs_setvtype(vp, vtyp); if (vp->v_type == VFIFO) { vp->v_ops = &vp->v_mount->mnt_vn_fifo_ops; } else if (vp->v_type == VCHR || vp->v_type == VBLK) { @@ -1864,9 +1864,6 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, else *rdonlyp = 0; - if ((*vpp)->v_type == VREG && (*vpp)->v_object) - vinitvmio(*vpp); - if (!lockflag) VOP_UNLOCK(*vpp, 0, td); return (0); @@ -1992,6 +1989,26 @@ nfs_invaldir(struct vnode *vp) np->n_cookies.lh_first->ndm_eocookie = 0; } +/* + * Set the v_type field for an NFS client's vnode and initialize for + * buffer cache operations if necessary. + */ +void +nfs_setvtype(struct vnode *vp, enum vtype vtyp) +{ + vp->v_type = vtyp; + + switch(vtyp) { + case VREG: + case VDIR: + case VLNK: + vinitvmio(vp, 0); /* needs VMIO, size not yet known */ + break; + default: + break; + } +} + /* * The write verifier has changed (probably due to a server reboot), so all * B_NEEDCOMMIT blocks will have to be written again. Since they are on the diff --git a/sys/vfs/nfs/nfs_vfsops.c b/sys/vfs/nfs/nfs_vfsops.c index a03b1bae61..05fce3c71f 100644 --- a/sys/vfs/nfs/nfs_vfsops.c +++ b/sys/vfs/nfs/nfs_vfsops.c @@ -35,7 +35,7 @@ * * @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95 * $FreeBSD: src/sys/nfs/nfs_vfsops.c,v 1.91.2.7 2003/01/27 20:04:08 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_vfsops.c,v 1.37 2006/03/27 17:01:18 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_vfsops.c,v 1.38 2006/04/07 06:38:33 dillon Exp $ */ #include "opt_bootp.h" @@ -574,9 +574,9 @@ nfs_mountroot(mp) * Since the swap file is not the root dir of a file system, * hack it to a regular file. */ - vp->v_type = VREG; vp->v_flag = 0; vref(vp); + nfs_setvtype(vp, VREG); swaponvp(td, vp, nd->swap_nblks); } @@ -1102,7 +1102,7 @@ nfs_root(mp, vpp) } } if (vp->v_type == VNON) - vp->v_type = VDIR; + nfs_setvtype(vp, VDIR); vp->v_flag = VROOT; *vpp = vp; return (0); diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index 3d44d336b8..71afc389da 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -35,7 +35,7 @@ * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.54 2006/04/01 20:46:53 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.55 2006/04/07 06:38:33 dillon Exp $ */ @@ -485,14 +485,6 @@ nfs_open(struct vop_open_args *ap) return (EOPNOTSUPP); } - /* - * Regular files are mmapable and we use the buffer cache. We also - * use the buffer cache for directories internally, so those - * vnodes need a VM object. - */ - if (vp->v_type == VREG || vp->v_type == VDIR) - vinitvmio(vp); - /* * Clear the attribute cache only if opening with write access. It * is unclear if we should do this at all here, but we certainly @@ -1157,8 +1149,6 @@ nfs_readlink(struct vop_readlink_args *ap) if (vp->v_type != VLNK) return (EINVAL); - if (vp->v_object == NULL) - vinitvmio(vp); return (nfs_bioread(vp, ap->a_uio, 0)); } diff --git a/sys/vfs/nfs/nfsmount.h b/sys/vfs/nfs/nfsmount.h index 2f124d633c..12888da6a9 100644 --- a/sys/vfs/nfs/nfsmount.h +++ b/sys/vfs/nfs/nfsmount.h @@ -35,7 +35,7 @@ * * @(#)nfsmount.h 8.3 (Berkeley) 3/30/95 * $FreeBSD: src/sys/nfs/nfsmount.h,v 1.17 1999/12/29 04:54:54 peter Exp $ - * $DragonFly: src/sys/vfs/nfs/nfsmount.h,v 1.7 2006/03/27 16:18:39 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfsmount.h,v 1.8 2006/04/07 06:38:33 dillon Exp $ */ @@ -103,6 +103,7 @@ struct nfsmount { */ #define VFSTONFS(mp) ((struct nfsmount *)((mp)->mnt_data)) extern void nfs_free_mount(struct nfsmount *nmp); +extern void nfs_setvtype(struct vnode *, enum vtype); #endif diff --git a/sys/vfs/ntfs/ntfs_vnops.c b/sys/vfs/ntfs/ntfs_vnops.c index c172d240bc..ff64f61d76 100644 --- a/sys/vfs/ntfs/ntfs_vnops.c +++ b/sys/vfs/ntfs/ntfs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/ntfs/ntfs_vnops.c,v 1.9.2.4 2002/08/06 19:35:18 semenu Exp $ - * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.28 2006/04/01 20:46:53 dillon Exp $ + * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.29 2006/04/07 06:38:33 dillon Exp $ * */ @@ -519,24 +519,6 @@ ntfs_access(struct vop_access_args *ap) static int ntfs_open(struct vop_open_args *ap) { - struct vnode *vp = ap->a_vp; -#if NTFS_DEBUG - struct ntnode *ip = VTONT(vp); - - printf("ntfs_open: %d\n",ip->i_number); -#endif - - /* - * We use the buffer cache, so files at least have to have a - * VM object. - */ - if (vp->v_type == VREG || vp->v_type == VDIR) - vinitvmio(vp); - - /* - * Files marked append-only must be opened for appending. - */ - return (vop_stdopen(ap)); } diff --git a/sys/vfs/specfs/spec_vnops.c b/sys/vfs/specfs/spec_vnops.c index 9330c4c867..3076102d40 100644 --- a/sys/vfs/specfs/spec_vnops.c +++ b/sys/vfs/specfs/spec_vnops.c @@ -32,7 +32,7 @@ * * @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95 * $FreeBSD: src/sys/miscfs/specfs/spec_vnops.c,v 1.131.2.4 2001/02/26 04:23:20 jlemon Exp $ - * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.34 2006/04/01 20:46:53 dillon Exp $ + * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.35 2006/04/07 06:38:33 dillon Exp $ */ #include @@ -54,6 +54,8 @@ #include #include +#include + #include #include @@ -263,7 +265,7 @@ spec_open(struct vop_open_args *ap) if (vn_isdisk(vp, NULL)) { if (!dev->si_bsize_phys) dev->si_bsize_phys = DEV_BSIZE; - vinitvmio(vp); + vinitvmio(vp, IDX_TO_OFF(INT_MAX)); } if ((dev_dflags(dev) & D_DISK) == 0) { cp = devtoname(dev); diff --git a/sys/vfs/ufs/ffs_inode.c b/sys/vfs/ufs/ffs_inode.c index ac06389fab..788cc56bdd 100644 --- a/sys/vfs/ufs/ffs_inode.c +++ b/sys/vfs/ufs/ffs_inode.c @@ -32,7 +32,7 @@ * * @(#)ffs_inode.c 8.13 (Berkeley) 4/21/95 * $FreeBSD: src/sys/ufs/ffs/ffs_inode.c,v 1.56.2.5 2002/02/05 18:35:03 dillon Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_inode.c,v 1.18 2006/04/03 02:02:37 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_inode.c,v 1.19 2006/04/07 06:38:33 dillon Exp $ */ #include "opt_quota.h" @@ -174,13 +174,6 @@ ffs_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, if (error) return (error); #endif - /* - * truncation can occur for a variety of reasons where an OPEN has - * not been performed. truncate(), rmdir(), and remove() being - * examples. Vnode-based buffer cache ops require a VM object. - */ - if (vp->v_object == NULL) - vinitvmio(vp); ovp->v_lasta = ovp->v_clen = ovp->v_cstart = ovp->v_lastw = 0; if (DOINGSOFTDEP(ovp)) { if (length > 0 || softdep_slowdown(ovp)) { diff --git a/sys/vfs/ufs/ufs_vnops.c b/sys/vfs/ufs/ufs_vnops.c index 1eff9f2ad8..68c2776d50 100644 --- a/sys/vfs/ufs/ufs_vnops.c +++ b/sys/vfs/ufs/ufs_vnops.c @@ -37,7 +37,7 @@ * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $ - * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.41 2006/04/05 20:22:30 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.42 2006/04/07 06:38:33 dillon Exp $ */ #include "opt_quota.h" @@ -273,12 +273,6 @@ ufs_open(struct vop_open_args *ap) return (EPERM); } - /* - * The buffer cache is used for VREG and VDIR files - */ - if (vp->v_type == VREG || vp->v_type == VDIR) - vinitvmio(vp); - return (vop_stdopen(ap)); } @@ -1423,7 +1417,7 @@ ufs_mkdir(struct vop_old_mkdir_args *ap) * The vnode must have a VM object in order to issue buffer cache * ops on it. */ - vinitvmio(tvp); + vinitvmio(tvp, DIRBLKSIZ); /* * Initialize directory with "." and ".." from static template. @@ -1632,7 +1626,7 @@ ufs_symlink(struct vop_old_symlink_args *ap) * the buffer cache. */ if (vp->v_object == NULL) - vinitvmio(vp); + vinitvmio(vp, 0); error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, NULL, NULL); @@ -1774,8 +1768,6 @@ ufs_readlink(struct vop_readlink_args *ap) * Perform the equivalent of an OPEN on vp so we can issue a * VOP_READ. */ - if (vp->v_object == NULL) - vinitvmio(vp); return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred)); } @@ -2066,7 +2058,9 @@ ufs_vinit(struct mount *mntp, struct vnode **vpp) vp = *vpp; ip = VTOI(vp); - switch(vp->v_type = IFTOVT(ip->i_mode)) { + vp->v_type = IFTOVT(ip->i_mode); + + switch(vp->v_type) { case VCHR: case VBLK: vp->v_ops = &mntp->mnt_vn_spec_ops; @@ -2076,7 +2070,12 @@ ufs_vinit(struct mount *mntp, struct vnode **vpp) vp->v_ops = &mntp->mnt_vn_fifo_ops; break; case VDIR: - vinitvmio(vp); + case VREG: + vinitvmio(vp, ip->i_size); + break; + case VLNK: + if (ip->i_size >= vp->v_mount->mnt_maxsymlinklen) + vinitvmio(vp, ip->i_size); break; default: break; @@ -2188,6 +2187,13 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, if (cnp->cn_flags & CNP_ISWHITEOUT) ip->i_flags |= UF_OPAQUE; + /* + * Regular files and directories need VM objects. Softlinks do + * not (not immediately anyway). + */ + if (tvp->v_type == VREG || tvp->v_type == VDIR) + vinitvmio(tvp, 0); + /* * Make sure inode goes to disk before directory entry. */