aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-22 05:15:17 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:32:53 -0400
commit28060d5d9b261da110afe48aae7a2aa6555f798f (patch)
treed4de6738ddaf5d58dfbf84eb5d0db6a2893d1ce6 /fs/btrfs
parent91f79c43d1b54d7154b118860d81b39bad07dfff (diff)
btrfs: switch check_direct_IO() to iov_iter
... and don't open-code iov_iter_alignment() there Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/inode.c40
1 files changed, 15 insertions, 25 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b0b8fa0efba3..c8386f1961f0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7391,39 +7391,30 @@ free_ordered:
7391} 7391}
7392 7392
7393static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, 7393static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb,
7394 const struct iovec *iov, loff_t offset, 7394 const struct iov_iter *iter, loff_t offset)
7395 unsigned long nr_segs)
7396{ 7395{
7397 int seg; 7396 int seg;
7398 int i; 7397 int i;
7399 size_t size;
7400 unsigned long addr;
7401 unsigned blocksize_mask = root->sectorsize - 1; 7398 unsigned blocksize_mask = root->sectorsize - 1;
7402 ssize_t retval = -EINVAL; 7399 ssize_t retval = -EINVAL;
7403 loff_t end = offset;
7404 7400
7405 if (offset & blocksize_mask) 7401 if (offset & blocksize_mask)
7406 goto out; 7402 goto out;
7407 7403
7408 /* Check the memory alignment. Blocks cannot straddle pages */ 7404 if (iov_iter_alignment(iter) & blocksize_mask)
7409 for (seg = 0; seg < nr_segs; seg++) { 7405 goto out;
7410 addr = (unsigned long)iov[seg].iov_base;
7411 size = iov[seg].iov_len;
7412 end += size;
7413 if ((addr & blocksize_mask) || (size & blocksize_mask))
7414 goto out;
7415
7416 /* If this is a write we don't need to check anymore */
7417 if (rw & WRITE)
7418 continue;
7419 7406
7420 /* 7407 /* If this is a write we don't need to check anymore */
7421 * Check to make sure we don't have duplicate iov_base's in this 7408 if (rw & WRITE)
7422 * iovec, if so return EINVAL, otherwise we'll get csum errors 7409 return 0;
7423 * when reading back. 7410 /*
7424 */ 7411 * Check to make sure we don't have duplicate iov_base's in this
7425 for (i = seg + 1; i < nr_segs; i++) { 7412 * iovec, if so return EINVAL, otherwise we'll get csum errors
7426 if (iov[seg].iov_base == iov[i].iov_base) 7413 * when reading back.
7414 */
7415 for (seg = 0; seg < iter->nr_segs; seg++) {
7416 for (i = seg + 1; i < iter->nr_segs; i++) {
7417 if (iter->iov[seg].iov_base == iter->iov[i].iov_base)
7427 goto out; 7418 goto out;
7428 } 7419 }
7429 } 7420 }
@@ -7443,8 +7434,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
7443 bool relock = false; 7434 bool relock = false;
7444 ssize_t ret; 7435 ssize_t ret;
7445 7436
7446 if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iter->iov, 7437 if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iter, offset))
7447 offset, iter->nr_segs))
7448 return 0; 7438 return 0;
7449 7439
7450 atomic_inc(&inode->i_dio_count); 7440 atomic_inc(&inode->i_dio_count);