]> git.hungrycats.org Git - linux/commitdiff
[XFS] Fix use of AIO wait_on_sync_kiocb and a deadlock in O_SYNC
authorChristoph Hellwig <hch@sgi.com>
Mon, 6 Sep 2004 19:49:04 +0000 (05:49 +1000)
committerChristoph Hellwig <hch@sgi.com>
Mon, 6 Sep 2004 19:49:04 +0000 (05:49 +1000)
inode semaphore handling.

fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_lrw.c

index 1bef1abb5bd800b6c816185440b1a6d0b850af56..1950da37f07e1e547e7ed900e47fff48b10f87cd 100644 (file)
@@ -164,8 +164,6 @@ __linvfs_readv(
        if (unlikely(file->f_flags & O_DIRECT))
                ioflags |= IO_ISDIRECT;
        VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
-       if (rval == -EIOCBQUEUED)
-               rval = wait_on_sync_kiocb(&kiocb);
 
        *ppos = kiocb.ki_pos;
        return rval;
@@ -211,8 +209,6 @@ __linvfs_writev(
                ioflags |= IO_ISDIRECT;
 
        VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
-       if (rval == -EIOCBQUEUED)
-               rval = wait_on_sync_kiocb(&kiocb);
 
        *ppos = kiocb.ki_pos;
        return rval;
index 585b004855ab64ee3d9da958a44f8d0fec62162a..5c0059e7227cc7e6280c077beba3ecd655ad24a1 100644 (file)
@@ -319,6 +319,8 @@ xfs_read(
        xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
                                (void *)iovp, segs, *offset, ioflags);
        ret = __generic_file_aio_read(iocb, iovp, segs, offset);
+       if (ret == -EIOCBQUEUED)
+               ret = wait_on_sync_kiocb(iocb);
        xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 
        if (ret > 0)
@@ -846,6 +848,9 @@ retry:
 
        current->backing_dev_info = NULL;
 
+       if (ret == -EIOCBQUEUED)
+               ret = wait_on_sync_kiocb(iocb);
+
        if ((ret == -ENOSPC) &&
            DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) &&
            !(ioflags & IO_INVIS)) {
@@ -953,13 +958,15 @@ retry:
                                        goto out_unlock_internal;
                        }
                }
-
+       
                xfs_rwunlock(bdp, locktype);
+               if (need_isem)
+                       up(&inode->i_sem);
 
                error = sync_page_range(inode, mapping, pos, ret);
                if (!error)
-                       error = -ret;
-               goto out_unlock_isem;
+                       error = ret;
+               return error;
        }
 
  out_unlock_internal: