diff options
author | Lachlan McIlroy <lachlan@sgi.com> | 2006-09-07 00:27:05 -0400 |
---|---|---|
committer | David Chatterton <chatz@sgi.com> | 2006-09-07 00:27:05 -0400 |
commit | 721259bce2851893155c6cb88a3f8ecb106b348c (patch) | |
tree | 0db37f80a7ef0b701b313e9ba28f8c0d3950e533 /fs/xfs/linux-2.6/xfs_lrw.c | |
parent | 4be536debe3f7b0c62283e77fd6bd8bdb9f83c6f (diff) |
[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 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 11 |
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( | |||
264 | dmflags, &locktype); | 264 | dmflags, &locktype); |
265 | if (ret) { | 265 | if (ret) { |
266 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 266 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
267 | goto unlock_mutex; | 267 | if (unlikely(ioflags & IO_ISDIRECT)) |
268 | mutex_unlock(&inode->i_mutex); | ||
269 | return ret; | ||
268 | } | 270 | } |
269 | } | 271 | } |
270 | 272 | ||
@@ -272,6 +274,9 @@ xfs_read( | |||
272 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), | 274 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), |
273 | -1, FI_REMAPF_LOCKED); | 275 | -1, FI_REMAPF_LOCKED); |
274 | 276 | ||
277 | if (unlikely(ioflags & IO_ISDIRECT)) | ||
278 | mutex_unlock(&inode->i_mutex); | ||
279 | |||
275 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, | 280 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, |
276 | (void *)iovp, segs, *offset, ioflags); | 281 | (void *)iovp, segs, *offset, ioflags); |
277 | ret = __generic_file_aio_read(iocb, iovp, segs, offset); | 282 | ret = __generic_file_aio_read(iocb, iovp, segs, offset); |
@@ -281,10 +286,6 @@ xfs_read( | |||
281 | XFS_STATS_ADD(xs_read_bytes, ret); | 286 | XFS_STATS_ADD(xs_read_bytes, ret); |
282 | 287 | ||
283 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 288 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
284 | |||
285 | unlock_mutex: | ||
286 | if (unlikely(ioflags & IO_ISDIRECT)) | ||
287 | mutex_unlock(&inode->i_mutex); | ||
288 | return ret; | 289 | return ret; |
289 | } | 290 | } |
290 | 291 | ||