aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_lrw.c
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2006-09-07 14:27:05 +1000
committerDavid Chatterton <chatz@sgi.com>2006-09-07 14:27:05 +1000
commit721259bce2851893155c6cb88a3f8ecb106b348c (patch)
tree0db37f80a7ef0b701b313e9ba28f8c0d3950e533 /fs/xfs/linux-2.6/xfs_lrw.c
parent[XFS] Prevent free space oversubscription and xfssyncd looping. (diff)
downloadlinux-dev-721259bce2851893155c6cb88a3f8ecb106b348c.tar.xz
linux-dev-721259bce2851893155c6cb88a3f8ecb106b348c.zip
[XFS] Fix ABBA deadlock between i_mutex and iolock. Avoid calling
__blockdev_direct_IO for the DIO_OWN_LOCKING case for direct I/O reads since it drops and reacquires the i_mutex while holding the iolock and this violates the locking order. SGI-PV: 955696 SGI-Modid: xfs-linux-melb:xfs-kern:26898a Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: David Chatterton <chatz@sgi.com>
Diffstat (limited to '')
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 5d9cfd91ad08..110c038910ff 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -264,7 +264,9 @@ xfs_read(
dmflags, &locktype);
if (ret) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- goto unlock_mutex;
+ if (unlikely(ioflags & IO_ISDIRECT))
+ mutex_unlock(&inode->i_mutex);
+ return ret;
}
}
@@ -272,6 +274,9 @@ xfs_read(
bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
-1, FI_REMAPF_LOCKED);
+ if (unlikely(ioflags & IO_ISDIRECT))
+ mutex_unlock(&inode->i_mutex);
+
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
(void *)iovp, segs, *offset, ioflags);
ret = __generic_file_aio_read(iocb, iovp, segs, offset);
@@ -281,10 +286,6 @@ xfs_read(
XFS_STATS_ADD(xs_read_bytes, ret);
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-
-unlock_mutex:
- if (unlikely(ioflags & IO_ISDIRECT))
- mutex_unlock(&inode->i_mutex);
return ret;
}