From 17f8c842d24ac054e4212c82b5bd6ae455a334f3 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Mar 2015 04:33:50 -0700 Subject: Remove rw from {,__,do_}blockdev_direct_IO() Most filesystems call through to these at some point, so we'll start here. Signed-off-by: Omar Sandoval Signed-off-by: Al Viro --- fs/ocfs2/aops.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index e1bf18c5d25e..68cb199fb2b6 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -738,10 +738,9 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb, di_bh = NULL; } - written = __blockdev_direct_IO(WRITE, iocb, inode, inode->i_sb->s_bdev, - iter, offset, - ocfs2_direct_IO_get_blocks, - ocfs2_dio_end_io, NULL, 0); + written = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter, + offset, ocfs2_direct_IO_get_blocks, + ocfs2_dio_end_io, NULL, 0); if (unlikely(written < 0)) { loff_t i_size = i_size_read(inode); @@ -844,11 +843,10 @@ static ssize_t ocfs2_direct_IO(int rw, return 0; if (rw == READ) - return __blockdev_direct_IO(rw, iocb, inode, - inode->i_sb->s_bdev, - iter, offset, - ocfs2_direct_IO_get_blocks, - ocfs2_dio_end_io, NULL, 0); + return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, + iter, offset, + ocfs2_direct_IO_get_blocks, + ocfs2_dio_end_io, NULL, 0); else return ocfs2_direct_IO_write(iocb, iter, offset); } -- cgit v1.2.3-59-g8ed1b From 6f67376318abea58589ebe6d69dffeabb6f6c26a Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Mar 2015 04:33:52 -0700 Subject: direct_IO: use iov_iter_rw() instead of rw everywhere The rw parameter to direct_IO is redundant with iov_iter->type, and treated slightly differently just about everywhere it's used: some users do rw & WRITE, and others do rw == WRITE where they should be doing a bitwise check. Simplify this with the new iov_iter_rw() helper, which always returns either READ or WRITE. Signed-off-by: Omar Sandoval Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/rw26.c | 18 +++++++++--------- fs/9p/vfs_addr.c | 2 +- fs/affs/file.c | 4 ++-- fs/btrfs/inode.c | 10 +++++----- fs/ext2/inode.c | 2 +- fs/ext3/inode.c | 8 ++++---- fs/ext4/ext4.h | 4 ++-- fs/ext4/indirect.c | 10 +++++----- fs/ext4/inode.c | 20 ++++++++++---------- fs/f2fs/data.c | 16 ++++++++-------- fs/fat/inode.c | 4 ++-- fs/fuse/file.c | 13 +++++++------ fs/gfs2/aops.c | 7 +++---- fs/hfs/inode.c | 2 +- fs/hfsplus/inode.c | 2 +- fs/jfs/inode.c | 2 +- fs/nfs/direct.c | 2 +- fs/nilfs2/inode.c | 4 ++-- fs/ocfs2/aops.c | 2 +- fs/reiserfs/inode.c | 2 +- fs/udf/inode.c | 2 +- fs/xfs/xfs_aops.c | 2 +- 22 files changed, 69 insertions(+), 69 deletions(-) (limited to 'fs/ocfs2') diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 2f21304046aa..3aa9de6bcc40 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -399,7 +399,7 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, * size changing by concurrent truncates and writes. * 1. Need inode mutex to operate transient pages. */ - if (rw == READ) + if (iov_iter_rw(iter) == READ) mutex_lock(&inode->i_mutex); LASSERT(obj->cob_transient_pages == 0); @@ -408,7 +408,7 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, size_t offs; count = min_t(size_t, iov_iter_count(iter), size); - if (rw == READ) { + if (iov_iter_rw(iter) == READ) { if (file_offset >= i_size_read(inode)) break; if (file_offset + count > i_size_read(inode)) @@ -418,11 +418,11 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, result = iov_iter_get_pages_alloc(iter, &pages, count, &offs); if (likely(result > 0)) { int n = DIV_ROUND_UP(result + offs, PAGE_SIZE); - result = ll_direct_IO_26_seg(env, io, rw, inode, - file->f_mapping, - result, file_offset, - pages, n); - ll_free_user_pages(pages, n, rw==READ); + result = ll_direct_IO_26_seg(env, io, iov_iter_rw(iter), + inode, file->f_mapping, + result, file_offset, pages, + n); + ll_free_user_pages(pages, n, iov_iter_rw(iter) == READ); } if (unlikely(result <= 0)) { /* If we can't allocate a large enough buffer @@ -449,11 +449,11 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, } out: LASSERT(obj->cob_transient_pages == 0); - if (rw == READ) + if (iov_iter_rw(iter) == READ) mutex_unlock(&inode->i_mutex); if (tot_bytes > 0) { - if (rw == WRITE) { + if (iov_iter_rw(iter) == WRITE) { struct lov_stripe_md *lsm; lsm = ccc_inode_lsm_get(inode); diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 2e38f9a5b472..dd5543b1d183 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -253,7 +253,7 @@ v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) struct file *file = iocb->ki_filp; ssize_t n; int err = 0; - if (rw & WRITE) { + if (iov_iter_rw(iter) == WRITE) { n = p9_client_write(file->private_data, pos, iter, &err); if (n) { struct inode *inode = file_inode(file); diff --git a/fs/affs/file.c b/fs/affs/file.c index 1edc0d4b40db..7f05a468d594 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -398,7 +398,7 @@ affs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, size_t count = iov_iter_count(iter); ssize_t ret; - if (rw == WRITE) { + if (iov_iter_rw(iter) == WRITE) { loff_t size = offset + count; if (AFFS_I(inode)->mmu_private < size) @@ -406,7 +406,7 @@ affs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, } ret = blockdev_direct_IO(iocb, inode, iter, offset, affs_get_block); - if (ret < 0 && (rw & WRITE)) + if (ret < 0 && iov_iter_rw(iter) == WRITE) affs_write_failed(mapping, offset + count); return ret; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e9a3ff8a85fd..ca69e83d4f3c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8081,7 +8081,7 @@ free_ordered: bio_endio(dio_bio, ret); } -static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, +static ssize_t check_direct_IO(struct btrfs_root *root, struct kiocb *iocb, const struct iov_iter *iter, loff_t offset) { int seg; @@ -8096,7 +8096,7 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io goto out; /* If this is a write we don't need to check anymore */ - if (rw & WRITE) + if (iov_iter_rw(iter) == WRITE) return 0; /* * Check to make sure we don't have duplicate iov_base's in this @@ -8126,7 +8126,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, offset)) + if (check_direct_IO(BTRFS_I(inode)->root, iocb, iter, offset)) return 0; atomic_inc(&inode->i_dio_count); @@ -8144,7 +8144,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, filemap_fdatawrite_range(inode->i_mapping, offset, offset + count - 1); - if (rw & WRITE) { + if (iov_iter_rw(iter) == WRITE) { /* * If the write DIO is beyond the EOF, we need update * the isize, but it is protected by i_mutex. So we can @@ -8178,7 +8178,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, iter, offset, btrfs_get_blocks_direct, NULL, btrfs_submit_direct, flags); - if (rw & WRITE) { + if (iov_iter_rw(iter) == WRITE) { current->journal_info = NULL; if (ret < 0 && ret != -EIOCBQUEUED) btrfs_delalloc_release_space(inode, count); diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 14e8d1752685..685e514c57dd 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -866,7 +866,7 @@ ext2_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, else ret = blockdev_direct_IO(iocb, inode, iter, offset, ext2_get_block); - if (ret < 0 && (rw & WRITE)) + if (ret < 0 && iov_iter_rw(iter) == WRITE) ext2_write_failed(mapping, offset + count); return ret; } diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 6fb376c8d938..c70839d26ccd 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1832,9 +1832,9 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, size_t count = iov_iter_count(iter); int retries = 0; - trace_ext3_direct_IO_enter(inode, offset, count, rw); + trace_ext3_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); - if (rw == WRITE) { + if (iov_iter_rw(iter) == WRITE) { loff_t final_size = offset + count; if (final_size > inode->i_size) { @@ -1861,7 +1861,7 @@ retry: * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ - if (unlikely((rw & WRITE) && ret < 0)) { + if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + count; @@ -1908,7 +1908,7 @@ retry: ret = err; } out: - trace_ext3_direct_IO_exit(inode, offset, count, rw, ret); + trace_ext3_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), ret); return ret; } diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index f63c3d5805c4..2031c994024e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2152,8 +2152,8 @@ extern void ext4_da_update_reserve_space(struct inode *inode, /* indirect.c */ extern int ext4_ind_map_blocks(handle_t *handle, struct inode *inode, struct ext4_map_blocks *map, int flags); -extern ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset); +extern ssize_t ext4_ind_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset); extern int ext4_ind_calc_metadata_amount(struct inode *inode, sector_t lblock); extern int ext4_ind_trans_blocks(struct inode *inode, int nrblocks); extern void ext4_ind_truncate(handle_t *, struct inode *inode); diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index cd81d01da0b0..3580629e42d3 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -642,8 +642,8 @@ out: * crashes then stale disk data _may_ be exposed inside the file. But current * VFS code falls back into buffered path in that case so we are safe. */ -ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +ssize_t ext4_ind_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; @@ -654,7 +654,7 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb, size_t count = iov_iter_count(iter); int retries = 0; - if (rw == WRITE) { + if (iov_iter_rw(iter) == WRITE) { loff_t final_size = offset + count; if (final_size > inode->i_size) { @@ -676,7 +676,7 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb, } retry: - if (rw == READ && ext4_should_dioread_nolock(inode)) { + if (iov_iter_rw(iter) == READ && ext4_should_dioread_nolock(inode)) { /* * Nolock dioread optimization may be dynamically disabled * via ext4_inode_block_unlocked_dio(). Check inode's state @@ -707,7 +707,7 @@ locked: ret = blockdev_direct_IO(iocb, inode, iter, offset, ext4_get_block); - if (unlikely((rw & WRITE) && ret < 0)) { + if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + count; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 76b8cba5d041..cf6ba6536035 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2952,8 +2952,8 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, * if the machine crashes during the write. * */ -static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; @@ -2966,8 +2966,8 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, ext4_io_end_t *io_end = NULL; /* Use the old path for reads and writes beyond i_size. */ - if (rw != WRITE || final_size > inode->i_size) - return ext4_ind_direct_IO(rw, iocb, iter, offset); + if (iov_iter_rw(iter) != WRITE || final_size > inode->i_size) + return ext4_ind_direct_IO(iocb, iter, offset); BUG_ON(iocb->private == NULL); @@ -2976,7 +2976,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, * conversion. This also disallows race between truncate() and * overwrite DIO as i_dio_count needs to be incremented under i_mutex. */ - if (rw == WRITE) + if (iov_iter_rw(iter) == WRITE) atomic_inc(&inode->i_dio_count); /* If we do a overwrite dio, i_mutex locking can be released */ @@ -3078,7 +3078,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, } retake_lock: - if (rw == WRITE) + if (iov_iter_rw(iter) == WRITE) inode_dio_done(inode); /* take i_mutex locking again if we do a ovewrite dio */ if (overwrite) { @@ -3107,12 +3107,12 @@ static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb, if (ext4_has_inline_data(inode)) return 0; - trace_ext4_direct_IO_enter(inode, offset, count, rw); + trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) - ret = ext4_ext_direct_IO(rw, iocb, iter, offset); + ret = ext4_ext_direct_IO(iocb, iter, offset); else - ret = ext4_ind_direct_IO(rw, iocb, iter, offset); - trace_ext4_direct_IO_exit(inode, offset, count, rw, ret); + ret = ext4_ind_direct_IO(iocb, iter, offset); + trace_ext4_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), ret); return ret; } diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index e16adebcb9b6..ce25f62edfa7 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1118,12 +1118,12 @@ static int f2fs_write_end(struct file *file, return copied; } -static int check_direct_IO(struct inode *inode, int rw, - struct iov_iter *iter, loff_t offset) +static int check_direct_IO(struct inode *inode, struct iov_iter *iter, + loff_t offset) { unsigned blocksize_mask = inode->i_sb->s_blocksize - 1; - if (rw == READ) + if (iov_iter_rw(iter) == READ) return 0; if (offset & blocksize_mask) @@ -1151,19 +1151,19 @@ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb, return err; } - if (check_direct_IO(inode, rw, iter, offset)) + if (check_direct_IO(inode, iter, offset)) return 0; - trace_f2fs_direct_IO_enter(inode, offset, count, rw); + trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); - if (rw & WRITE) + if (iov_iter_rw(iter) == WRITE) __allocate_data_blocks(inode, offset, count); err = blockdev_direct_IO(iocb, inode, iter, offset, get_data_block); - if (err < 0 && (rw & WRITE)) + if (err < 0 && iov_iter_rw(iter) == WRITE) f2fs_write_failed(mapping, offset + count); - trace_f2fs_direct_IO_exit(inode, offset, count, rw, err); + trace_f2fs_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), err); return err; } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index a1a39f571e78..342d791b28db 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -255,7 +255,7 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, size_t count = iov_iter_count(iter); ssize_t ret; - if (rw == WRITE) { + if (iov_iter_rw(iter) == WRITE) { /* * FIXME: blockdev_direct_IO() doesn't use ->write_begin(), * so we need to update the ->mmu_private to block boundary. @@ -275,7 +275,7 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, * condition of fat_get_block() and ->truncate(). */ ret = blockdev_direct_IO(iocb, inode, iter, offset, fat_get_block); - if (ret < 0 && (rw & WRITE)) + if (ret < 0 && iov_iter_rw(iter) == WRITE) fat_write_failed(mapping, offset + count); return ret; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e1afdd7abf90..c1a67da6a8a0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2800,11 +2800,11 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, inode = file->f_mapping->host; i_size = i_size_read(inode); - if ((rw == READ) && (offset > i_size)) + if ((iov_iter_rw(iter) == READ) && (offset > i_size)) return 0; /* optimization for short read */ - if (async_dio && rw != WRITE && offset + count > i_size) { + if (async_dio && iov_iter_rw(iter) != WRITE && offset + count > i_size) { if (offset >= i_size) return 0; count = min_t(loff_t, count, fuse_round_up(i_size - offset)); @@ -2819,7 +2819,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, io->bytes = -1; io->size = 0; io->offset = offset; - io->write = (rw == WRITE); + io->write = (iov_iter_rw(iter) == WRITE); io->err = 0; io->file = file; /* @@ -2834,13 +2834,14 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, * to wait on real async I/O requests, so we must submit this request * synchronously. */ - if (!is_sync_kiocb(iocb) && (offset + count > i_size) && rw == WRITE) + if (!is_sync_kiocb(iocb) && (offset + count > i_size) && + iov_iter_rw(iter) == WRITE) io->async = false; if (io->async && is_sync_kiocb(iocb)) io->done = &wait; - if (rw == WRITE) { + if (iov_iter_rw(iter) == WRITE) { ret = generic_write_checks(file, &pos, &count, 0); if (!ret) { iov_iter_truncate(iter, count); @@ -2865,7 +2866,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, kfree(io); - if (rw == WRITE) { + if (iov_iter_rw(iter) == WRITE) { if (ret > 0) fuse_write_update_size(inode, pos); else if (ret < 0 && offset + count > i_size) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 59983a18cab4..e22e6e686a11 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -1016,13 +1016,12 @@ out: /** * gfs2_ok_for_dio - check that dio is valid on this file * @ip: The inode - * @rw: READ or WRITE * @offset: The offset at which we are reading or writing * * Returns: 0 (to ignore the i/o request and thus fall back to buffered i/o) * 1 (to accept the i/o request) */ -static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset) +static int gfs2_ok_for_dio(struct gfs2_inode *ip, loff_t offset) { /* * Should we return an error here? I can't see that O_DIRECT for @@ -1061,7 +1060,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, rv = gfs2_glock_nq(&gh); if (rv) return rv; - rv = gfs2_ok_for_dio(ip, rw, offset); + rv = gfs2_ok_for_dio(ip, offset); if (rv != 1) goto out; /* dio not valid, fall back to buffered i/o */ @@ -1091,7 +1090,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, rv = filemap_write_and_wait_range(mapping, lstart, end); if (rv) goto out; - if (rw == WRITE) + if (iov_iter_rw(iter) == WRITE) truncate_inode_pages_range(mapping, lstart, end); } diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index e92d175d1fd7..0085d527a55c 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -139,7 +139,7 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb, * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ - if (unlikely((rw & WRITE) && ret < 0)) { + if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + count; diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 2a98dc07c22c..afcde36b506b 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -137,7 +137,7 @@ static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb, * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ - if (unlikely((rw & WRITE) && ret < 0)) { + if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + count; diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index c20f7883543f..e7047b63ffc5 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -345,7 +345,7 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb, * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ - if (unlikely((rw & WRITE) && ret < 0)) { + if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + count; diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index c3929fb2ab26..e8482b8f4830 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -267,7 +267,7 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t #else VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE); - if (rw == READ) + if (iov_iter_rw(iter) == READ) return nfs_file_direct_read(iocb, iter, pos); return nfs_file_direct_write(iocb, iter, pos); #endif /* CONFIG_NFS_SWAP */ diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 3727b8caa46e..4726f1493d5d 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -314,7 +314,7 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, size_t count = iov_iter_count(iter); ssize_t size; - if (rw == WRITE) + if (iov_iter_rw(iter) == WRITE) return 0; /* Needs synchronization with the cleaner */ @@ -324,7 +324,7 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ - if (unlikely((rw & WRITE) && size < 0)) { + if (unlikely(iov_iter_rw(iter) == WRITE && size < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + count; diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 68cb199fb2b6..0ee9474cca46 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -842,7 +842,7 @@ static ssize_t ocfs2_direct_IO(int rw, if (i_size_read(inode) <= offset && !full_coherency) return 0; - if (rw == READ) + if (iov_iter_rw(iter) == READ) return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter, offset, ocfs2_direct_IO_get_blocks, diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a51e9177b056..d61ab13244a8 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -3293,7 +3293,7 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb, * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ - if (unlikely((rw & WRITE) && ret < 0)) { + if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + count; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 3adf49c01c19..a685aea93068 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -226,7 +226,7 @@ static ssize_t udf_direct_IO(int rw, struct kiocb *iocb, ssize_t ret; ret = blockdev_direct_IO(iocb, inode, iter, offset, udf_get_block); - if (unlikely(ret < 0 && (rw & WRITE))) + if (unlikely(ret < 0 && iov_iter_rw(iter) == WRITE)) udf_write_failed(mapping, offset + count); return ret; } diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 5ca504c66e85..532d5279df2f 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1503,7 +1503,7 @@ xfs_vm_direct_IO( struct inode *inode = iocb->ki_filp->f_mapping->host; struct block_device *bdev = xfs_find_bdev_for_inode(inode); - if (rw & WRITE) { + if (iov_iter_rw(iter) == WRITE) { return __blockdev_direct_IO(iocb, inode, bdev, iter, offset, xfs_get_blocks_direct, xfs_end_io_direct_write, NULL, -- cgit v1.2.3-59-g8ed1b From 22c6186ecea0be9eff1c399298ad36e94a59995f Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Mar 2015 04:33:53 -0700 Subject: direct_IO: remove rw from a_ops->direct_IO() Now that no one is using rw, remove it completely. Signed-off-by: Omar Sandoval Signed-off-by: Al Viro --- Documentation/filesystems/Locking | 2 +- Documentation/filesystems/vfs.txt | 2 +- drivers/staging/lustre/lustre/llite/rw26.c | 4 ++-- fs/9p/vfs_addr.c | 3 +-- fs/affs/file.c | 3 +-- fs/block_dev.c | 3 +-- fs/btrfs/inode.c | 4 ++-- fs/ceph/addr.c | 3 +-- fs/cifs/file.c | 3 +-- fs/exofs/inode.c | 4 ++-- fs/ext2/inode.c | 3 +-- fs/ext3/inode.c | 4 ++-- fs/ext4/inode.c | 4 ++-- fs/f2fs/data.c | 4 ++-- fs/fat/inode.c | 3 +-- fs/fuse/file.c | 3 +-- fs/gfs2/aops.c | 4 ++-- fs/hfs/inode.c | 4 ++-- fs/hfsplus/inode.c | 4 ++-- fs/jfs/inode.c | 4 ++-- fs/nfs/direct.c | 3 +-- fs/nilfs2/inode.c | 3 +-- fs/ocfs2/aops.c | 4 +--- fs/reiserfs/inode.c | 4 ++-- fs/udf/file.c | 3 +-- fs/udf/inode.c | 3 +-- fs/xfs/xfs_aops.c | 1 - include/linux/fs.h | 2 +- include/linux/nfs_fs.h | 2 +- mm/filemap.c | 4 ++-- mm/page_io.c | 4 +--- 31 files changed, 42 insertions(+), 59 deletions(-) (limited to 'fs/ocfs2') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index c3cd6279e92e..7cdbca44e343 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -196,7 +196,7 @@ prototypes: void (*invalidatepage) (struct page *, unsigned int, unsigned int); int (*releasepage) (struct page *, int); void (*freepage)(struct page *); - int (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset); + int (*direct_IO)(struct kiocb *, struct iov_iter *iter, loff_t offset); int (*migratepage)(struct address_space *, struct page *, struct page *); int (*launder_page)(struct page *); int (*is_partially_uptodate)(struct page *, unsigned long, unsigned long); diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 207cdca68bed..5d833b32bbcd 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -590,7 +590,7 @@ struct address_space_operations { void (*invalidatepage) (struct page *, unsigned int, unsigned int); int (*releasepage) (struct page *, int); void (*freepage)(struct page *); - ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset); + ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter, loff_t offset); /* migrate the contents of a page to the specified target */ int (*migratepage) (struct page *, struct page *); int (*launder_page) (struct page *); diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 3aa9de6bcc40..0d7ce6b0e23c 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -359,8 +359,8 @@ static ssize_t ll_direct_IO_26_seg(const struct lu_env *env, struct cl_io *io, * up to 22MB for 128kB kmalloc and up to 682MB for 4MB kmalloc. */ #define MAX_DIO_SIZE ((MAX_MALLOC / sizeof(struct brw_page) * PAGE_CACHE_SIZE) & \ ~(DT_MAX_BRW_SIZE - 1)) -static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t file_offset) +static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter, + loff_t file_offset) { struct lu_env *env; struct cl_io *io; diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index dd5543b1d183..be35d05a4d0e 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -230,7 +230,6 @@ static int v9fs_launder_page(struct page *page) /** * v9fs_direct_IO - 9P address space operation for direct I/O - * @rw: direction (read or write) * @iocb: target I/O control block * @iov: array of vectors that define I/O buffer * @pos: offset in file to begin the operation @@ -248,7 +247,7 @@ static int v9fs_launder_page(struct page *page) * */ static ssize_t -v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) +v9fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; ssize_t n; diff --git a/fs/affs/file.c b/fs/affs/file.c index 7f05a468d594..dcf27951781c 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -389,8 +389,7 @@ static void affs_write_failed(struct address_space *mapping, loff_t to) } static ssize_t -affs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, - loff_t offset) +affs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; diff --git a/fs/block_dev.c b/fs/block_dev.c index bc23afd35fdb..6e3de63c3055 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -146,8 +146,7 @@ blkdev_get_block(struct inode *inode, sector_t iblock, } static ssize_t -blkdev_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, - loff_t offset) +blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ca69e83d4f3c..43192e10cc43 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8114,8 +8114,8 @@ out: return retval; } -static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index fd5599d32362..155ab9c0246b 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -1198,8 +1198,7 @@ static int ceph_write_end(struct file *file, struct address_space *mapping, * intercept O_DIRECT reads and writes early, this function should * never get called. */ -static ssize_t ceph_direct_io(int rw, struct kiocb *iocb, - struct iov_iter *iter, +static ssize_t ceph_direct_io(struct kiocb *iocb, struct iov_iter *iter, loff_t pos) { WARN_ON(1); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ca30c391a894..72394c5abd0f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3877,8 +3877,7 @@ void cifs_oplock_break(struct work_struct *work) * Direct IO is not yet supported in the cached mode. */ static ssize_t -cifs_direct_io(int rw, struct kiocb *iocb, struct iov_iter *iter, - loff_t pos) +cifs_direct_io(struct kiocb *iocb, struct iov_iter *iter, loff_t pos) { /* * FIXME diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index a198e94813fe..35073aaec6e0 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -963,8 +963,8 @@ static void exofs_invalidatepage(struct page *page, unsigned int offset, /* TODO: Should be easy enough to do proprly */ -static ssize_t exofs_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t exofs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { return 0; } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 685e514c57dd..e1abf75e994c 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -851,8 +851,7 @@ static sector_t ext2_bmap(struct address_space *mapping, sector_t block) } static ssize_t -ext2_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, - loff_t offset) +ext2_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index c70839d26ccd..13c0868c7160 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1820,8 +1820,8 @@ static int ext3_releasepage(struct page *page, gfp_t wait) * crashes then stale disk data _may_ be exposed inside the file. But current * VFS code falls back into buffered path in that case so we are safe. */ -static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t ext3_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index cf6ba6536035..42c942a950e1 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3089,8 +3089,8 @@ retake_lock: return ret; } -static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index ce25f62edfa7..319eda511c4f 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1135,8 +1135,8 @@ static int check_direct_IO(struct inode *inode, struct iov_iter *iter, return 0; } -static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 342d791b28db..41b729933638 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -245,8 +245,7 @@ static int fat_write_end(struct file *file, struct address_space *mapping, return err; } -static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, +static ssize_t fat_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c1a67da6a8a0..3d355e946991 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2782,8 +2782,7 @@ static inline loff_t fuse_round_up(loff_t off) } static ssize_t -fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, - loff_t offset) +fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { DECLARE_COMPLETION_ONSTACK(wait); ssize_t ret = 0; diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index e22e6e686a11..20dd33da92de 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -1038,8 +1038,8 @@ static int gfs2_ok_for_dio(struct gfs2_inode *ip, loff_t offset) -static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t gfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 0085d527a55c..75fd5d873c19 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -124,8 +124,8 @@ static int hfs_releasepage(struct page *page, gfp_t mask) return res ? try_to_free_buffers(page) : 0; } -static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t hfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index afcde36b506b..a43811f90935 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -122,8 +122,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) return res ? try_to_free_buffers(page) : 0; } -static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t hfsplus_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index e7047b63ffc5..070dc4b33544 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -330,8 +330,8 @@ static sector_t jfs_bmap(struct address_space *mapping, sector_t block) return generic_block_bmap(mapping, block, jfs_get_block); } -static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t jfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index e8482b8f4830..06503bc604e1 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -240,7 +240,6 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, /** * nfs_direct_IO - NFS address space operation for direct I/O - * @rw: direction (read or write) * @iocb: target I/O control block * @iov: array of vectors that define I/O buffer * @pos: offset in file to begin the operation @@ -251,7 +250,7 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, * shunt off direct read and write requests before the VFS gets them, * so this method is only ever called for swap. */ -ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) +ssize_t nfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t pos) { struct inode *inode = iocb->ki_filp->f_mapping->host; diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 4726f1493d5d..36f057fa8aa3 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -305,8 +305,7 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping, } static ssize_t -nilfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, - loff_t offset) +nilfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 0ee9474cca46..28b5ad81bbec 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -818,9 +818,7 @@ out: return ret; } -static ssize_t ocfs2_direct_IO(int rw, - struct kiocb *iocb, - struct iov_iter *iter, +static ssize_t ocfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index d61ab13244a8..742242b60972 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -3278,8 +3278,8 @@ static int reiserfs_releasepage(struct page *page, gfp_t unused_gfp_flags) * We thank Mingming Cao for helping us understand in great detail what * to do in this section of the code. */ -static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, loff_t offset) +static ssize_t reiserfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; diff --git a/fs/udf/file.c b/fs/udf/file.c index 74050bff64f4..78d42548b260 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -100,8 +100,7 @@ static int udf_adinicb_write_begin(struct file *file, return 0; } -static ssize_t udf_adinicb_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, +static ssize_t udf_adinicb_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { /* Fallback to buffered I/O. */ diff --git a/fs/udf/inode.c b/fs/udf/inode.c index a685aea93068..4f178c83b04f 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -215,8 +215,7 @@ static int udf_write_begin(struct file *file, struct address_space *mapping, return ret; } -static ssize_t udf_direct_IO(int rw, struct kiocb *iocb, - struct iov_iter *iter, +static ssize_t udf_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 532d5279df2f..1d8eef9cf0f5 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1495,7 +1495,6 @@ xfs_end_io_direct_write( STATIC ssize_t xfs_vm_direct_IO( - int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t offset) diff --git a/include/linux/fs.h b/include/linux/fs.h index 295bc589fe1b..72e3759de8c3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -383,7 +383,7 @@ struct address_space_operations { void (*invalidatepage) (struct page *, unsigned int, unsigned int); int (*releasepage) (struct page *, gfp_t); void (*freepage)(struct page *); - ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset); + ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter, loff_t offset); /* * migrate the contents of a page to the specified target. If * migrate_mode is MIGRATE_ASYNC, it must not block. diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index b01ccf371fdc..3d1b0d2fe55e 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -447,7 +447,7 @@ static inline struct rpc_cred *nfs_file_cred(struct file *file) /* * linux/fs/nfs/direct.c */ -extern ssize_t nfs_direct_IO(int, struct kiocb *, struct iov_iter *, loff_t); +extern ssize_t nfs_direct_IO(struct kiocb *, struct iov_iter *, loff_t); extern ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter, loff_t pos); diff --git a/mm/filemap.c b/mm/filemap.c index 876f4e6f3ed6..9920db455f05 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1707,7 +1707,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) pos + count - 1); if (!retval) { struct iov_iter data = *iter; - retval = mapping->a_ops->direct_IO(READ, iocb, &data, pos); + retval = mapping->a_ops->direct_IO(iocb, &data, pos); } if (retval > 0) { @@ -2395,7 +2395,7 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos) } data = *from; - written = mapping->a_ops->direct_IO(WRITE, iocb, &data, pos); + written = mapping->a_ops->direct_IO(iocb, &data, pos); /* * Finally, try again to invalidate clean pages which might have been diff --git a/mm/page_io.c b/mm/page_io.c index a96c8562d835..6424869e275e 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -277,9 +277,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc, set_page_writeback(page); unlock_page(page); - ret = mapping->a_ops->direct_IO(ITER_BVEC | WRITE, - &kiocb, &from, - kiocb.ki_pos); + ret = mapping->a_ops->direct_IO(&kiocb, &from, kiocb.ki_pos); if (ret == PAGE_SIZE) { count_vm_event(PSWPOUT); ret = 0; -- cgit v1.2.3-59-g8ed1b From 0fa6b005afdb3152ce85df963302e59b61115f9b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 4 Apr 2015 04:05:48 -0400 Subject: generic_write_checks(): drop isblk argument all remaining callers are passing 0; some just obscure that fact. Signed-off-by: Al Viro --- fs/9p/vfs_file.c | 2 +- fs/btrfs/file.c | 2 +- fs/ceph/file.c | 2 +- fs/cifs/file.c | 4 ++-- fs/ext4/file.c | 2 +- fs/fuse/file.c | 6 +++--- fs/ncpfs/file.c | 2 +- fs/nfs/direct.c | 2 +- fs/ntfs/file.c | 2 +- fs/ocfs2/file.c | 3 +-- fs/udf/file.c | 2 +- fs/xfs/xfs_file.c | 2 +- include/linux/fs.h | 2 +- mm/filemap.c | 63 +++++++++++++++++------------------------------------- 14 files changed, 36 insertions(+), 60 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index d7fcb775311e..b5b020ace1b3 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -409,7 +409,7 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) size_t count = iov_iter_count(from); int err = 0; - retval = generic_write_checks(file, &origin, &count, 0); + retval = generic_write_checks(file, &origin, &count); if (retval) return retval; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index cdc801c85105..691a84a81e09 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1747,7 +1747,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, mutex_lock(&inode->i_mutex); current->backing_dev_info = inode_to_bdi(inode); - err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); + err = generic_write_checks(file, &pos, &count); if (err) { mutex_unlock(&inode->i_mutex); goto out; diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 56237ea5fc22..761841903160 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -953,7 +953,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) /* We can write back this queue in page reclaim */ current->backing_dev_info = inode_to_bdi(inode); - err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); + err = generic_write_checks(file, &pos, &count); if (err) goto out; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 3c5c9bc5cbaf..4202e74b2db5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2580,7 +2580,7 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from) */ len = iov_iter_count(from); - rc = generic_write_checks(file, &iocb->ki_pos, &len, 0); + rc = generic_write_checks(file, &iocb->ki_pos, &len); if (rc) return rc; @@ -2684,7 +2684,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) mutex_lock(&inode->i_mutex); count = iov_iter_count(from); - rc = generic_write_checks(file, &iocb->ki_pos, &count, 0); + rc = generic_write_checks(file, &iocb->ki_pos, &count); if (rc) goto out; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index f7cca423dded..1f0afc181b7b 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -171,7 +171,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) } } - ret = generic_write_checks(file, &iocb->ki_pos, &length, 0); + ret = generic_write_checks(file, &iocb->ki_pos, &length); if (ret) goto out; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3d355e946991..4c04a8144a75 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1167,7 +1167,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) /* We can write back this queue in page reclaim */ current->backing_dev_info = inode_to_bdi(inode); - err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); + err = generic_write_checks(file, &pos, &count); if (err) goto out; @@ -1420,7 +1420,7 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from) /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); - res = generic_write_checks(file, &iocb->ki_pos, &count, 0); + res = generic_write_checks(file, &iocb->ki_pos, &count); if (!res) { iov_iter_truncate(from, count); res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE); @@ -2841,7 +2841,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) io->done = &wait; if (iov_iter_rw(iter) == WRITE) { - ret = generic_write_checks(file, &pos, &count, 0); + ret = generic_write_checks(file, &pos, &count); if (!ret) { iov_iter_truncate(iter, count); ret = fuse_direct_io(io, iter, &pos, FUSE_DIO_WRITE); diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 479bf8db264e..ab6363b16556 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -177,7 +177,7 @@ ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from) void *bouncebuffer; ncp_dbg(1, "enter %pD2\n", file); - errno = generic_write_checks(file, &pos, &count, 0); + errno = generic_write_checks(file, &pos, &count); if (errno) return errno; iov_iter_truncate(from, count); diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 06503bc604e1..5ddd77acb3f7 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -977,7 +977,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n", file, count, (long long) pos); - result = generic_write_checks(file, &pos, &count, 0); + result = generic_write_checks(file, &pos, &count); if (result) goto out; diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 77087d5ad458..cec4ec3c1ede 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -345,7 +345,7 @@ static ssize_t ntfs_prepare_file_for_write(struct kiocb *iocb, "0x%llx, count 0x%zx.", vi->i_ino, (unsigned)le32_to_cpu(ni->type), (unsigned long long)iocb->ki_pos, count); - err = generic_write_checks(file, &iocb->ki_pos, &count, S_ISBLK(vi->i_mode)); + err = generic_write_checks(file, &iocb->ki_pos, &count); if (unlikely(err)) goto out; iov_iter_truncate(from, count); diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 0a6ec7e6efd8..1c11314946cb 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2374,8 +2374,7 @@ relock: /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb, rw_level); - ret = generic_write_checks(file, ppos, &count, - S_ISBLK(inode->i_mode)); + ret = generic_write_checks(file, ppos, &count); if (ret) goto out_dio; diff --git a/fs/udf/file.c b/fs/udf/file.c index 35e81ed99405..6834509a7e5a 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -151,7 +151,7 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from) } else up_write(&iinfo->i_data_sem); - retval = generic_write_checks(file, &iocb->ki_pos, &count, 0); + retval = generic_write_checks(file, &iocb->ki_pos, &count); if (retval) goto out; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 44856c3b9617..43c0e6686c47 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -554,7 +554,7 @@ xfs_file_aio_write_checks( int error = 0; restart: - error = generic_write_checks(file, pos, count, S_ISBLK(inode->i_mode)); + error = generic_write_checks(file, pos, count); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 72e3759de8c3..492948ea4c9b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2566,7 +2566,7 @@ extern int sb_min_blocksize(struct super_block *, int); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); -int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); +int generic_write_checks(struct file *file, loff_t *pos, size_t *count); extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); diff --git a/mm/filemap.c b/mm/filemap.c index a794a7f98743..dfc573c6ec25 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2260,7 +2260,7 @@ EXPORT_SYMBOL(read_cache_page_gfp); * Returns appropriate error code that caller should return or * zero in case that write should be allowed. */ -inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk) +inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count) { struct inode *inode = file->f_mapping->host; unsigned long limit = rlimit(RLIMIT_FSIZE); @@ -2268,20 +2268,17 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i if (unlikely(*pos < 0)) return -EINVAL; - if (!isblk) { - /* FIXME: this is for backwards compatibility with 2.4 */ - if (file->f_flags & O_APPEND) - *pos = i_size_read(inode); + /* FIXME: this is for backwards compatibility with 2.4 */ + if (file->f_flags & O_APPEND) + *pos = i_size_read(inode); - if (limit != RLIM_INFINITY) { - if (*pos >= limit) { - send_sig(SIGXFSZ, current, 0); - return -EFBIG; - } - if (*count > limit - (typeof(limit))*pos) { - *count = limit - (typeof(limit))*pos; - } + if (limit != RLIM_INFINITY) { + if (*pos >= limit) { + send_sig(SIGXFSZ, current, 0); + return -EFBIG; } + if (*count > limit - (typeof(limit))*pos) + *count = limit - (typeof(limit))*pos; } /* @@ -2289,12 +2286,10 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i */ if (unlikely(*pos + *count > MAX_NON_LFS && !(file->f_flags & O_LARGEFILE))) { - if (*pos >= MAX_NON_LFS) { + if (*pos >= MAX_NON_LFS) return -EFBIG; - } - if (*count > MAX_NON_LFS - (unsigned long)*pos) { + if (*count > MAX_NON_LFS - (unsigned long)*pos) *count = MAX_NON_LFS - (unsigned long)*pos; - } } /* @@ -2304,33 +2299,15 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i * exceeded without writing data we send a signal and return EFBIG. * Linus frestrict idea will clean these up nicely.. */ - if (likely(!isblk)) { - if (unlikely(*pos >= inode->i_sb->s_maxbytes)) { - if (*count || *pos > inode->i_sb->s_maxbytes) { - return -EFBIG; - } - /* zero-length writes at ->s_maxbytes are OK */ - } - - if (unlikely(*pos + *count > inode->i_sb->s_maxbytes)) - *count = inode->i_sb->s_maxbytes - *pos; - } else { -#ifdef CONFIG_BLOCK - loff_t isize; - if (bdev_read_only(I_BDEV(inode))) - return -EPERM; - isize = i_size_read(inode); - if (*pos >= isize) { - if (*count || *pos > isize) - return -ENOSPC; + if (unlikely(*pos >= inode->i_sb->s_maxbytes)) { + if (*count || *pos > inode->i_sb->s_maxbytes) { + return -EFBIG; } - - if (*pos + *count > isize) - *count = isize - *pos; -#else - return -EPERM; -#endif + /* zero-length writes at ->s_maxbytes are OK */ } + + if (unlikely(*pos + *count > inode->i_sb->s_maxbytes)) + *count = inode->i_sb->s_maxbytes - *pos; return 0; } EXPORT_SYMBOL(generic_write_checks); @@ -2644,7 +2621,7 @@ ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from) size_t count = iov_iter_count(from); mutex_lock(&inode->i_mutex); - ret = generic_write_checks(file, &iocb->ki_pos, &count, 0); + ret = generic_write_checks(file, &iocb->ki_pos, &count); if (!ret && count) { iov_iter_truncate(from, count); ret = __generic_file_write_iter(iocb, from); -- cgit v1.2.3-59-g8ed1b From 5dc3161cb63265adca0c34fac79512af59b776a4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 9 Apr 2015 07:25:03 -0400 Subject: ocfs2_file_write_iter: stop messing with ppos it's &iocb->ki_pos; no need to obfuscate. Signed-off-by: Al Viro --- fs/ocfs2/file.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8096fb6c081b..78e245df5e32 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2264,7 +2264,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, int can_do_direct, has_refcount = 0; ssize_t written = 0; size_t count = iov_iter_count(from); - loff_t old_size, *ppos = &iocb->ki_pos; + loff_t old_size; u32 old_clusters; struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); @@ -2330,7 +2330,7 @@ relock: } can_do_direct = direct_io; - ret = ocfs2_prepare_inode_for_write(file, ppos, count, appending, + ret = ocfs2_prepare_inode_for_write(file, &iocb->ki_pos, count, appending, &can_do_direct, &has_refcount); if (ret < 0) { mlog_errno(ret); @@ -2338,7 +2338,7 @@ relock: } if (direct_io && !is_sync_kiocb(iocb)) - unaligned_dio = ocfs2_is_io_unaligned(inode, count, *ppos); + unaligned_dio = ocfs2_is_io_unaligned(inode, count, iocb->ki_pos); /* * We can't complete the direct I/O as requested, fall back to @@ -2374,7 +2374,7 @@ relock: /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb, rw_level); - ret = generic_write_checks(file, ppos, &count); + ret = generic_write_checks(file, &iocb->ki_pos, &count); if (ret) goto out_dio; @@ -2382,7 +2382,7 @@ relock: if (direct_io) { loff_t endbyte; ssize_t written_buffered; - written = generic_file_direct_write(iocb, from, *ppos); + written = generic_file_direct_write(iocb, from, iocb->ki_pos); if (written < 0 || written == count) { ret = written; goto out_dio; @@ -2392,7 +2392,7 @@ relock: * for completing the rest of the request. */ count -= written; - written_buffered = generic_perform_write(file, from, *ppos); + written_buffered = generic_perform_write(file, from, iocb->ki_pos); /* * If generic_file_buffered_write() returned a synchronous error * then we want to return the number of bytes which were @@ -2409,14 +2409,14 @@ relock: * disk and invalidated to preserve the expected O_DIRECT * semantics. */ - endbyte = *ppos + written_buffered - 1; - ret = filemap_write_and_wait_range(file->f_mapping, *ppos, + endbyte = iocb->ki_pos + written_buffered - 1; + ret = filemap_write_and_wait_range(file->f_mapping, iocb->ki_pos, endbyte); if (ret == 0) { - iocb->ki_pos = *ppos + written_buffered; + iocb->ki_pos += written_buffered; written += written_buffered; invalidate_mapping_pages(mapping, - *ppos >> PAGE_CACHE_SHIFT, + iocb->ki_pos >> PAGE_CACHE_SHIFT, endbyte >> PAGE_CACHE_SHIFT); } else { /* @@ -2426,9 +2426,9 @@ relock: } } else { current->backing_dev_info = inode_to_bdi(inode); - written = generic_perform_write(file, from, *ppos); + written = generic_perform_write(file, from, iocb->ki_pos); if (likely(written >= 0)) - iocb->ki_pos = *ppos + written; + iocb->ki_pos = iocb->ki_pos + written; current->backing_dev_info = NULL; } -- cgit v1.2.3-59-g8ed1b From 90320251db0fe3d05f2b10686ec936c7d6ecd99a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 9 Apr 2015 11:14:45 -0400 Subject: ocfs2: move generic_write_checks() before the alignment checks Alignment checks for dio depend upon the range truncation done by generic_write_checks(). They can be done as soon as we got ocfs2_rw_lock() and that actually makes ocfs2_prepare_inode_for_write() simpler. The only thing to watch out for is restoring the original count in "unlock and redo without dio" case. Position doesn't need to be restored, since we change it only in O_APPEND case and in that case it will be reassigned anyway. Signed-off-by: Al Viro --- fs/ocfs2/file.c | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 78e245df5e32..fc53ff065364 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2106,7 +2106,7 @@ out: } static int ocfs2_prepare_inode_for_write(struct file *file, - loff_t *ppos, + loff_t pos, size_t count, int appending, int *direct_io, @@ -2115,7 +2115,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file, int ret = 0, meta_level = 0; struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; - loff_t saved_pos = 0, end; + loff_t end; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); int full_coherency = !(osb->s_mount_opt & OCFS2_MOUNT_COHERENCY_BUFFERED); @@ -2155,23 +2155,16 @@ static int ocfs2_prepare_inode_for_write(struct file *file, } } - /* work on a copy of ppos until we're sure that we won't have - * to recalculate it due to relocking. */ - if (appending) - saved_pos = i_size_read(inode); - else - saved_pos = *ppos; - - end = saved_pos + count; + end = pos + count; - ret = ocfs2_check_range_for_refcount(inode, saved_pos, count); + ret = ocfs2_check_range_for_refcount(inode, pos, count); if (ret == 1) { ocfs2_inode_unlock(inode, meta_level); meta_level = -1; ret = ocfs2_prepare_inode_for_refcount(inode, file, - saved_pos, + pos, count, &meta_level); if (has_refcount) @@ -2227,7 +2220,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file, * caller will have to retake some cluster * locks and initiate the io as buffered. */ - ret = ocfs2_check_range_for_holes(inode, saved_pos, count); + ret = ocfs2_check_range_for_holes(inode, pos, count); if (ret == 1) { /* * Fallback to old way if the feature bit is not set. @@ -2242,12 +2235,9 @@ static int ocfs2_prepare_inode_for_write(struct file *file, break; } - if (appending) - *ppos = saved_pos; - out_unlock: trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno, - saved_pos, appending, count, + pos, appending, count, direct_io, has_refcount); if (meta_level >= 0) @@ -2263,7 +2253,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, int ret, direct_io, appending, rw_level, have_alloc_sem = 0; int can_do_direct, has_refcount = 0; ssize_t written = 0; - size_t count = iov_iter_count(from); + size_t count = iov_iter_count(from), orig_count; loff_t old_size; u32 old_clusters; struct file *file = iocb->ki_filp; @@ -2329,8 +2319,16 @@ relock: ocfs2_inode_unlock(inode, 1); } + orig_count = count; + ret = generic_write_checks(file, &iocb->ki_pos, &count); + if (ret < 0) { + mlog_errno(ret); + goto out; + } + iov_iter_truncate(from, count); + can_do_direct = direct_io; - ret = ocfs2_prepare_inode_for_write(file, &iocb->ki_pos, count, appending, + ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, appending, &can_do_direct, &has_refcount); if (ret < 0) { mlog_errno(ret); @@ -2351,6 +2349,7 @@ relock: rw_level = -1; direct_io = 0; + iov_iter_reexpand(from, count = orig_count); goto relock; } @@ -2374,11 +2373,6 @@ relock: /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb, rw_level); - ret = generic_write_checks(file, &iocb->ki_pos, &count); - if (ret) - goto out_dio; - - iov_iter_truncate(from, count); if (direct_io) { loff_t endbyte; ssize_t written_buffered; -- cgit v1.2.3-59-g8ed1b From 3309dd04cbcd2cdad168485af5cf3576b5051e49 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 9 Apr 2015 12:55:47 -0400 Subject: switch generic_write_checks() to iocb and iter ... returning -E... upon error and amount of data left in iter after (possible) truncation upon success. Note, that normal case gives a non-zero (positive) return value, so any tests for != 0 _must_ be updated. Signed-off-by: Al Viro Conflicts: fs/ext4/file.c --- fs/9p/vfs_file.c | 26 ++++++++++---------------- fs/btrfs/file.c | 24 +++++++++--------------- fs/ceph/file.c | 14 ++++++-------- fs/cifs/file.c | 26 ++++++-------------------- fs/ext4/file.c | 20 ++++++-------------- fs/fuse/file.c | 22 +++++++--------------- fs/ncpfs/file.c | 14 +++++--------- fs/nfs/direct.c | 25 ++++++++++--------------- fs/ntfs/file.c | 11 ++++------- fs/ocfs2/file.c | 19 ++++++++++--------- fs/udf/file.c | 10 ++-------- fs/xfs/xfs_file.c | 8 ++++---- include/linux/fs.h | 2 +- mm/filemap.c | 44 +++++++++++++++++++------------------------- 14 files changed, 99 insertions(+), 166 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index b5b020ace1b3..2a9dd37dc426 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -404,21 +404,16 @@ static ssize_t v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; - ssize_t retval = 0; - loff_t origin = iocb->ki_pos; - size_t count = iov_iter_count(from); + ssize_t retval; + loff_t origin; int err = 0; - retval = generic_write_checks(file, &origin, &count); - if (retval) + retval = generic_write_checks(iocb, from); + if (retval <= 0) return retval; - iov_iter_truncate(from, count); - - if (!count) - return 0; - - retval = p9_client_write(file->private_data, origin, from, &err); + origin = iocb->ki_pos; + retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err); if (retval > 0) { struct inode *inode = file_inode(file); loff_t i_size; @@ -428,12 +423,11 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (inode->i_mapping && inode->i_mapping->nrpages) invalidate_inode_pages2_range(inode->i_mapping, pg_start, pg_end); - origin += retval; + iocb->ki_pos += retval; i_size = i_size_read(inode); - iocb->ki_pos = origin; - if (origin > i_size) { - inode_add_bytes(inode, origin - i_size); - i_size_write(inode, origin); + if (iocb->ki_pos > i_size) { + inode_add_bytes(inode, iocb->ki_pos - i_size); + i_size_write(inode, iocb->ki_pos); } return retval; } diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 691a84a81e09..c64d11c41eeb 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1739,27 +1739,19 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, u64 start_pos; u64 end_pos; ssize_t num_written = 0; - ssize_t err = 0; - size_t count = iov_iter_count(from); bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); - loff_t pos = iocb->ki_pos; + ssize_t err; + loff_t pos; + size_t count; mutex_lock(&inode->i_mutex); - - current->backing_dev_info = inode_to_bdi(inode); - err = generic_write_checks(file, &pos, &count); - if (err) { + err = generic_write_checks(iocb, from); + if (err <= 0) { mutex_unlock(&inode->i_mutex); - goto out; - } - - if (count == 0) { - mutex_unlock(&inode->i_mutex); - goto out; + return err; } - iov_iter_truncate(from, count); - + current->backing_dev_info = inode_to_bdi(inode); err = file_remove_suid(file); if (err) { mutex_unlock(&inode->i_mutex); @@ -1786,6 +1778,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, */ update_time_for_write(inode); + pos = iocb->ki_pos; + count = iov_iter_count(from); start_pos = round_down(pos, root->sectorsize); if (start_pos > i_size_read(inode)) { /* Expand hole size to cover write data, preventing empty gap */ diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 761841903160..3f0b9339d823 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -941,9 +941,9 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_osd_client *osdc = &ceph_sb_to_client(inode->i_sb)->client->osdc; - ssize_t count = iov_iter_count(from), written = 0; + ssize_t count, written = 0; int err, want, got; - loff_t pos = iocb->ki_pos; + loff_t pos; if (ceph_snap(inode) != CEPH_NOSNAP) return -EROFS; @@ -953,14 +953,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) /* We can write back this queue in page reclaim */ current->backing_dev_info = inode_to_bdi(inode); - err = generic_write_checks(file, &pos, &count); - if (err) - goto out; - - if (count == 0) + err = generic_write_checks(iocb, from); + if (err <= 0) goto out; - iov_iter_truncate(from, count); + pos = iocb->ki_pos; + count = iov_iter_count(from); err = file_remove_suid(file); if (err) goto out; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 4202e74b2db5..ca2bc5406306 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2563,7 +2563,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; - size_t len; ssize_t total_written = 0; struct cifsFileInfo *open_file; struct cifs_tcon *tcon; @@ -2579,16 +2578,10 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from) * write request. */ - len = iov_iter_count(from); - rc = generic_write_checks(file, &iocb->ki_pos, &len); - if (rc) + rc = generic_write_checks(iocb, from); + if (rc <= 0) return rc; - if (!len) - return 0; - - iov_iter_truncate(from, len); - INIT_LIST_HEAD(&wdata_list); cifs_sb = CIFS_FILE_SB(file); open_file = file->private_data; @@ -2599,8 +2592,8 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from) memcpy(&saved_from, from, sizeof(struct iov_iter)); - rc = cifs_write_from_iter(iocb->ki_pos, len, from, open_file, cifs_sb, - &wdata_list); + rc = cifs_write_from_iter(iocb->ki_pos, iov_iter_count(from), from, + open_file, cifs_sb, &wdata_list); /* * If at least one write was successfully sent, then discard any rc @@ -2674,7 +2667,6 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) struct cifsInodeInfo *cinode = CIFS_I(inode); struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; ssize_t rc; - size_t count; /* * We need to hold the sem to be sure nobody modifies lock list @@ -2683,16 +2675,10 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) down_read(&cinode->lock_sem); mutex_lock(&inode->i_mutex); - count = iov_iter_count(from); - rc = generic_write_checks(file, &iocb->ki_pos, &count); - if (rc) + rc = generic_write_checks(iocb, from); + if (rc <= 0) goto out; - if (count == 0) - goto out; - - iov_iter_truncate(from, count); - if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), server->vals->exclusive_lock_type, NULL, CIFS_WRITE_OP)) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 42b1fa33a17a..c10785f10d1d 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -97,9 +97,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) struct blk_plug plug; int o_direct = io_is_direct(file); int overwrite = 0; - size_t length = iov_iter_count(from); ssize_t ret; - loff_t pos; /* * Unaligned direct AIO must be serialized; see comment above @@ -116,16 +114,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) } mutex_lock(&inode->i_mutex); - ret = generic_write_checks(file, &iocb->ki_pos, &length); - if (ret) + ret = generic_write_checks(iocb, from); + if (ret <= 0) goto out; - if (length == 0) - goto out; - - iov_iter_truncate(from, length); - pos = iocb->ki_pos; - /* * If we have encountered a bitmap-format file, the size limit * is smaller than s_maxbytes, which is for extent-mapped files. @@ -133,19 +125,19 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - if (pos >= sbi->s_bitmap_maxbytes) { + if (iocb->ki_pos >= sbi->s_bitmap_maxbytes) { ret = -EFBIG; goto out; } - iov_iter_truncate(from, sbi->s_bitmap_maxbytes - pos); + iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos); } iocb->private = &overwrite; if (o_direct) { - length = iov_iter_count(from); + size_t length = iov_iter_count(from); + loff_t pos = iocb->ki_pos; blk_start_plug(&plug); - /* check whether we do a DIO overwrite or not */ if (ext4_should_dioread_nolock(inode) && !aio_mutex && !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 8c15d0a077e8..b86c8e08399a 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1145,13 +1145,11 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; - size_t count = iov_iter_count(from); ssize_t written = 0; ssize_t written_buffered = 0; struct inode *inode = mapping->host; ssize_t err; loff_t endbyte = 0; - loff_t pos = iocb->ki_pos; if (get_fuse_conn(inode)->writeback_cache) { /* Update size (EOF optimization) and mode (SUID clearing) */ @@ -1167,14 +1165,10 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) /* We can write back this queue in page reclaim */ current->backing_dev_info = inode_to_bdi(inode); - err = generic_write_checks(file, &pos, &count); - if (err) - goto out; - - if (count == 0) + err = generic_write_checks(iocb, from); + if (err <= 0) goto out; - iov_iter_truncate(from, count); err = file_remove_suid(file); if (err) goto out; @@ -1184,6 +1178,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) goto out; if (file->f_flags & O_DIRECT) { + loff_t pos = iocb->ki_pos; written = generic_file_direct_write(iocb, from, pos); if (written < 0 || !iov_iter_count(from)) goto out; @@ -1209,9 +1204,9 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) written += written_buffered; iocb->ki_pos = pos + written_buffered; } else { - written = fuse_perform_write(file, mapping, from, pos); + written = fuse_perform_write(file, mapping, from, iocb->ki_pos); if (written >= 0) - iocb->ki_pos = pos + written; + iocb->ki_pos += written; } out: current->backing_dev_info = NULL; @@ -1412,7 +1407,6 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from) struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); struct fuse_io_priv io = { .async = 0, .file = file }; - size_t count = iov_iter_count(from); ssize_t res; if (is_bad_inode(inode)) @@ -1420,11 +1414,9 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from) /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); - res = generic_write_checks(file, &iocb->ki_pos, &count); - if (!res) { - iov_iter_truncate(from, count); + res = generic_write_checks(iocb, from); + if (res > 0) res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE); - } fuse_invalidate_attr(inode); if (res > 0) fuse_write_update_size(inode, iocb->ki_pos); diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index ab6363b16556..011324ce9df2 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -170,20 +170,15 @@ ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from) struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); size_t already_written = 0; - loff_t pos = iocb->ki_pos; - size_t count = iov_iter_count(from); size_t bufsize; int errno; void *bouncebuffer; + off_t pos; ncp_dbg(1, "enter %pD2\n", file); - errno = generic_write_checks(file, &pos, &count); - if (errno) + errno = generic_write_checks(iocb, from); + if (errno <= 0) return errno; - iov_iter_truncate(from, count); - - if (!count) - return 0; errno = ncp_make_open(inode, O_WRONLY); if (errno) { @@ -201,10 +196,11 @@ ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from) errno = -EIO; /* -ENOMEM */ goto outrel; } + pos = iocb->ki_pos; while (iov_iter_count(from)) { int written_this_time; size_t to_write = min_t(size_t, - bufsize - ((off_t)pos % bufsize), + bufsize - (pos % bufsize), iov_iter_count(from)); if (copy_from_iter(bouncebuffer, to_write, from) != to_write) { diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 5ddd77acb3f7..9634189b8545 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -969,24 +969,19 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, struct nfs_direct_req *dreq; struct nfs_lock_context *l_ctx; loff_t end; - size_t count = iov_iter_count(iter); - end = (pos + count - 1) >> PAGE_CACHE_SHIFT; - - nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count); dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n", - file, count, (long long) pos); + file, iov_iter_count(iter), (long long) iocb->ki_pos); - result = generic_write_checks(file, &pos, &count); - if (result) + result = generic_write_checks(iocb, iter); + if (result <= 0) goto out; - result = -EINVAL; - if ((ssize_t) count < 0) - goto out; - result = 0; - if (!count) - goto out; + nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, + iov_iter_count(iter)); + + pos = iocb->ki_pos; + end = (pos + iov_iter_count(iter) - 1) >> PAGE_CACHE_SHIFT; mutex_lock(&inode->i_mutex); @@ -1001,7 +996,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, goto out_unlock; } - task_io_account_write(count); + task_io_account_write(iov_iter_count(iter)); result = -ENOMEM; dreq = nfs_direct_req_alloc(); @@ -1009,7 +1004,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, goto out_unlock; dreq->inode = inode; - dreq->bytes_left = count; + dreq->bytes_left = iov_iter_count(iter); dreq->io_start = pos; dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); l_ctx = nfs_get_lock_context(dreq->ctx); diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index cec4ec3c1ede..7bb487e663b4 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -339,17 +339,14 @@ static ssize_t ntfs_prepare_file_for_write(struct kiocb *iocb, struct inode *vi = file_inode(file); ntfs_inode *base_ni, *ni = NTFS_I(vi); ntfs_volume *vol = ni->vol; - size_t count = iov_iter_count(from); ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, pos " "0x%llx, count 0x%zx.", vi->i_ino, (unsigned)le32_to_cpu(ni->type), - (unsigned long long)iocb->ki_pos, count); - err = generic_write_checks(file, &iocb->ki_pos, &count); - if (unlikely(err)) - goto out; - iov_iter_truncate(from, count); - if (count == 0) + (unsigned long long)iocb->ki_pos, + iov_iter_count(from)); + err = generic_write_checks(iocb, from); + if (unlikely(err <= 0)) goto out; /* * All checks have passed. Before we start doing any writing we want diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index fc53ff065364..b93919f50f0f 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2250,9 +2250,10 @@ out: static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { - int ret, direct_io, appending, rw_level, have_alloc_sem = 0; + int direct_io, appending, rw_level, have_alloc_sem = 0; int can_do_direct, has_refcount = 0; ssize_t written = 0; + ssize_t ret; size_t count = iov_iter_count(from), orig_count; loff_t old_size; u32 old_clusters; @@ -2319,13 +2320,14 @@ relock: ocfs2_inode_unlock(inode, 1); } - orig_count = count; - ret = generic_write_checks(file, &iocb->ki_pos, &count); - if (ret < 0) { - mlog_errno(ret); + orig_count = iov_iter_count(from); + ret = generic_write_checks(iocb, from); + if (ret <= 0) { + if (ret) + mlog_errno(ret); goto out; } - iov_iter_truncate(from, count); + count = ret; can_do_direct = direct_io; ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, appending, @@ -2349,7 +2351,7 @@ relock: rw_level = -1; direct_io = 0; - iov_iter_reexpand(from, count = orig_count); + iov_iter_reexpand(from, orig_count); goto relock; } @@ -2377,7 +2379,7 @@ relock: loff_t endbyte; ssize_t written_buffered; written = generic_file_direct_write(iocb, from, iocb->ki_pos); - if (written < 0 || written == count) { + if (written < 0 || !iov_iter_count(from)) { ret = written; goto out_dio; } @@ -2385,7 +2387,6 @@ relock: /* * for completing the rest of the request. */ - count -= written; written_buffered = generic_perform_write(file, from, iocb->ki_pos); /* * If generic_file_buffered_write() returned a synchronous error diff --git a/fs/udf/file.c b/fs/udf/file.c index ccab8b78e363..3de2edafff73 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -120,21 +120,15 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ssize_t retval; struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - size_t count = iov_iter_count(from); struct udf_inode_info *iinfo = UDF_I(inode); int err; mutex_lock(&inode->i_mutex); - retval = generic_write_checks(file, &iocb->ki_pos, &count); - if (retval) + retval = generic_write_checks(iocb, from); + if (retval <= 0) goto out; - if (count == 0) - goto out; - - iov_iter_truncate(from, count); - down_write(&iinfo->i_data_sem); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { loff_t end = iocb->ki_pos + iov_iter_count(from); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index ebde43e15dd9..28d157807b42 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -551,12 +551,12 @@ xfs_file_aio_write_checks( struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; struct xfs_inode *ip = XFS_I(inode); - int error = 0; + ssize_t error = 0; size_t count = iov_iter_count(from); restart: - error = generic_write_checks(file, &iocb->ki_pos, &count); - if (error) + error = generic_write_checks(iocb, from); + if (error <= 0) return error; error = xfs_break_layouts(inode, iolock); @@ -577,13 +577,13 @@ restart: xfs_rw_iunlock(ip, *iolock); *iolock = XFS_IOLOCK_EXCL; xfs_rw_ilock(ip, *iolock); + iov_iter_reexpand(from, count); goto restart; } error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero); if (error) return error; } - iov_iter_truncate(from, count); /* * Updating the timestamps will grab the ilock again from diff --git a/include/linux/fs.h b/include/linux/fs.h index c7b21db7782f..b4aa400ac723 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2566,7 +2566,7 @@ extern int sb_min_blocksize(struct super_block *, int); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); -int generic_write_checks(struct file *file, loff_t *pos, size_t *count); +extern ssize_t generic_write_checks(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); diff --git a/mm/filemap.c b/mm/filemap.c index dfc573c6ec25..243997a26e7c 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2260,36 +2260,38 @@ EXPORT_SYMBOL(read_cache_page_gfp); * Returns appropriate error code that caller should return or * zero in case that write should be allowed. */ -inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count) +inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from) { + struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; unsigned long limit = rlimit(RLIMIT_FSIZE); + loff_t pos; - if (unlikely(*pos < 0)) - return -EINVAL; + if (!iov_iter_count(from)) + return 0; /* FIXME: this is for backwards compatibility with 2.4 */ if (file->f_flags & O_APPEND) - *pos = i_size_read(inode); + iocb->ki_pos = i_size_read(inode); + + pos = iocb->ki_pos; if (limit != RLIM_INFINITY) { - if (*pos >= limit) { + if (iocb->ki_pos >= limit) { send_sig(SIGXFSZ, current, 0); return -EFBIG; } - if (*count > limit - (typeof(limit))*pos) - *count = limit - (typeof(limit))*pos; + iov_iter_truncate(from, limit - (unsigned long)pos); } /* * LFS rule */ - if (unlikely(*pos + *count > MAX_NON_LFS && + if (unlikely(pos + iov_iter_count(from) > MAX_NON_LFS && !(file->f_flags & O_LARGEFILE))) { - if (*pos >= MAX_NON_LFS) + if (pos >= MAX_NON_LFS) return -EFBIG; - if (*count > MAX_NON_LFS - (unsigned long)*pos) - *count = MAX_NON_LFS - (unsigned long)*pos; + iov_iter_truncate(from, MAX_NON_LFS - (unsigned long)pos); } /* @@ -2299,16 +2301,11 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count) * exceeded without writing data we send a signal and return EFBIG. * Linus frestrict idea will clean these up nicely.. */ - if (unlikely(*pos >= inode->i_sb->s_maxbytes)) { - if (*count || *pos > inode->i_sb->s_maxbytes) { - return -EFBIG; - } - /* zero-length writes at ->s_maxbytes are OK */ - } + if (unlikely(pos >= inode->i_sb->s_maxbytes)) + return -EFBIG; - if (unlikely(*pos + *count > inode->i_sb->s_maxbytes)) - *count = inode->i_sb->s_maxbytes - *pos; - return 0; + iov_iter_truncate(from, inode->i_sb->s_maxbytes - pos); + return iov_iter_count(from); } EXPORT_SYMBOL(generic_write_checks); @@ -2618,14 +2615,11 @@ ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from) struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; ssize_t ret; - size_t count = iov_iter_count(from); mutex_lock(&inode->i_mutex); - ret = generic_write_checks(file, &iocb->ki_pos, &count); - if (!ret && count) { - iov_iter_truncate(from, count); + ret = generic_write_checks(iocb, from); + if (ret > 0) ret = __generic_file_write_iter(iocb, from); - } mutex_unlock(&inode->i_mutex); if (ret > 0) { -- cgit v1.2.3-59-g8ed1b From 2ba48ce513c4e545318d22b138861d5876edf906 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 9 Apr 2015 13:52:01 -0400 Subject: mirror O_APPEND and O_DIRECT into iocb->ki_flags ... avoiding write_iter/fcntl races. Signed-off-by: Al Viro --- fs/aio.c | 2 +- fs/btrfs/file.c | 2 +- fs/ceph/file.c | 8 ++++---- fs/ext4/file.c | 4 ++-- fs/fuse/file.c | 2 +- fs/gfs2/file.c | 2 +- fs/nfs/file.c | 6 +++--- fs/ocfs2/file.c | 10 +++++----- fs/xfs/xfs_file.c | 4 ++-- include/linux/fs.h | 15 +++++++++++++++ mm/filemap.c | 6 +++--- 11 files changed, 38 insertions(+), 23 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/aio.c b/fs/aio.c index 5785c4b58fea..e976185c8e5b 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1502,7 +1502,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, } req->common.ki_pos = iocb->aio_offset; req->common.ki_complete = aio_complete; - req->common.ki_flags = 0; + req->common.ki_flags = iocb_flags(req->common.ki_filp); if (iocb->aio_flags & IOCB_FLAG_RESFD) { /* diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c64d11c41eeb..faa7d390841b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1794,7 +1794,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, if (sync) atomic_inc(&BTRFS_I(inode)->sync_writers); - if (file->f_flags & O_DIRECT) { + if (iocb->ki_flags & IOCB_DIRECT) { num_written = __btrfs_direct_write(iocb, from, pos); } else { num_written = __btrfs_buffered_write(file, from, pos); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 3f0b9339d823..b9b8eb225f66 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -457,7 +457,7 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i, if (ret < 0) return ret; - if (file->f_flags & O_DIRECT) { + if (iocb->ki_flags & IOCB_DIRECT) { while (iov_iter_count(i)) { size_t start; ssize_t n; @@ -828,7 +828,7 @@ again: return ret; if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 || - (iocb->ki_filp->f_flags & O_DIRECT) || + (iocb->ki_flags & IOCB_DIRECT) || (fi->flags & CEPH_F_SYNC)) { dout("aio_sync_read %p %llx.%llx %llu~%u got cap refs on %s\n", @@ -995,12 +995,12 @@ retry_snap: inode, ceph_vinop(inode), pos, count, ceph_cap_string(got)); if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 || - (file->f_flags & O_DIRECT) || (fi->flags & CEPH_F_SYNC)) { + (iocb->ki_flags & IOCB_DIRECT) || (fi->flags & CEPH_F_SYNC)) { struct iov_iter data; mutex_unlock(&inode->i_mutex); /* we might need to revert back to that point */ data = *from; - if (file->f_flags & O_DIRECT) + if (iocb->ki_flags & IOCB_DIRECT) written = ceph_sync_direct_write(iocb, &data, pos); else written = ceph_sync_write(iocb, &data, pos); diff --git a/fs/ext4/file.c b/fs/ext4/file.c index c10785f10d1d..53bbc0b1995f 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -95,7 +95,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file_inode(iocb->ki_filp); struct mutex *aio_mutex = NULL; struct blk_plug plug; - int o_direct = io_is_direct(file); + int o_direct = iocb->ki_flags & IOCB_DIRECT; int overwrite = 0; ssize_t ret; @@ -106,7 +106,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (o_direct && ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && !is_sync_kiocb(iocb) && - (file->f_flags & O_APPEND || + (iocb->ki_flags & IOCB_APPEND || ext4_unaligned_aio(inode, from, iocb->ki_pos))) { aio_mutex = ext4_aio_mutex(inode); mutex_lock(aio_mutex); diff --git a/fs/fuse/file.c b/fs/fuse/file.c index b86c8e08399a..5ef05b5c4cff 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1177,7 +1177,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (err) goto out; - if (file->f_flags & O_DIRECT) { + if (iocb->ki_flags & IOCB_DIRECT) { loff_t pos = iocb->ki_pos; written = generic_file_direct_write(iocb, from, pos); if (written < 0 || !iov_iter_count(from)) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 614bb42cb7e1..08329afa1339 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -709,7 +709,7 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from) gfs2_size_hint(file, iocb->ki_pos, iov_iter_count(from)); - if (file->f_flags & O_APPEND) { + if (iocb->ki_flags & IOCB_APPEND) { struct gfs2_holder gh; ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); diff --git a/fs/nfs/file.c b/fs/nfs/file.c index f6a3adedf027..14364dc001f7 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -170,7 +170,7 @@ nfs_file_read(struct kiocb *iocb, struct iov_iter *to) struct inode *inode = file_inode(iocb->ki_filp); ssize_t result; - if (iocb->ki_filp->f_flags & O_DIRECT) + if (iocb->ki_flags & IOCB_DIRECT) return nfs_file_direct_read(iocb, to, iocb->ki_pos); dprintk("NFS: read(%pD2, %zu@%lu)\n", @@ -680,7 +680,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) if (result) return result; - if (file->f_flags & O_DIRECT) + if (iocb->ki_flags & IOCB_DIRECT) return nfs_file_direct_write(iocb, from, pos); dprintk("NFS: write(%pD2, %zu@%Ld)\n", @@ -692,7 +692,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) /* * O_APPEND implies that we must revalidate the file length. */ - if (file->f_flags & O_APPEND) { + if (iocb->ki_flags & IOCB_APPEND) { result = nfs_revalidate_file_size(inode, file); if (result) goto out; diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index b93919f50f0f..cd37f6cd4d51 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2274,8 +2274,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, if (count == 0) return 0; - appending = file->f_flags & O_APPEND ? 1 : 0; - direct_io = file->f_flags & O_DIRECT ? 1 : 0; + appending = iocb->ki_flags & IOCB_APPEND ? 1 : 0; + direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0; mutex_lock(&inode->i_mutex); @@ -2429,7 +2429,7 @@ relock: out_dio: /* buffered aio wouldn't have proper lock coverage today */ - BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); + BUG_ON(ret == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); if (unlikely(written <= 0)) goto no_sync; @@ -2546,7 +2546,7 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, * buffered reads protect themselves in ->readpage(). O_DIRECT reads * need locks to protect pending reads from racing with truncate. */ - if (filp->f_flags & O_DIRECT) { + if (iocb->ki_flags & IOCB_DIRECT) { have_alloc_sem = 1; ocfs2_iocb_set_sem_locked(iocb); @@ -2580,7 +2580,7 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, trace_generic_file_aio_read_ret(ret); /* buffered aio wouldn't have proper lock coverage today */ - BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); + BUG_ON(ret == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); /* see ocfs2_file_write_iter */ if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) { diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 28d157807b42..1f12ad0a8585 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -279,7 +279,7 @@ xfs_file_read_iter( XFS_STATS_INC(xs_read_calls); - if (unlikely(file->f_flags & O_DIRECT)) + if (unlikely(iocb->ki_flags & IOCB_DIRECT)) ioflags |= XFS_IO_ISDIRECT; if (file->f_mode & FMODE_NOCMTIME) ioflags |= XFS_IO_INVIS; @@ -804,7 +804,7 @@ xfs_file_write_iter( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; - if (unlikely(file->f_flags & O_DIRECT)) + if (unlikely(iocb->ki_flags & IOCB_DIRECT)) ret = xfs_file_dio_aio_write(iocb, from); else ret = xfs_file_buffered_aio_write(iocb, from); diff --git a/include/linux/fs.h b/include/linux/fs.h index b4aa400ac723..b1d7db28c13c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -315,6 +315,8 @@ struct address_space; struct writeback_control; #define IOCB_EVENTFD (1 << 0) +#define IOCB_APPEND (1 << 1) +#define IOCB_DIRECT (1 << 2) struct kiocb { struct file *ki_filp; @@ -329,10 +331,13 @@ static inline bool is_sync_kiocb(struct kiocb *kiocb) return kiocb->ki_complete == NULL; } +static inline int iocb_flags(struct file *file); + static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) { *kiocb = (struct kiocb) { .ki_filp = filp, + .ki_flags = iocb_flags(filp), }; } @@ -2779,6 +2784,16 @@ static inline bool io_is_direct(struct file *filp) return (filp->f_flags & O_DIRECT) || IS_DAX(file_inode(filp)); } +static inline int iocb_flags(struct file *file) +{ + int res = 0; + if (file->f_flags & O_APPEND) + res |= IOCB_APPEND; + if (io_is_direct(file)) + res |= IOCB_DIRECT; + return res; +} + static inline ino_t parent_ino(struct dentry *dentry) { ino_t res; diff --git a/mm/filemap.c b/mm/filemap.c index 243997a26e7c..405de370e657 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1694,7 +1694,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) loff_t *ppos = &iocb->ki_pos; loff_t pos = *ppos; - if (io_is_direct(file)) { + if (iocb->ki_flags & IOCB_DIRECT) { struct address_space *mapping = file->f_mapping; struct inode *inode = mapping->host; size_t count = iov_iter_count(iter); @@ -2271,7 +2271,7 @@ inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from) return 0; /* FIXME: this is for backwards compatibility with 2.4 */ - if (file->f_flags & O_APPEND) + if (iocb->ki_flags & IOCB_APPEND) iocb->ki_pos = i_size_read(inode); pos = iocb->ki_pos; @@ -2545,7 +2545,7 @@ ssize_t __generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (err) goto out; - if (io_is_direct(file)) { + if (iocb->ki_flags & IOCB_DIRECT) { loff_t pos, endbyte; written = generic_file_direct_write(iocb, from, iocb->ki_pos); -- cgit v1.2.3-59-g8ed1b From 7da839c475894ea872ec909a5d2e83dddccff5be Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 9 Apr 2015 14:01:33 -0400 Subject: ocfs2: use __generic_file_write_iter() we can do that now - all we need is to clear IOCB_DIRECT from ->ki_flags in "can't do dio" case. Signed-off-by: Al Viro --- fs/ocfs2/file.c | 64 +++++++-------------------------------------------------- 1 file changed, 7 insertions(+), 57 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index cd37f6cd4d51..913fc250d85a 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2259,11 +2259,11 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, u32 old_clusters; struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - struct address_space *mapping = file->f_mapping; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); int full_coherency = !(osb->s_mount_opt & OCFS2_MOUNT_COHERENCY_BUFFERED); int unaligned_dio = 0; + int dropped_dio = 0; trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, (unsigned long long)OCFS2_I(inode)->ip_blkno, @@ -2351,7 +2351,9 @@ relock: rw_level = -1; direct_io = 0; + iocb->ki_flags &= ~IOCB_DIRECT; iov_iter_reexpand(from, orig_count); + dropped_dio = 1; goto relock; } @@ -2375,67 +2377,15 @@ relock: /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb, rw_level); - if (direct_io) { - loff_t endbyte; - ssize_t written_buffered; - written = generic_file_direct_write(iocb, from, iocb->ki_pos); - if (written < 0 || !iov_iter_count(from)) { - ret = written; - goto out_dio; - } - - /* - * for completing the rest of the request. - */ - written_buffered = generic_perform_write(file, from, iocb->ki_pos); - /* - * If generic_file_buffered_write() returned a synchronous error - * then we want to return the number of bytes which were - * direct-written, or the error code if that was zero. Note - * that this differs from normal direct-io semantics, which - * will return -EFOO even if some bytes were written. - */ - if (written_buffered < 0) { - ret = written_buffered; - goto out_dio; - } - - /* We need to ensure that the page cache pages are written to - * disk and invalidated to preserve the expected O_DIRECT - * semantics. - */ - endbyte = iocb->ki_pos + written_buffered - 1; - ret = filemap_write_and_wait_range(file->f_mapping, iocb->ki_pos, - endbyte); - if (ret == 0) { - iocb->ki_pos += written_buffered; - written += written_buffered; - invalidate_mapping_pages(mapping, - iocb->ki_pos >> PAGE_CACHE_SHIFT, - endbyte >> PAGE_CACHE_SHIFT); - } else { - /* - * We don't know how much we wrote, so just return - * the number of bytes which were direct-written - */ - } - } else { - current->backing_dev_info = inode_to_bdi(inode); - written = generic_perform_write(file, from, iocb->ki_pos); - if (likely(written >= 0)) - iocb->ki_pos = iocb->ki_pos + written; - current->backing_dev_info = NULL; - } - -out_dio: + written = __generic_file_write_iter(iocb, from); /* buffered aio wouldn't have proper lock coverage today */ - BUG_ON(ret == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); + BUG_ON(written == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); if (unlikely(written <= 0)) goto no_sync; - if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || - ((file->f_flags & O_DIRECT) && !direct_io)) { + if (((file->f_flags & O_DSYNC) && !direct_io) || + IS_SYNC(inode) || dropped_dio) { ret = filemap_fdatawrite_range(file->f_mapping, iocb->ki_pos - written, iocb->ki_pos - 1); -- cgit v1.2.3-59-g8ed1b