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/inode.c | |
parent | 91f79c43d1b54d7154b118860d81b39bad07dfff (diff) | |
download | lwn-28060d5d9b261da110afe48aae7a2aa6555f798f.tar.gz lwn-28060d5d9b261da110afe48aae7a2aa6555f798f.zip |
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/inode.c')
-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: } static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, - const struct iovec *iov, loff_t offset, - unsigned long nr_segs) + const struct iov_iter *iter, loff_t offset) { int seg; int i; - size_t size; - unsigned long addr; unsigned blocksize_mask = root->sectorsize - 1; ssize_t retval = -EINVAL; - loff_t end = offset; if (offset & blocksize_mask) goto out; - /* Check the memory alignment. Blocks cannot straddle pages */ - for (seg = 0; seg < nr_segs; seg++) { - addr = (unsigned long)iov[seg].iov_base; - size = iov[seg].iov_len; - end += size; - if ((addr & blocksize_mask) || (size & blocksize_mask)) - goto out; - - /* If this is a write we don't need to check anymore */ - if (rw & WRITE) - continue; + if (iov_iter_alignment(iter) & blocksize_mask) + goto out; - /* - * Check to make sure we don't have duplicate iov_base's in this - * iovec, if so return EINVAL, otherwise we'll get csum errors - * when reading back. - */ - for (i = seg + 1; i < nr_segs; i++) { - if (iov[seg].iov_base == iov[i].iov_base) + /* If this is a write we don't need to check anymore */ + if (rw & WRITE) + return 0; + /* + * Check to make sure we don't have duplicate iov_base's in this + * iovec, if so return EINVAL, otherwise we'll get csum errors + * when reading back. + */ + for (seg = 0; seg < iter->nr_segs; seg++) { + for (i = seg + 1; i < iter->nr_segs; i++) { + if (iter->iov[seg].iov_base == iter->iov[i].iov_base) goto out; } } @@ -7443,8 +7434,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, bool relock = false; ssize_t ret; - if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iter->iov, - offset, iter->nr_segs)) + if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iter, offset)) return 0; atomic_inc(&inode->i_dio_count); |