aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2012-09-29 00:56:15 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-09-29 00:56:15 -0400
commit1b65007e9870e0021397b548e8cd6bbc584f9152 (patch)
tree17cd144e9215ac7db9084f385c9c0d50e82b0bf6 /fs/ext4
parentext4: serialize unlocked dio reads with truncate (diff)
downloadlinux-dev-1b65007e9870e0021397b548e8cd6bbc584f9152.tar.xz
linux-dev-1b65007e9870e0021397b548e8cd6bbc584f9152.zip
ext4: endless truncate due to nonlocked dio readers
If we have enough aggressive DIO readers, truncate and other dio waiters will wait forever inside inode_dio_wait(). It is reasonable to disable nonlock DIO read optimization during truncate. Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/inode.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 0bfc63331467..05ab70dd5c64 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4333,9 +4333,14 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
if (attr->ia_valid & ATTR_SIZE) {
if (attr->ia_size != i_size_read(inode)) {
truncate_setsize(inode, attr->ia_size);
- /* Inode size will be reduced, wait for dio in flight */
- if (orphan)
+ /* Inode size will be reduced, wait for dio in flight.
+ * Temporarily disable dioread_nolock to prevent
+ * livelock. */
+ if (orphan) {
+ ext4_inode_block_unlocked_dio(inode);
inode_dio_wait(inode);
+ ext4_inode_resume_unlocked_dio(inode);
+ }
}
ext4_truncate(inode);
}