diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-03-22 05:15:17 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-06 17:32:53 -0400 |
commit | 28060d5d9b261da110afe48aae7a2aa6555f798f (patch) | |
tree | d4de6738ddaf5d58dfbf84eb5d0db6a2893d1ce6 /fs/btrfs | |
parent | 91f79c43d1b54d7154b118860d81b39bad07dfff (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.c | 40 |
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 | ||
7393 | static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, | 7393 | static 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); |