From: Christoph Hellwig On Fri, Dec 10, 2004 at 11:04:22AM +1100, Nathan Scott wrote: > The bug# for the write deadlock I mentioned earlier -- 925836. I finally found some time to look at it, and this fix is almost trivial. XFS doesn't need the i_alloc_sem at all, so we should avoid taking it in direct-io.c completely. As a side-effect it makes the code a little bit simpler even. Signed-off-by: Andrew Morton --- 25-akpm/fs/direct-io.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff -puN fs/direct-io.c~direct-write-vs-truncate-deadlock fs/direct-io.c --- 25/fs/direct-io.c~direct-write-vs-truncate-deadlock 2005-01-10 17:29:27.236746304 -0800 +++ 25-akpm/fs/direct-io.c 2005-01-10 17:29:27.240745696 -0800 @@ -215,7 +215,7 @@ static void dio_complete(struct dio *dio { if (dio->end_io && dio->result) dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private); - if (dio->lock_type != DIO_NO_LOCKING) + if (dio->lock_type == DIO_LOCKING) up_read(&dio->inode->i_alloc_sem); } @@ -1201,8 +1201,8 @@ __blockdev_direct_IO(int rw, struct kioc * readers need to grab i_sem and i_alloc_sem * writers need to grab i_alloc_sem only (i_sem is already held) * For regular files using DIO_OWN_LOCKING, - * readers need to grab i_alloc_sem only (i_sem is already held) - * writers need to grab i_alloc_sem only + * neither readers nor writers take any locks here + * (i_sem is already held and release for writers here) */ dio->lock_type = dio_lock_type; if (dio_lock_type != DIO_NO_LOCKING) { @@ -1219,14 +1219,15 @@ __blockdev_direct_IO(int rw, struct kioc kfree(dio); goto out; } - down_read(&inode->i_alloc_sem); + if (dio_lock_type == DIO_OWN_LOCKING) { up(&inode->i_sem); reader_with_isem = 0; } - } else { - down_read(&inode->i_alloc_sem); } + + if (dio_lock_type == DIO_LOCKING) + down_read(&inode->i_alloc_sem); } /* _