diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-06-24 14:29:45 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-07-20 20:47:47 -0400 |
commit | 562c72aa57c36b178eacc3500a0215651eca9429 (patch) | |
tree | 2c522c53ab26fc72e85e08747a08e3dca1207c87 /fs | |
parent | 11b80f459adaf91a712f95e7734a17655a36bf30 (diff) |
fs: move inode_dio_wait calls into ->setattr
Let filesystems handle waiting for direct I/O requests themselves instead
of doing it beforehand. This means filesystem-specific locks to prevent
new dio referenes from appearing can be held. This is important to allow
generalizing i_dio_count to non-DIO_LOCKING filesystems.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/attr.c | 3 | ||||
-rw-r--r-- | fs/ext2/inode.c | 2 | ||||
-rw-r--r-- | fs/ext3/inode.c | 3 | ||||
-rw-r--r-- | fs/ext4/inode.c | 2 | ||||
-rw-r--r-- | fs/fat/file.c | 2 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 2 | ||||
-rw-r--r-- | fs/hfs/inode.c | 2 | ||||
-rw-r--r-- | fs/hfsplus/inode.c | 2 | ||||
-rw-r--r-- | fs/jfs/file.c | 2 | ||||
-rw-r--r-- | fs/nilfs2/inode.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 3 |
12 files changed, 24 insertions, 3 deletions
@@ -232,9 +232,6 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
232 | if (error) | 232 | if (error) |
233 | return error; | 233 | return error; |
234 | 234 | ||
235 | if (ia_valid & ATTR_SIZE) | ||
236 | inode_dio_wait(inode); | ||
237 | |||
238 | if (inode->i_op->setattr) | 235 | if (inode->i_op->setattr) |
239 | error = inode->i_op->setattr(dentry, attr); | 236 | error = inode->i_op->setattr(dentry, attr); |
240 | else | 237 | else |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 788e09a07f7e..06e7c767ab35 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -1184,6 +1184,8 @@ static int ext2_setsize(struct inode *inode, loff_t newsize) | |||
1184 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 1184 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
1185 | return -EPERM; | 1185 | return -EPERM; |
1186 | 1186 | ||
1187 | inode_dio_wait(inode); | ||
1188 | |||
1187 | if (mapping_is_xip(inode->i_mapping)) | 1189 | if (mapping_is_xip(inode->i_mapping)) |
1188 | error = xip_truncate_page(inode->i_mapping, newsize); | 1190 | error = xip_truncate_page(inode->i_mapping, newsize); |
1189 | else if (test_opt(inode->i_sb, NOBH)) | 1191 | else if (test_opt(inode->i_sb, NOBH)) |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 3451d23c3bae..99c28b246b89 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -3216,6 +3216,9 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
3216 | ext3_journal_stop(handle); | 3216 | ext3_journal_stop(handle); |
3217 | } | 3217 | } |
3218 | 3218 | ||
3219 | if (attr->ia_valid & ATTR_SIZE) | ||
3220 | inode_dio_wait(inode); | ||
3221 | |||
3219 | if (S_ISREG(inode->i_mode) && | 3222 | if (S_ISREG(inode->i_mode) && |
3220 | attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) { | 3223 | attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) { |
3221 | handle_t *handle; | 3224 | handle_t *handle; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bd309764557f..9ec0a2ba2502 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -5351,6 +5351,8 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
5351 | } | 5351 | } |
5352 | 5352 | ||
5353 | if (attr->ia_valid & ATTR_SIZE) { | 5353 | if (attr->ia_valid & ATTR_SIZE) { |
5354 | inode_dio_wait(inode); | ||
5355 | |||
5354 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { | 5356 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { |
5355 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 5357 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
5356 | 5358 | ||
diff --git a/fs/fat/file.c b/fs/fat/file.c index a4a3a3c06436..e1587c54d3c1 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -397,6 +397,8 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
397 | * sequence. | 397 | * sequence. |
398 | */ | 398 | */ |
399 | if (attr->ia_valid & ATTR_SIZE) { | 399 | if (attr->ia_valid & ATTR_SIZE) { |
400 | inode_dio_wait(inode); | ||
401 | |||
400 | if (attr->ia_size > inode->i_size) { | 402 | if (attr->ia_size > inode->i_size) { |
401 | error = fat_cont_expand(inode, attr->ia_size); | 403 | error = fat_cont_expand(inode, attr->ia_size); |
402 | if (error || attr->ia_valid == ATTR_SIZE) | 404 | if (error || attr->ia_valid == ATTR_SIZE) |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index e65493a8ac00..2cd0e56b8893 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -1224,6 +1224,8 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) | |||
1224 | if (ret) | 1224 | if (ret) |
1225 | return ret; | 1225 | return ret; |
1226 | 1226 | ||
1227 | inode_dio_wait(inode); | ||
1228 | |||
1227 | oldsize = inode->i_size; | 1229 | oldsize = inode->i_size; |
1228 | if (newsize >= oldsize) | 1230 | if (newsize >= oldsize) |
1229 | return do_grow(inode, newsize); | 1231 | return do_grow(inode, newsize); |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index fff16c968e67..48d567cc203e 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -615,6 +615,8 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr) | |||
615 | 615 | ||
616 | if ((attr->ia_valid & ATTR_SIZE) && | 616 | if ((attr->ia_valid & ATTR_SIZE) && |
617 | attr->ia_size != i_size_read(inode)) { | 617 | attr->ia_size != i_size_read(inode)) { |
618 | inode_dio_wait(inode); | ||
619 | |||
618 | error = vmtruncate(inode, attr->ia_size); | 620 | error = vmtruncate(inode, attr->ia_size); |
619 | if (error) | 621 | if (error) |
620 | return error; | 622 | return error; |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index b248a6cfcad9..b0a0a4b621eb 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -296,6 +296,8 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) | |||
296 | 296 | ||
297 | if ((attr->ia_valid & ATTR_SIZE) && | 297 | if ((attr->ia_valid & ATTR_SIZE) && |
298 | attr->ia_size != i_size_read(inode)) { | 298 | attr->ia_size != i_size_read(inode)) { |
299 | inode_dio_wait(inode); | ||
300 | |||
299 | error = vmtruncate(inode, attr->ia_size); | 301 | error = vmtruncate(inode, attr->ia_size); |
300 | if (error) | 302 | if (error) |
301 | return error; | 303 | return error; |
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 2f3f531f3606..9f32315acef1 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -110,6 +110,8 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
110 | 110 | ||
111 | if ((iattr->ia_valid & ATTR_SIZE) && | 111 | if ((iattr->ia_valid & ATTR_SIZE) && |
112 | iattr->ia_size != i_size_read(inode)) { | 112 | iattr->ia_size != i_size_read(inode)) { |
113 | inode_dio_wait(inode); | ||
114 | |||
113 | rc = vmtruncate(inode, iattr->ia_size); | 115 | rc = vmtruncate(inode, iattr->ia_size); |
114 | if (rc) | 116 | if (rc) |
115 | return rc; | 117 | return rc; |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index be8664c6a825..13f113154a9f 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -778,6 +778,8 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
778 | 778 | ||
779 | if ((iattr->ia_valid & ATTR_SIZE) && | 779 | if ((iattr->ia_valid & ATTR_SIZE) && |
780 | iattr->ia_size != i_size_read(inode)) { | 780 | iattr->ia_size != i_size_read(inode)) { |
781 | inode_dio_wait(inode); | ||
782 | |||
781 | err = vmtruncate(inode, iattr->ia_size); | 783 | err = vmtruncate(inode, iattr->ia_size); |
782 | if (unlikely(err)) | 784 | if (unlikely(err)) |
783 | goto out_err; | 785 | goto out_err; |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 2c3a465514a2..736283ca4a4c 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1142,6 +1142,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1142 | if (status) | 1142 | if (status) |
1143 | goto bail_unlock; | 1143 | goto bail_unlock; |
1144 | 1144 | ||
1145 | inode_dio_wait(inode); | ||
1146 | |||
1145 | if (i_size_read(inode) > attr->ia_size) { | 1147 | if (i_size_read(inode) > attr->ia_size) { |
1146 | if (ocfs2_should_order_data(inode)) { | 1148 | if (ocfs2_should_order_data(inode)) { |
1147 | status = ocfs2_begin_ordered_truncate(inode, | 1149 | status = ocfs2_begin_ordered_truncate(inode, |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 4fd5bb33dbb5..dcf543d8caf1 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -3114,6 +3114,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3114 | error = -EFBIG; | 3114 | error = -EFBIG; |
3115 | goto out; | 3115 | goto out; |
3116 | } | 3116 | } |
3117 | |||
3118 | inode_dio_wait(inode); | ||
3119 | |||
3117 | /* fill in hole pointers in the expanding truncate case. */ | 3120 | /* fill in hole pointers in the expanding truncate case. */ |
3118 | if (attr->ia_size > inode->i_size) { | 3121 | if (attr->ia_size > inode->i_size) { |
3119 | error = generic_cont_expand_simple(inode, attr->ia_size); | 3122 | error = generic_cont_expand_simple(inode, attr->ia_size); |