Due to continuing issues with VOP_READ/VOP_WRITE ops being called without
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 7 Apr 2006 06:38:33 +0000 (06:38 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 7 Apr 2006 06:38:33 +0000 (06:38 +0000)
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.

18 files changed:
sys/kern/vfs_subr.c
sys/sys/vnode.h
sys/vfs/gnu/ext2fs/ext2_inode.c
sys/vfs/gnu/ext2fs/ext2_vnops.c
sys/vfs/isofs/cd9660/cd9660_lookup.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/isofs/cd9660/cd9660_vnops.c
sys/vfs/msdosfs/msdosfs_denode.c
sys/vfs/msdosfs/msdosfs_vnops.c
sys/vfs/nfs/nfs_serv.c
sys/vfs/nfs/nfs_subs.c
sys/vfs/nfs/nfs_vfsops.c
sys/vfs/nfs/nfs_vnops.c
sys/vfs/nfs/nfsmount.h
sys/vfs/ntfs/ntfs_vnops.c
sys/vfs/specfs/spec_vnops.c
sys/vfs/ufs/ffs_inode.c
sys/vfs/ufs/ufs_vnops.c

index 5d85f24..5058585 100644 (file)
@@ -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.
index 5758516..d084d5b 100644 (file)
@@ -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);
index 260e4b7..c4927d7 100644 (file)
@@ -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);
index bbe3962..38ca528 100644 (file)
@@ -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;
index aa96e2d..962437b 100644 (file)
@@ -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 <sys/param.h>
@@ -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.
         */
index fab78ec..fe88b06 100644 (file)
@@ -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 <sys/param.h>
@@ -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;
        }
index 7273b2a..dec49ca 100644 (file)
@@ -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 <sys/param.h>
@@ -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));
 }
 
index b51f832..880bdc9 100644 (file)
@@ -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.
index 362ea28..b9fbb50 100644 (file)
@@ -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));
 }
 
index 7337208..0276662 100644 (file)
@@ -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);
index 7544fe3..b61a3f1 100644 (file)
@@ -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
index a03b1ba..05fce3c 100644 (file)
@@ -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);
index 3d44d33..71afc38 100644 (file)
@@ -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));
 }
 
index 2f124d6..12888da 100644 (file)
@@ -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
 
index c172d24..ff64f61 100644 (file)
@@ -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));
 }
 
index 9330c4c..3076102 100644 (file)
@@ -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 <sys/param.h>
@@ -54,6 +54,8 @@
 #include <vm/vm_page.h>
 #include <vm/vm_pager.h>
 
+#include <machine/limits.h>
+
 #include <sys/buf2.h>
 
 #include <sys/thread2.h>
@@ -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);
index ac06389..788cc56 100644 (file)
@@ -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)) {
index 1eff9f2..68c2776 100644 (file)
@@ -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.
         */