[PATCH 3/5] ext4: drop aio_mutex after grabbing i_mutex in ext4_file_write()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Once we have grabbed i_mutex, this will prevent any other writes from
proceeding, so we don't need to worry about any writes to unwritten
regions from taking place.  So drop the aio_mutex so that if there are
any other parallel writes happen to some other inode that happens to
hash to the same hash table entry, we won't end up blocking that work.

Signed-off-by: "Theodore Ts'o" <tytso@xxxxxxx>
---
 fs/ext4/file.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3ec0c09..5e428d58 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -98,7 +98,6 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(iocb->ki_filp);
 	struct blk_plug plug;
-	int unaligned_aio = 0;
 	int overwrite = 0;
 	size_t length = iov_length(iov, nr_segs);
 	ssize_t ret;
@@ -124,24 +123,26 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
 	}
 
 	if (unlikely(iocb->ki_filp->f_flags & O_DIRECT)) {
-		if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
-		    !is_sync_kiocb(iocb))
-			unaligned_aio = ext4_unaligned_aio(inode, iov,
-							   nr_segs, pos);
+		struct mutex *aio_mutex = NULL;
 
 		/* Unaligned direct AIO must be serialized; see comment above */
-		if (unaligned_aio) {
-			mutex_lock(ext4_aio_mutex(inode));
+		if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
+		    !is_sync_kiocb(iocb) &&
+		    ext4_unaligned_aio(inode, iov, nr_segs, pos)) {
+			aio_mutex = ext4_aio_mutex(inode);
+			mutex_lock(aio_mutex);
 			ext4_unwritten_wait(inode);
 		}
 
 		mutex_lock(&inode->i_mutex);
+		if (aio_mutex)
+			mutex_unlock(aio_mutex);
 		blk_start_plug(&plug);
 
 		iocb->private = &overwrite;
 
 		/* check whether we do a DIO overwrite or not */
-		if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
+		if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
 		    !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
 			struct ext4_map_blocks map;
 			unsigned int blkbits = inode->i_blkbits;
@@ -181,9 +182,6 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
 				ret = err;
 		}
 		blk_finish_plug(&plug);
-
-		if (unaligned_aio)
-			mutex_unlock(ext4_aio_mutex(inode));
 	} else {
 		mutex_lock(&inode->i_mutex);
 		ret = __generic_file_aio_write(iocb, iov, nr_segs,
-- 
1.9.0

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux