diff --git a/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 7acbe64cbb..c8302e3631 100644 --- a/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -565,15 +565,16 @@ zfs_read(vnode_t *vp, struct file* fp, uio_t *uio, int ioflag) xuio_t *xuio = NULL; #endif - // Return EISDIR when reading from a directory, as Linux does. - if (vp->v_type == VDIR) { - return EISDIR; - } - ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); os = zfsvfs->z_os; + // Return EISDIR when reading from a directory, as Linux does. + if (S_ISDIR(zp->z_mode)) { + ZFS_EXIT(zfsvfs); + return EISDIR; + } + if (zp->z_pflags & ZFS_AV_QUARANTINED) { ZFS_EXIT(zfsvfs); return (EACCES); @@ -958,8 +959,11 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag) */ nbytes = MIN(n, max_blksz - P2PHASE(woff, max_blksz)); - if (woff + nbytes > zp->z_size) + if (woff + nbytes > zp->z_size) { + vn_lock(vp); vnode_pager_setsize(vp, woff + nbytes); + vn_unlock(vp); + } if (abuf == NULL) { tx_bytes = uio->uio_resid; diff --git a/core/pagecache.cc b/core/pagecache.cc index 81b7a4710d..64259fe0df 100644 --- a/core/pagecache.cc +++ b/core/pagecache.cc @@ -204,17 +204,12 @@ class cached_page_write : public cached_page { } int writeback() { - int error; struct iovec iov {_page, mmu::page_size}; struct uio uio {&iov, 1, _key.offset, mmu::page_size, UIO_WRITE}; _dirty = false; - vn_lock(_vp); - error = VOP_WRITE(_vp, &uio, 0); - vn_unlock(_vp); - - return error; + return VOP_WRITE(_vp, &uio, 0); } void* release() { // called to demote a page from cache page to anonymous assert(boost::get(_ptes) == nullptr); diff --git a/fs/devfs/devfs_vnops.cc b/fs/devfs/devfs_vnops.cc index 3ad28a5630..0a88c65098 100644 --- a/fs/devfs/devfs_vnops.cc +++ b/fs/devfs/devfs_vnops.cc @@ -104,12 +104,14 @@ devfs_close(struct vnode *vp, struct file *fp) static int devfs_read(struct vnode *vp, struct file *fp, struct uio *uio, int ioflags) { + SCOPE_LOCK(vp->v_lock); return device_read((device*)vp->v_data, uio, ioflags); } static int devfs_write(struct vnode *vp, struct uio *uio, int ioflags) { + SCOPE_LOCK(vp->v_lock); return device_write((device*)vp->v_data, uio, ioflags); } diff --git a/fs/procfs/procfs_vnops.cc b/fs/procfs/procfs_vnops.cc index 267048fe9e..8fb39aab13 100644 --- a/fs/procfs/procfs_vnops.cc +++ b/fs/procfs/procfs_vnops.cc @@ -147,6 +147,7 @@ static int procfs_read(vnode* vp, file *fp, uio* uio, int ioflags) { auto* data = static_cast(fp->f_data); + SCOPE_LOCK(vp->v_lock); if (vp->v_type == VDIR) return EISDIR; diff --git a/fs/ramfs/ramfs_vnops.cc b/fs/ramfs/ramfs_vnops.cc index 5509d965c8..4c51e56b79 100644 --- a/fs/ramfs/ramfs_vnops.cc +++ b/fs/ramfs/ramfs_vnops.cc @@ -299,6 +299,7 @@ ramfs_read(struct vnode *vp, struct file *fp, struct uio *uio, int ioflag) { struct ramfs_node *np = (ramfs_node*)vp->v_data; size_t len; + SCOPE_LOCK(vp->v_lock); if (vp->v_type == VDIR) return EISDIR; @@ -325,6 +326,7 @@ static int ramfs_write(struct vnode *vp, struct uio *uio, int ioflag) { struct ramfs_node *np = (ramfs_node*)vp->v_data; + SCOPE_LOCK(vp->v_lock); if (vp->v_type == VDIR) return EISDIR; diff --git a/fs/vfs/vfs_fops.cc b/fs/vfs/vfs_fops.cc index 54a8192104..b4416c1ae7 100644 --- a/fs/vfs/vfs_fops.cc +++ b/fs/vfs/vfs_fops.cc @@ -47,7 +47,6 @@ int vfs_file::read(struct uio *uio, int flags) bytes = uio->uio_resid; - vn_lock(vp); if ((flags & FOF_OFFSET) == 0) uio->uio_offset = fp->f_offset; @@ -57,7 +56,6 @@ int vfs_file::read(struct uio *uio, int flags) if ((flags & FOF_OFFSET) == 0) fp->f_offset += count; } - vn_unlock(vp); return error; } @@ -74,8 +72,6 @@ int vfs_file::write(struct uio *uio, int flags) bytes = uio->uio_resid; - vn_lock(vp); - if (fp->f_flags & O_APPEND) ioflags |= IO_APPEND; if (fp->f_flags & (O_DSYNC|O_SYNC)) @@ -91,7 +87,6 @@ int vfs_file::write(struct uio *uio, int flags) fp->f_offset += count; } - vn_unlock(vp); return error; } @@ -171,9 +166,7 @@ int vfs_file::get_arcbuf(void* key, off_t offset) data.uio_resid = mmu::page_size; data.uio_rw = UIO_READ; - vn_lock(vp); assert(VOP_CACHE(vp, this, &data) == 0); - vn_unlock(vp); return (data.uio_resid != 0) ? -1 : 0; }