Skip to content

Commit

Permalink
Revert "vfs/zfs: remove per-file lock enforcement for ZFS read/write …
Browse files Browse the repository at this point in the history
…ops"

This reverts commit b5eadc3. It
introduces a deadlock as outlined in issue #504.

Signed-off-by: Pekka Enberg <[email protected]>
  • Loading branch information
Pekka Enberg committed Oct 1, 2014
1 parent 1545b50 commit 697943f
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 16 deletions.
16 changes: 6 additions & 10 deletions bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,16 +570,15 @@ 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);
Expand Down Expand Up @@ -974,11 +973,8 @@ 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) {
vn_lock(vp);
if (woff + nbytes > zp->z_size)
vnode_pager_setsize(vp, woff + nbytes);
vn_unlock(vp);
}

if (abuf == NULL) {
tx_bytes = uio->uio_resid;
Expand Down
7 changes: 6 additions & 1 deletion core/pagecache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,17 @@ 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;

return VOP_WRITE(_vp, &uio, 0);
vn_lock(_vp);
error = VOP_WRITE(_vp, &uio, 0);
vn_unlock(_vp);

return error;
}
void* release() { // called to demote a page from cache page to anonymous
assert(boost::get<std::nullptr_t>(_ptes) == nullptr);
Expand Down
2 changes: 0 additions & 2 deletions fs/devfs/devfs_vnops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,12 @@ 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);
}

Expand Down
1 change: 0 additions & 1 deletion fs/procfs/procfs_vnops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ static int
procfs_read(vnode* vp, file *fp, uio* uio, int ioflags)
{
auto* data = static_cast<string*>(fp->f_data);
SCOPE_LOCK(vp->v_lock);

if (vp->v_type == VDIR)
return EISDIR;
Expand Down
2 changes: 0 additions & 2 deletions fs/ramfs/ramfs_vnops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ 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;
Expand All @@ -326,7 +325,6 @@ 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;
Expand Down
7 changes: 7 additions & 0 deletions fs/vfs/vfs_fops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ 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;

Expand All @@ -56,6 +57,7 @@ int vfs_file::read(struct uio *uio, int flags)
if ((flags & FOF_OFFSET) == 0)
fp->f_offset += count;
}
vn_unlock(vp);

return error;
}
Expand All @@ -72,6 +74,8 @@ 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))
Expand All @@ -87,6 +91,7 @@ int vfs_file::write(struct uio *uio, int flags)
fp->f_offset += count;
}

vn_unlock(vp);
return error;
}

Expand Down Expand Up @@ -166,7 +171,9 @@ 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;
}
Expand Down

0 comments on commit 697943f

Please sign in to comment.