Loading fs/ext4/file.c +22 −34 Original line number Diff line number Diff line Loading @@ -97,8 +97,9 @@ 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 mutex *aio_mutex = NULL; struct blk_plug plug; int unaligned_aio = 0; int o_direct = file->f_flags & O_DIRECT; int overwrite = 0; size_t length = iov_length(iov, nr_segs); ssize_t ret; Loading @@ -123,15 +124,13 @@ 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); if (o_direct) { /* 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); } Loading @@ -141,7 +140,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, 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; Loading @@ -168,6 +167,8 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) overwrite = 1; } } else mutex_lock(&inode->i_mutex); ret = __generic_file_aio_write(iocb, iov, nr_segs); mutex_unlock(&inode->i_mutex); Loading @@ -179,24 +180,11 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, if (err < 0) ret = err; } if (o_direct) 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); mutex_unlock(&inode->i_mutex); if (ret > 0) { ssize_t err; err = generic_write_sync(file, iocb->ki_pos - ret, ret); if (err < 0) ret = err; } } if (aio_mutex) mutex_unlock(aio_mutex); return ret; } Loading Loading
fs/ext4/file.c +22 −34 Original line number Diff line number Diff line Loading @@ -97,8 +97,9 @@ 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 mutex *aio_mutex = NULL; struct blk_plug plug; int unaligned_aio = 0; int o_direct = file->f_flags & O_DIRECT; int overwrite = 0; size_t length = iov_length(iov, nr_segs); ssize_t ret; Loading @@ -123,15 +124,13 @@ 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); if (o_direct) { /* 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); } Loading @@ -141,7 +140,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, 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; Loading @@ -168,6 +167,8 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) overwrite = 1; } } else mutex_lock(&inode->i_mutex); ret = __generic_file_aio_write(iocb, iov, nr_segs); mutex_unlock(&inode->i_mutex); Loading @@ -179,24 +180,11 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, if (err < 0) ret = err; } if (o_direct) 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); mutex_unlock(&inode->i_mutex); if (ret > 0) { ssize_t err; err = generic_write_sync(file, iocb->ki_pos - ret, ret); if (err < 0) ret = err; } } if (aio_mutex) mutex_unlock(aio_mutex); return ret; } Loading