aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/block_dev.c5
-rw-r--r--fs/direct-io.c74
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext3/inode.c11
-rw-r--r--fs/ext4/inode.c15
-rw-r--r--fs/fat/inode.c4
-rw-r--r--fs/gfs2/aops.c6
-rw-r--r--fs/hfs/inode.c17
-rw-r--r--fs/hfsplus/inode.c17
-rw-r--r--fs/jfs/inode.c17
-rw-r--r--fs/nilfs2/inode.c13
-rw-r--r--fs/ocfs2/aops.c9
-rw-r--r--fs/reiserfs/inode.c17
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c16
14 files changed, 140 insertions, 83 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 99d6af811747..65a0c26508e5 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -172,9 +172,8 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
172 struct file *file = iocb->ki_filp; 172 struct file *file = iocb->ki_filp;
173 struct inode *inode = file->f_mapping->host; 173 struct inode *inode = file->f_mapping->host;
174 174
175 return blockdev_direct_IO_no_locking_newtrunc(rw, iocb, inode, 175 return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
176 I_BDEV(inode), iov, offset, nr_segs, 176 nr_segs, blkdev_get_blocks, NULL, NULL, 0);
177 blkdev_get_blocks, NULL);
178} 177}
179 178
180int __sync_blockdev(struct block_device *bdev, int wait) 179int __sync_blockdev(struct block_device *bdev, int wait)
diff --git a/fs/direct-io.c b/fs/direct-io.c
index a10cb91cadea..51f270b479b6 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1136,8 +1136,27 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
1136 return ret; 1136 return ret;
1137} 1137}
1138 1138
1139/*
1140 * This is a library function for use by filesystem drivers.
1141 *
1142 * The locking rules are governed by the flags parameter:
1143 * - if the flags value contains DIO_LOCKING we use a fancy locking
1144 * scheme for dumb filesystems.
1145 * For writes this function is called under i_mutex and returns with
1146 * i_mutex held, for reads, i_mutex is not held on entry, but it is
1147 * taken and dropped again before returning.
1148 * For reads and writes i_alloc_sem is taken in shared mode and released
1149 * on I/O completion (which may happen asynchronously after returning to
1150 * the caller).
1151 *
1152 * - if the flags value does NOT contain DIO_LOCKING we don't use any
1153 * internal locking but rather rely on the filesystem to synchronize
1154 * direct I/O reads/writes versus each other and truncate.
1155 * For reads and writes both i_mutex and i_alloc_sem are not held on
1156 * entry and are never taken.
1157 */
1139ssize_t 1158ssize_t
1140__blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode, 1159__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1141 struct block_device *bdev, const struct iovec *iov, loff_t offset, 1160 struct block_device *bdev, const struct iovec *iov, loff_t offset,
1142 unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, 1161 unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
1143 dio_submit_t submit_io, int flags) 1162 dio_submit_t submit_io, int flags)
@@ -1233,57 +1252,4 @@ __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
1233out: 1252out:
1234 return retval; 1253 return retval;
1235} 1254}
1236EXPORT_SYMBOL(__blockdev_direct_IO_newtrunc);
1237
1238/*
1239 * This is a library function for use by filesystem drivers.
1240 *
1241 * The locking rules are governed by the flags parameter:
1242 * - if the flags value contains DIO_LOCKING we use a fancy locking
1243 * scheme for dumb filesystems.
1244 * For writes this function is called under i_mutex and returns with
1245 * i_mutex held, for reads, i_mutex is not held on entry, but it is
1246 * taken and dropped again before returning.
1247 * For reads and writes i_alloc_sem is taken in shared mode and released
1248 * on I/O completion (which may happen asynchronously after returning to
1249 * the caller).
1250 *
1251 * - if the flags value does NOT contain DIO_LOCKING we don't use any
1252 * internal locking but rather rely on the filesystem to synchronize
1253 * direct I/O reads/writes versus each other and truncate.
1254 * For reads and writes both i_mutex and i_alloc_sem are not held on
1255 * entry and are never taken.
1256 */
1257ssize_t
1258__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1259 struct block_device *bdev, const struct iovec *iov, loff_t offset,
1260 unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
1261 dio_submit_t submit_io, int flags)
1262{
1263 ssize_t retval;
1264
1265 retval = __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov,
1266 offset, nr_segs, get_block, end_io, submit_io, flags);
1267 /*
1268 * In case of error extending write may have instantiated a few
1269 * blocks outside i_size. Trim these off again for DIO_LOCKING.
1270 * NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this in
1271 * their own manner. This is a further example of where the old
1272 * truncate sequence is inadequate.
1273 *
1274 * NOTE: filesystems with their own locking have to handle this
1275 * on their own.
1276 */
1277 if (flags & DIO_LOCKING) {
1278 if (unlikely((rw & WRITE) && retval < 0)) {
1279 loff_t isize = i_size_read(inode);
1280 loff_t end = offset + iov_length(iov, nr_segs);
1281
1282 if (end > isize)
1283 vmtruncate(inode, isize);
1284 }
1285 }
1286
1287 return retval;
1288}
1289EXPORT_SYMBOL(__blockdev_direct_IO); 1255EXPORT_SYMBOL(__blockdev_direct_IO);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 3675088cb88c..f36e967e4fde 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -838,7 +838,7 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
838 struct inode *inode = mapping->host; 838 struct inode *inode = mapping->host;
839 ssize_t ret; 839 ssize_t ret;
840 840
841 ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev, 841 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
842 iov, offset, nr_segs, ext2_get_block, NULL); 842 iov, offset, nr_segs, ext2_get_block, NULL);
843 if (ret < 0 && (rw & WRITE)) 843 if (ret < 0 && (rw & WRITE))
844 ext2_write_failed(mapping, offset + iov_length(iov, nr_segs)); 844 ext2_write_failed(mapping, offset + iov_length(iov, nr_segs));
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 735f0190ec2a..a66f3fe33672 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1785,6 +1785,17 @@ retry:
1785 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 1785 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
1786 offset, nr_segs, 1786 offset, nr_segs,
1787 ext3_get_block, NULL); 1787 ext3_get_block, NULL);
1788 /*
1789 * In case of error extending write may have instantiated a few
1790 * blocks outside i_size. Trim these off again.
1791 */
1792 if (unlikely((rw & WRITE) && ret < 0)) {
1793 loff_t isize = i_size_read(inode);
1794 loff_t end = offset + iov_length(iov, nr_segs);
1795
1796 if (end > isize)
1797 vmtruncate(inode, isize);
1798 }
1788 if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) 1799 if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
1789 goto retry; 1800 goto retry;
1790 1801
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 0afc8c1d8cf3..d6a7701018a6 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3545,15 +3545,24 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
3545 3545
3546retry: 3546retry:
3547 if (rw == READ && ext4_should_dioread_nolock(inode)) 3547 if (rw == READ && ext4_should_dioread_nolock(inode))
3548 ret = blockdev_direct_IO_no_locking(rw, iocb, inode, 3548 ret = __blockdev_direct_IO(rw, iocb, inode,
3549 inode->i_sb->s_bdev, iov, 3549 inode->i_sb->s_bdev, iov,
3550 offset, nr_segs, 3550 offset, nr_segs,
3551 ext4_get_block, NULL); 3551 ext4_get_block, NULL, NULL, 0);
3552 else 3552 else {
3553 ret = blockdev_direct_IO(rw, iocb, inode, 3553 ret = blockdev_direct_IO(rw, iocb, inode,
3554 inode->i_sb->s_bdev, iov, 3554 inode->i_sb->s_bdev, iov,
3555 offset, nr_segs, 3555 offset, nr_segs,
3556 ext4_get_block, NULL); 3556 ext4_get_block, NULL);
3557
3558 if (unlikely((rw & WRITE) && ret < 0)) {
3559 loff_t isize = i_size_read(inode);
3560 loff_t end = offset + iov_length(iov, nr_segs);
3561
3562 if (end > isize)
3563 vmtruncate(inode, isize);
3564 }
3565 }
3557 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 3566 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
3558 goto retry; 3567 goto retry;
3559 3568
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 7bf45aee56d7..ffe7c6fdc1ec 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -212,8 +212,8 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
212 * FAT need to use the DIO_LOCKING for avoiding the race 212 * FAT need to use the DIO_LOCKING for avoiding the race
213 * condition of fat_get_block() and ->truncate(). 213 * condition of fat_get_block() and ->truncate().
214 */ 214 */
215 ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev, 215 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
216 iov, offset, nr_segs, fat_get_block, NULL); 216 iov, offset, nr_segs, fat_get_block, NULL);
217 if (ret < 0 && (rw & WRITE)) 217 if (ret < 0 && (rw & WRITE))
218 fat_write_failed(mapping, offset + iov_length(iov, nr_segs)); 218 fat_write_failed(mapping, offset + iov_length(iov, nr_segs));
219 219
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 9f8b52500d63..703000d6e4d2 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -1047,9 +1047,9 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
1047 if (rv != 1) 1047 if (rv != 1)
1048 goto out; /* dio not valid, fall back to buffered i/o */ 1048 goto out; /* dio not valid, fall back to buffered i/o */
1049 1049
1050 rv = blockdev_direct_IO_no_locking(rw, iocb, inode, inode->i_sb->s_bdev, 1050 rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
1051 iov, offset, nr_segs, 1051 offset, nr_segs, gfs2_get_block_direct,
1052 gfs2_get_block_direct, NULL); 1052 NULL, NULL, 0);
1053out: 1053out:
1054 gfs2_glock_dq_m(1, &gh); 1054 gfs2_glock_dq_m(1, &gh);
1055 gfs2_holder_uninit(&gh); 1055 gfs2_holder_uninit(&gh);
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 14f5cb1b9fdc..07b2464b5716 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -112,9 +112,24 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,
112{ 112{
113 struct file *file = iocb->ki_filp; 113 struct file *file = iocb->ki_filp;
114 struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; 114 struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;
115 ssize_t ret;
115 116
116 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 117 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
117 offset, nr_segs, hfs_get_block, NULL); 118 offset, nr_segs, hfs_get_block, NULL);
119
120 /*
121 * In case of error extending write may have instantiated a few
122 * blocks outside i_size. Trim these off again.
123 */
124 if (unlikely((rw & WRITE) && ret < 0)) {
125 loff_t isize = i_size_read(inode);
126 loff_t end = offset + iov_length(iov, nr_segs);
127
128 if (end > isize)
129 vmtruncate(inode, isize);
130 }
131
132 return ret;
118} 133}
119 134
120static int hfs_writepages(struct address_space *mapping, 135static int hfs_writepages(struct address_space *mapping,
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 9bbb82924a22..486021773911 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -105,9 +105,24 @@ static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,
105{ 105{
106 struct file *file = iocb->ki_filp; 106 struct file *file = iocb->ki_filp;
107 struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; 107 struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;
108 ssize_t ret;
108 109
109 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 110 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
110 offset, nr_segs, hfsplus_get_block, NULL); 111 offset, nr_segs, hfsplus_get_block, NULL);
112
113 /*
114 * In case of error extending write may have instantiated a few
115 * blocks outside i_size. Trim these off again.
116 */
117 if (unlikely((rw & WRITE) && ret < 0)) {
118 loff_t isize = i_size_read(inode);
119 loff_t end = offset + iov_length(iov, nr_segs);
120
121 if (end > isize)
122 vmtruncate(inode, isize);
123 }
124
125 return ret;
111} 126}
112 127
113static int hfsplus_writepages(struct address_space *mapping, 128static int hfsplus_writepages(struct address_space *mapping,
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index ed9ba6fe04f5..79e6cda28181 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -317,9 +317,24 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
317{ 317{
318 struct file *file = iocb->ki_filp; 318 struct file *file = iocb->ki_filp;
319 struct inode *inode = file->f_mapping->host; 319 struct inode *inode = file->f_mapping->host;
320 ssize_t ret;
320 321
321 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 322 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
322 offset, nr_segs, jfs_get_block, NULL); 323 offset, nr_segs, jfs_get_block, NULL);
324
325 /*
326 * In case of error extending write may have instantiated a few
327 * blocks outside i_size. Trim these off again.
328 */
329 if (unlikely((rw & WRITE) && ret < 0)) {
330 loff_t isize = i_size_read(inode);
331 loff_t end = offset + iov_length(iov, nr_segs);
332
333 if (end > isize)
334 vmtruncate(inode, isize);
335 }
336
337 return ret;
323} 338}
324 339
325const struct address_space_operations jfs_aops = { 340const struct address_space_operations jfs_aops = {
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 39e038ac8fcb..1dd9e6a7d787 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -237,6 +237,19 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
237 /* Needs synchronization with the cleaner */ 237 /* Needs synchronization with the cleaner */
238 size = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 238 size = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
239 offset, nr_segs, nilfs_get_block, NULL); 239 offset, nr_segs, nilfs_get_block, NULL);
240
241 /*
242 * In case of error extending write may have instantiated a few
243 * blocks outside i_size. Trim these off again.
244 */
245 if (unlikely((rw & WRITE) && size < 0)) {
246 loff_t isize = i_size_read(inode);
247 loff_t end = offset + iov_length(iov, nr_segs);
248
249 if (end > isize)
250 vmtruncate(inode, isize);
251 }
252
240 return size; 253 return size;
241} 254}
242 255
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 96337a4fbbdf..0de69c9a08be 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -643,11 +643,10 @@ static ssize_t ocfs2_direct_IO(int rw,
643 if (i_size_read(inode) <= offset) 643 if (i_size_read(inode) <= offset)
644 return 0; 644 return 0;
645 645
646 ret = blockdev_direct_IO_no_locking(rw, iocb, inode, 646 ret = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
647 inode->i_sb->s_bdev, iov, offset, 647 iov, offset, nr_segs,
648 nr_segs, 648 ocfs2_direct_IO_get_blocks,
649 ocfs2_direct_IO_get_blocks, 649 ocfs2_dio_end_io, NULL, 0);
650 ocfs2_dio_end_io);
651 650
652 mlog_exit(ret); 651 mlog_exit(ret);
653 return ret; 652 return ret;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 6edac85c2b93..4c1fb548ab64 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3057,10 +3057,25 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
3057{ 3057{
3058 struct file *file = iocb->ki_filp; 3058 struct file *file = iocb->ki_filp;
3059 struct inode *inode = file->f_mapping->host; 3059 struct inode *inode = file->f_mapping->host;
3060 ssize_t ret;
3060 3061
3061 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 3062 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
3062 offset, nr_segs, 3063 offset, nr_segs,
3063 reiserfs_get_blocks_direct_io, NULL); 3064 reiserfs_get_blocks_direct_io, NULL);
3065
3066 /*
3067 * In case of error extending write may have instantiated a few
3068 * blocks outside i_size. Trim these off again.
3069 */
3070 if (unlikely((rw & WRITE) && ret < 0)) {
3071 loff_t isize = i_size_read(inode);
3072 loff_t end = offset + iov_length(iov, nr_segs);
3073
3074 if (end > isize)
3075 vmtruncate(inode, isize);
3076 }
3077
3078 return ret;
3064} 3079}
3065 3080
3066int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) 3081int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index d24e78f32f3e..7968d41e27ad 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1478,17 +1478,17 @@ xfs_vm_direct_IO(
1478 if (rw & WRITE) { 1478 if (rw & WRITE) {
1479 iocb->private = xfs_alloc_ioend(inode, IO_NEW); 1479 iocb->private = xfs_alloc_ioend(inode, IO_NEW);
1480 1480
1481 ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov, 1481 ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov,
1482 offset, nr_segs, 1482 offset, nr_segs,
1483 xfs_get_blocks_direct, 1483 xfs_get_blocks_direct,
1484 xfs_end_io_direct_write); 1484 xfs_end_io_direct_write, NULL, 0);
1485 if (ret != -EIOCBQUEUED && iocb->private) 1485 if (ret != -EIOCBQUEUED && iocb->private)
1486 xfs_destroy_ioend(iocb->private); 1486 xfs_destroy_ioend(iocb->private);
1487 } else { 1487 } else {
1488 ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov, 1488 ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov,
1489 offset, nr_segs, 1489 offset, nr_segs,
1490 xfs_get_blocks_direct, 1490 xfs_get_blocks_direct,
1491 NULL); 1491 NULL, NULL, 0);
1492 } 1492 }
1493 1493
1494 return ret; 1494 return ret;