Remove rw parameter from direct_IO()
Subsystems (29)
cover Remove rw parameter from direct_IO()
Hi,
Al, here's some cleanup that you mentioned back in December that I got around to (https://lkml.org/lkml/2014/12/15/28).
In summary, the rw parameter to a_ops->direct_IO() is redundant with .type in struct iov_iter. Additionally, rw is inconsistently checked for being a WRITE; some filesystems do rw == WRITE, others do rw & WRITE, and others do both within the same function :) The distinction is that swapout may OR in the ITER_BVEC flag in the rw passed to ->direct_IO(), so the two are not equivalent (although this really only happens for swap-over-NFS, but it's scary nonetheless). After looking through all of these, it definitely looks like every check means for ANY write, not just non-kernel writes.
So, the solution presented here is:
- Add a helper, iov_iter_rw(), which always returns either READ or WRITE, no ITER_.* or REQ_.* nonsense mixed in. For consistency, the return value is always checked for equality
- Get rid of all uses of rw in any implementations of direct_IO, starting with the generic code
- Nuke the actual parameter and update the documentation
I decided to squish all of the filesystems together in patch 4 to avoid inundating the mailing lists with 20+ mostly two-line patches, but I can split those out if that's any better. Additionally, patch 1 pulls fs.h into uio.h, which seems undesirable.
These were mostly just compile tested, with a couple of direct I/O xfstests run on btrfs as quick sanity check, so getting some more eyes on is probably a good thing. They should apply on top of v4.0-rc4. Please comment away.
Thank you,
Omar Sandoval (5):
new helper: iov_iter_rw()
Remove rw from {,__,do_}blockdev_direct_IO() Remove rw from dax_{do_,}io()
direct_IO: use iov_iter_rw() instead of rw everywhere
direct_IO: remove rw from a_ops->direct_IO()
Documentation/filesystems/Locking | 2 +- Documentation/filesystems/vfs.txt | 2 +- drivers/staging/lustre/lustre/llite/rw26.c | 22 ++++++++--------- fs/9p/vfs_addr.c | 2 +- fs/affs/file.c | 9 +++---- fs/block_dev.c | 8 +++--- fs/btrfs/inode.c | 24 +++++++++--------- fs/ceph/addr.c | 3 +-- fs/cifs/file.c | 3 +-- fs/dax.c | 27 ++++++++++----------- fs/direct-io.c | 39 ++++++++++++++---------------- fs/exofs/inode.c | 4 +-- fs/ext2/inode.c | 11 ++++----- fs/ext3/inode.c | 14 +++++------ fs/ext4/ext4.h | 4 +-- fs/ext4/indirect.c | 25 ++++++++++--------- fs/ext4/inode.c | 28 ++++++++++----------- fs/f2fs/data.c | 22 ++++++++--------- fs/fat/inode.c | 9 +++---- fs/fuse/file.c | 16 ++++++------ fs/gfs2/aops.c | 16 ++++++------ fs/hfs/inode.c | 8 +++--- fs/hfsplus/inode.c | 9 +++---- fs/jfs/inode.c | 8 +++--- fs/nfs/direct.c | 4 +-- fs/nilfs2/inode.c | 10 +++----- fs/ocfs2/aops.c | 22 +++++++---------- fs/reiserfs/inode.c | 8 +++--- fs/udf/file.c | 3 +-- fs/udf/inode.c | 7 +++--- fs/xfs/xfs_aops.c | 12 ++++----- include/linux/fs.h | 24 +++++++++--------- include/linux/nfs_fs.h | 2 +- include/linux/uio.h | 10 ++++++++ mm/filemap.c | 4 +-- mm/page_io.c | 4 +-- 36 files changed, 206 insertions(+), 219 deletions(-)
Signature · 6 lines
2.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH 1/5 new helper: iov_iter_rw()
Get either READ or WRITE out of iter->type.
--- include/linux/uio.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
include/linux/uio.h +10 -0
@@ -10,6 +10,7 @@#define __LINUX_UIO_H#include <linux/kernel.h> +#include <linux/fs.h> #include <uapi/linux/uio.h> struct page ;
@@ -111,6 +112,15 @@ static inline bool iter_is_iovec(struct iov_iter *i) }/* +* Get one of READ or WRITE out of iter->type without any other flags OR'd in +* with it. +*/ +static inline int iov_iter_rw (const struct iov_iter *i) +{ +return i->type &RW_MASK ; +} + +/* * Cap the iov_iter by given limit; note that the second argument is * *not* the new size - it's upper limit for such. Passing it a value * greater than the amount of data in iov_iter is fine - it'll just do
Signature · 1 line
2.3.3
Al Viro
maintainerRe: [RFC PATCH 1/5] new helper: iov_iter_rw()
Quoted 1 line · Omar Sandoval
Get either READ or WRITE out of
iter->type.
Umm...
include/linux/uio.h static inline bool iter_is_iovec(struct iov_iter *i) · line 121
Quoted 7 lines
+ * Get one of READ or WRITE out of
iter->typewithout any other flags OR'd in
+ * with it.
+ */include/linux/uio.h +4
-0+static inline int iov_iter_rw (const struct iov_iter *i) +{ +return i->type &RW_MASK ; +}
TBH, I would turn that into a macro. Reason: indirect includes.
How about
#define iov_iter_rw(i) ((0 ? (struct iov_iter *)0 : (i))->type & RW_MASK)
Should do you all the type safety of inline function and avoids the need to include fs.h in uio.h; _users_ of iov_iter_rw() obviously still need fs.h, but such places always used to...
RFC PATCH v2 1/5 new helper: iov_iter_rw()
Get either READ or WRITE out of iter->type.
---
Thanks, Al, this is much better. Anything else you'd like me to address for this series?
include/linux/uio.h | 6 ++++++ 1 file changed, 6 insertions(+)
include/linux/uio.h +6 -0
@@ -111,6 +111,12 @@ static inline bool iter_is_iovec(struct iov_iter *i) }/* +* Get one of READ or WRITE out of iter->type without any other flags OR'd in +* with it. +*/ +#define iov_iter_rw (i) ((0 ? (struct iov_iter *)0 : (i))->type & RW_MASK) + +/* * Cap the iov_iter by given limit; note that the second argument is * *not* the new size - it's upper limit for such. Passing it a value * greater than the amount of data in iov_iter is fine - it'll just do
Signature · 1 line
2.3.3
Re: [RFC PATCH 1/5] new helper: iov_iter_rw()
In reply to Al ViroQuoted 5 lines · Al Viro
Quoted 1 line · Omar Sandoval
Get either READ or WRITE out of
iter->type.Umm...
Quoted 9 lines
include/linux/uio.h static inline bool iter_is_iovec(struct iov_iter *i) · line 121
Quoted 7 lines
+ * Get one of READ or WRITE out of
iter->typewithout any other flags OR'd in
+ * with it.
+ */include/linux/uio.h +4
-0+static inline int iov_iter_rw (const struct iov_iter *i) +{ +return i->type &RW_MASK ; +}TBH, I would turn that into a macro. Reason: indirect includes.
Agreed, but the proposed define is rather cryptic and I was not able to understand the meaning on the first glance.
Quoted 1 line
#define
iov_iter_rw(i)((0 ? (structiov_iter*)0 : (i))->type &RW_MASK)
This worked for me, does not compile with anything else than 'struct iov_iter*' as i:
#define iov_iter_rw(i) ({ \
struct iov_iter __iter = *(i); \
(i)->type & RW_MASK; \
})The assignment is optimized out.
Re: [RFC PATCH 1/5] new helper: iov_iter_rw()
Quoted 24 lines · David Sterba
Quoted 5 lines · Al Viro
Quoted 1 line · Omar Sandoval
Get either READ or WRITE out of
iter->type.Umm...
Quoted 9 lines
include/linux/uio.h static inline bool iter_is_iovec(struct iov_iter *i) · line 121
Quoted 7 lines
+ * Get one of READ or WRITE out of
iter->typewithout any other flags OR'd in
+ * with it.
+ */include/linux/uio.h +4
-0+static inline int iov_iter_rw (const struct iov_iter *i) +{ +return i->type &RW_MASK ; +}TBH, I would turn that into a macro. Reason: indirect includes.
Agreed, but the proposed define is rather cryptic and I was not able to understand the meaning on the first glance.
Quoted 1 line
#define
iov_iter_rw(i)((0 ? (structiov_iter*)0 : (i))->type &RW_MASK)This worked for me, does not compile with anything else than 'struct iov_iter*' as i:
Quoted 6 lines
#define iov_iter_rw(i) ({ \ struct iov_iter __iter = *(i); \ (i)->type & RW_MASK; \ })The assignment is optimized out.
[-cc individual fs maintainers to avoid all of these email bounces, should've looked a bit closer at that get_maintainer.pl output...]
I agree that this is a bit more readable, but it evaluates i twice. That's an easy fix, just do __iter.type instead of (i)->type, but there's still the possibility of someone passing in something called __iter as i, and the fix for that tends to be "add more underscores". At the very least, Al's macro could probably use a comment explaining what's going on there, though.
Signature · 1 line
Omar
Al Viro
maintainerRe: [RFC PATCH 1/5] new helper: iov_iter_rw()
In reply to David SterbaQuoted 8 lines · David Sterba
Agreed, but the proposed define is rather cryptic and I was not able to understand the meaning on the first glance.
Quoted 1 line
#define
iov_iter_rw(i)((0 ? (structiov_iter*)0 : (i))->type &RW_MASK)This worked for me, does not compile with anything else than 'struct iov_iter*' as i:
Quoted 6 lines
#define iov_iter_rw(i) ({ \ struct iov_iter __iter = *(i); \ (i)->type & RW_MASK; \ })The assignment is optimized out.
... and you are getting
a) use of rather lousy gccism when plain C would do
b) double evaluation since you've got it wrong (should've been
__iter.type & RW_MASK, if you do it that way). As it is, if argument has any side effects, your variant will trigger those twice - even if the destination of the assignment is never used, the side effects remain.
I agree that it could use /* use ?: for typechecking */, but let's not go into ({...}) land unless we absolutely have to.
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH v3 1/5 new helper: iov_iter_rw()
Get either READ or WRITE out of iter->type.
---
Ok, let's do that, then.
include/linux/uio.h | 8 ++++++++ 1 file changed, 8 insertions(+)
include/linux/uio.h +8 -0
@@ -111,6 +111,14 @@ static inline bool iter_is_iovec(struct iov_iter *i) }/* +* Get one of READ or WRITE out of iter->type without any other flags OR'd in +* with it. +* +* The ?: is just for type safety. +*/ +#define iov_iter_rw (i) ((0 ? (struct iov_iter *)0 : (i))->type & RW_MASK) + +/* * Cap the iov_iter by given limit; note that the second argument is * *not* the new size - it's upper limit for such. Passing it a value * greater than the amount of data in iov_iter is fine - it'll just do
Signature · 1 line
2.3.3
Re: [RFC PATCH v3 1/5] new helper: iov_iter_rw()
Quoted 7 lines · Omar Sandoval
/*
+ * Get one of READ or WRITE out ofiter->typewithout any other flags OR'd in
+ * with it.
+ *
+ * The ?: is just for type safety.
+ */
+#defineiov_iter_rw(i)((0 ? (structiov_iter*)0 : (i))->type &RW_MASK)
I'm fine with that, thanks.
RFC PATCH 2/5 Remove rw from {,__,do_}blockdev_direct_IO()
In reply to Omar SandovalMost filesystems call through to these at some point, so we'll start here.
--- fs/affs/file.c | 2 +- fs/block_dev.c | 5 ++--- fs/btrfs/inode.c | 8 ++++---- fs/direct-io.c | 39 ++++++++++++++++++--------------------- fs/ext2/inode.c | 2 +- fs/ext3/inode.c | 2 +- fs/ext4/indirect.c | 11 ++++++----- fs/ext4/inode.c | 2 +- fs/f2fs/data.c | 2 +- fs/fat/inode.c | 2 +- fs/gfs2/aops.c | 5 ++--- fs/hfs/inode.c | 2 +- fs/hfsplus/inode.c | 3 +-- fs/jfs/inode.c | 2 +- fs/nilfs2/inode.c | 3 +-- fs/ocfs2/aops.c | 16 +++++++--------- fs/reiserfs/inode.c | 2 +- fs/udf/inode.c | 2 +- fs/xfs/xfs_aops.c | 9 ++++----- include/linux/fs.h | 22 ++++++++++++---------- 20 files changed, 67 insertions(+), 74 deletions(-)
fs/affs/file.c +1 -1
@@ -405,7 +405,7 @@ affs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,return 0 ; } - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, affs_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, affs_get_block);if (ret <0 && (rw &WRITE ))affs_write_failed (mapping, offset + count);return ret;
fs/block_dev.c +2 -3
@@ -153,9 +153,8 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,struct file *file = iocb->ki_filp;struct inode *inode = file->f_mapping->host; -return __blockdev_direct_IO (rw, iocb, inode,I_BDEV (inode), iter, - offset, blkdev_get_block, -NULL ,NULL ,0 ); +return __blockdev_direct_IO (iocb, inode,I_BDEV (inode), iter, offset, + blkdev_get_block,NULL ,NULL ,0 ); }int __sync_blockdev (struct block_device *bdev,int wait)
fs/btrfs/inode.c +4 -4
@@ -8119,10 +8119,10 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, wakeup = false; } - ret =__blockdev_direct_IO (rw, iocb, inode, -BTRFS_I (inode)->root->fs_info->fs_devices->latest_bdev, - iter, offset, btrfs_get_blocks_direct,NULL , - btrfs_submit_direct, flags); + ret =__blockdev_direct_IO (iocb, inode, +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 (ret <0 && ret != -EIOCBQUEUED )btrfs_delalloc_release_space (inode, count);
fs/direct-io.c +18 -21
@@ -1094,10 +1094,10 @@ static inline int drop_refcount(struct dio *dio)* for the whole file. */ static inline ssize_t -do_blockdev_direct_IO (int rw,struct kiocb *iocb,struct inode *inode, -struct block_device *bdev,struct iov_iter *iter,loff_t offset, -get_block_t get_block,dio_iodone_t end_io, -dio_submit_t submit_io,int flags) +do_blockdev_direct_IO (struct kiocb *iocb,struct inode *inode, +struct block_device *bdev,struct iov_iter *iter, +loff_t offset,get_block_t get_block,dio_iodone_t end_io, +dio_submit_t submit_io,int flags) {unsigned i_blkbits =ACCESS_ONCE (inode->i_blkbits);unsigned blkbits = i_blkbits;
@@ -1111,9 +1111,6 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,struct blk_plug plug;unsigned long align = offset |iov_iter_alignment (iter); -if (rw &WRITE ) - rw =WRITE_ODIRECT ; -/* * Avoid references to bdev if not absolutely needed to give * the early prefetch in the caller enough time.
@@ -1128,7 +1125,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, }/* watch out for a 0 len io from a tricksy fs */ -if (rw ==READ && !iov_iter_count (iter)) +if (iov_iter_rw (iter) ==READ && !iov_iter_count (iter))return 0 ; dio =kmem_cache_alloc (dio_cache,GFP_KERNEL );
@@ -1144,7 +1141,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, dio->flags = flags;if (dio->flags &DIO_LOCKING ) { -if (rw ==READ ) { +if (iov_iter_rw (iter) ==READ ) {struct address_space *mapping = iocb->ki_filp->f_mapping;
@@ -1170,19 +1167,19 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,if (is_sync_kiocb (iocb)) dio->is_async = false;else if (!(dio->flags &DIO_ASYNC_EXTEND ) && - (rw &WRITE ) && end >i_size_read (inode)) +iov_iter_rw (iter) ==WRITE && end >i_size_read (inode)) dio->is_async = false;else dio->is_async = true; dio->inode = inode; - dio->rw = rw; + dio->rw =iov_iter_rw (iter) ==WRITE ?WRITE_ODIRECT :READ ;/* * For AIO O_(D)SYNC writes we need to defer completions to a workqueue * so that we can call ->fsync. */ -if (dio->is_async && (rw &WRITE ) && +if (dio->is_async &&iov_iter_rw (iter) ==WRITE && ((iocb->ki_filp->f_flags &O_DSYNC ) ||IS_SYNC (iocb->ki_filp->f_mapping->host))) { retval =dio_set_defer_completion (dio);
@@ -1275,7 +1272,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,* we can let i_mutex go now that its achieved its purpose * of protecting us from looking up uninitialized blocks. */ -if (rw ==READ && (dio->flags &DIO_LOCKING )) +if (iov_iter_rw (iter) ==READ && (dio->flags &DIO_LOCKING ))mutex_unlock (&dio->inode->i_mutex);/*
@@ -1287,7 +1284,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,*/ BUG_ON (retval == -EIOCBQUEUED );if (dio->is_async && retval ==0 && dio->result && - (rw ==READ || dio->result == count)) + (iov_iter_rw (iter) ==READ || dio->result == count)) retval = -EIOCBQUEUED ;else dio_await_completion (dio);
@@ -1301,11 +1298,11 @@ out:return retval; } -ssize_t -__blockdev_direct_IO (int rw,struct kiocb *iocb,struct inode *inode, -struct block_device *bdev,struct iov_iter *iter,loff_t offset, -get_block_t get_block,dio_iodone_t end_io, -dio_submit_t submit_io,int flags) +ssize_t __blockdev_direct_IO (struct kiocb *iocb,struct inode *inode, +struct block_device *bdev,struct iov_iter *iter, +loff_t offset,get_block_t get_block, +dio_iodone_t end_io,dio_submit_t submit_io, +int flags) {/* * The block device state is needed in the end to finally
@@ -1319,8 +1316,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,prefetch (bdev->bd_queue);prefetch ((char *)bdev->bd_queue +SMP_CACHE_BYTES ); -return do_blockdev_direct_IO (rw, iocb, inode, bdev, iter, offset, - get_block, end_io, submit_io, flags); +return do_blockdev_direct_IO (iocb, inode, bdev, iter, offset, get_block, + end_io, submit_io, flags); }EXPORT_SYMBOL (__blockdev_direct_IO);
fs/ext2/inode.c +1 -1
@@ -864,7 +864,7 @@ ext2_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, ret =dax_do_io (rw, iocb, inode, iter, offset, ext2_get_block,NULL ,DIO_LOCKING ); else - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, + ret =blockdev_direct_IO (iocb, inode, iter, offset, ext2_get_block);if (ret <0 && (rw &WRITE ))ext2_write_failed (mapping, offset + count);
fs/ext3/inode.c +1 -1
@@ -1856,7 +1856,7 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, } retry: - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, ext3_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, ext3_get_block);/* * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again.
fs/ext4/indirect.c +6 -5
@@ -693,9 +693,10 @@ retry: ret =dax_do_io (rw, iocb, inode, iter, offset, ext4_get_block,NULL ,0 ); else - ret =__blockdev_direct_IO (rw, iocb, inode, - inode->i_sb->s_bdev, iter, offset, - ext4_get_block,NULL ,NULL ,0 ); + ret =__blockdev_direct_IO (iocb, inode, + inode->i_sb->s_bdev, iter, + offset, ext4_get_block,NULL , +NULL ,0 );inode_dio_done (inode); }else { locked:
@@ -703,8 +704,8 @@ locked: ret =dax_do_io (rw, iocb, inode, iter, offset, ext4_get_block,NULL ,DIO_LOCKING ); else - ret =blockdev_direct_IO (rw, iocb, inode, iter, - offset, ext4_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, + ext4_get_block);if (unlikely ((rw &WRITE ) && ret <0 )) {loff_t isize =i_size_read (inode);
fs/ext4/inode.c +1 -1
@@ -3038,7 +3038,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, ret =dax_do_io (rw, iocb, inode, iter, offset, get_block_func, ext4_end_io_dio, dio_flags); else - ret =__blockdev_direct_IO (rw, iocb, inode, + ret =__blockdev_direct_IO (iocb, inode, inode->i_sb->s_bdev, iter, offset, get_block_func, ext4_end_io_dio,NULL , dio_flags);
fs/f2fs/data.c +1 -1
@@ -1159,7 +1159,7 @@ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,if (rw &WRITE )__allocate_data_blocks (inode, offset, count); - err =blockdev_direct_IO (rw, iocb, inode, iter, offset, get_data_block); + err =blockdev_direct_IO (iocb, inode, iter, offset, get_data_block);if (err <0 && (rw &WRITE ))f2fs_write_failed (mapping, offset + count);
fs/fat/inode.c +1 -1
@@ -275,7 +275,7 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,* FAT need to use the DIO_LOCKING for avoiding the race * condition of fat_get_block() and ->truncate(). */ - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, fat_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, fat_get_block);if (ret <0 && (rw &WRITE ))fat_write_failed (mapping, offset + count);
fs/gfs2/aops.c +2 -3
@@ -1095,9 +1095,8 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,truncate_inode_pages_range (mapping, lstart, end); } - rv =__blockdev_direct_IO (rw, iocb, inode, inode->i_sb->s_bdev, - iter, offset, - gfs2_get_block_direct,NULL ,NULL ,0 ); + rv =__blockdev_direct_IO (iocb, inode, inode->i_sb->s_bdev, iter, + offset, gfs2_get_block_direct,NULL ,NULL ,0 ); out:gfs2_glock_dq (&gh);gfs2_holder_uninit (&gh);
fs/hfs/inode.c +1 -1
@@ -133,7 +133,7 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,size_t count =iov_iter_count (iter);ssize_t ret; - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, hfs_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, hfs_get_block);/* * In case of error extending write may have instantiated a few
fs/hfsplus/inode.c +1 -2
@@ -131,8 +131,7 @@ static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,size_t count =iov_iter_count (iter);ssize_t ret; - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, - hfsplus_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, hfsplus_get_block);/* * In case of error extending write may have instantiated a few
fs/jfs/inode.c +1 -1
@@ -339,7 +339,7 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,size_t count =iov_iter_count (iter);ssize_t ret; - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, jfs_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, jfs_get_block);/* * In case of error extending write may have instantiated a few
fs/nilfs2/inode.c +1 -2
@@ -318,8 +318,7 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,return 0 ;/* Needs synchronization with the cleaner */ - size =blockdev_direct_IO (rw, iocb, inode, iter, offset, - nilfs_get_block); + size =blockdev_direct_IO (iocb, inode, iter, offset, nilfs_get_block);/* * In case of error extending write may have instantiated a few
fs/ocfs2/aops.c +7 -9
@@ -737,10 +737,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);
@@ -843,11 +842,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); }
fs/reiserfs/inode.c +1 -1
@@ -3286,7 +3286,7 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,size_t count =iov_iter_count (iter);ssize_t ret; - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, + ret =blockdev_direct_IO (iocb, inode, iter, offset, reiserfs_get_blocks_direct_io);/*
fs/udf/inode.c +1 -1
@@ -225,7 +225,7 @@ static ssize_t udf_direct_IO(int rw, struct kiocb *iocb,size_t count =iov_iter_count (iter);ssize_t ret; - ret =blockdev_direct_IO (rw, iocb, inode, iter, offset, udf_get_block); + ret =blockdev_direct_IO (iocb, inode, iter, offset, udf_get_block);if (unlikely (ret <0 && (rw &WRITE )))udf_write_failed (mapping, offset + count);return ret;
fs/xfs/xfs_aops.c +4 -5
@@ -1505,14 +1505,13 @@ xfs_vm_direct_IO(struct block_device *bdev =xfs_find_bdev_for_inode (inode);if (rw &WRITE ) { -return __blockdev_direct_IO (rw, iocb, inode, bdev, iter, - offset, xfs_get_blocks_direct, +return __blockdev_direct_IO (iocb, inode, bdev, iter, offset, + xfs_get_blocks_direct, xfs_end_io_direct_write,NULL ,DIO_ASYNC_EXTEND ); } -return __blockdev_direct_IO (rw, iocb, inode, bdev, iter, - offset, xfs_get_blocks_direct, -NULL ,NULL ,0 ); +return __blockdev_direct_IO (iocb, inode, bdev, iter, offset, + xfs_get_blocks_direct,NULL ,NULL ,0 ); }/*
include/linux/fs.h +12 -10
@@ -2616,16 +2616,18 @@ enum {void dio_end_io (struct bio *bio,int error); -ssize_t __blockdev_direct_IO (int rw,struct kiocb *iocb,struct inode *inode, -struct block_device *bdev,struct iov_iter *iter,loff_t offset, -get_block_t get_block,dio_iodone_t end_io, -dio_submit_t submit_io,int flags); - -static inline ssize_t blockdev_direct_IO (int rw,struct kiocb *iocb, -struct inode *inode,struct iov_iter *iter,loff_t offset, -get_block_t get_block) -{ -return __blockdev_direct_IO (rw, iocb, inode, inode->i_sb->s_bdev, iter, +ssize_t __blockdev_direct_IO (struct kiocb *iocb,struct inode *inode, +struct block_device *bdev,struct iov_iter *iter, +loff_t offset,get_block_t get_block, +dio_iodone_t end_io,dio_submit_t submit_io, +int flags); + +static inline ssize_t blockdev_direct_IO (struct kiocb *iocb, +struct inode *inode, +struct iov_iter *iter,loff_t offset, +get_block_t get_block) +{ +return __blockdev_direct_IO (iocb, inode, inode->i_sb->s_bdev, iter, offset, get_block,NULL ,NULL ,DIO_LOCKING |DIO_SKIP_HOLES ); }
Signature · 1 line
2.3.3
RFC PATCH 3/5 Remove rw from dax_{do_,}io()
In reply to Omar SandovalAnd use iov_iter_rw() instead.
--- fs/dax.c | 27 +++++++++++++-------------- fs/ext2/inode.c | 4 ++-- fs/ext4/indirect.c | 4 ++-- fs/ext4/inode.c | 2 +- include/linux/fs.h | 4 ++-- 5 files changed, 20 insertions(+), 21 deletions(-)
fs/dax.c +13 -14
@@ -98,9 +98,9 @@ static bool buffer_size_valid(struct buffer_head *bh)return bh->b_state !=0 ; } -static ssize_t dax_io (int rw,struct inode *inode,struct iov_iter *iter, -loff_t start,loff_t end,get_block_t get_block, -struct buffer_head *bh) +static ssize_t dax_io (struct inode *inode,struct iov_iter *iter, +loff_t start,loff_t end,get_block_t get_block, +struct buffer_head *bh) {ssize_t retval =0 ;loff_t pos = start;
@@ -109,7 +109,7 @@ static ssize_t dax_io(int rw, struct inode *inode, struct iov_iter *iter,void *addr;bool hole = false; -if (rw !=WRITE ) +if (iov_iter_rw (iter) !=WRITE ) end =min (end,i_size_read (inode));while (pos < end) {
@@ -124,7 +124,7 @@ static ssize_t dax_io(int rw, struct inode *inode, struct iov_iter *iter, bh->b_size =PAGE_ALIGN (end - pos); bh->b_state =0 ; retval =get_block (inode, block, bh, - rw ==WRITE ); +iov_iter_rw (iter) ==WRITE );if (retval)break ;if (!buffer_size_valid (bh))
@@ -137,7 +137,7 @@ static ssize_t dax_io(int rw, struct inode *inode, struct iov_iter *iter, bh->b_size -= done; } - hole = (rw !=WRITE ) && !buffer_written (bh); + hole =iov_iter_rw (iter) !=WRITE && !buffer_written (bh);if (hole) { addr =NULL ; size = bh->b_size - first;
@@ -154,7 +154,7 @@ static ssize_t dax_io(int rw, struct inode *inode, struct iov_iter *iter, max =min (pos + size, end); } -if (rw ==WRITE ) +if (iov_iter_rw (iter) ==WRITE ) len =copy_from_iter (addr, max - pos, iter);else if (!hole) len =copy_to_iter (addr, max - pos, iter);
@@ -173,7 +173,6 @@ static ssize_t dax_io(int rw, struct inode *inode, struct iov_iter *iter,/** * dax_do_io - Perform I/O to a DAX file -* @rw: READ to read or WRITE to write * @iocb: The control block for this I/O * @inode: The file which the I/O is directed at * @iter: The addresses to do I/O from or to
@@ -189,9 +188,9 @@ static ssize_t dax_io(int rw, struct inode *inode, struct iov_iter *iter,* As with do_blockdev_direct_IO(), we increment i_dio_count while the I/O * is in progress. */ -ssize_t dax_do_io (int rw,struct kiocb *iocb,struct inode *inode, -struct iov_iter *iter,loff_t pos, -get_block_t get_block,dio_iodone_t end_io,int flags) +ssize_t dax_do_io (struct kiocb *iocb,struct inode *inode, +struct iov_iter *iter,loff_t pos,get_block_t get_block, +dio_iodone_t end_io,int flags) {struct buffer_head bh;ssize_t retval = -EINVAL ;
@@ -199,7 +198,7 @@ ssize_t dax_do_io(int rw, struct kiocb *iocb, struct inode *inode,memset (&bh,0 ,sizeof (bh)); -if ((flags &DIO_LOCKING ) && (rw ==READ )) { +if ((flags &DIO_LOCKING ) &&iov_iter_rw (iter) ==READ ) {struct address_space *mapping = inode->i_mapping;mutex_lock (&inode->i_mutex); retval =filemap_write_and_wait_range (mapping, pos, end -1 );
@@ -212,9 +211,9 @@ ssize_t dax_do_io(int rw, struct kiocb *iocb, struct inode *inode,/* Protects against truncate */ atomic_inc (&inode->i_dio_count); - retval =dax_io (rw, inode, iter, pos, end, get_block, &bh); + retval =dax_io (inode, iter, pos, end, get_block, &bh); -if ((flags &DIO_LOCKING ) && (rw ==READ )) +if ((flags &DIO_LOCKING ) &&iov_iter_rw (iter) ==READ )mutex_unlock (&inode->i_mutex);if ((retval >0 ) && end_io)
fs/ext2/inode.c +2 -2
@@ -861,8 +861,8 @@ ext2_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,ssize_t ret;if (IS_DAX (inode)) - ret =dax_do_io (rw, iocb, inode, iter, offset, ext2_get_block, -NULL ,DIO_LOCKING ); + ret =dax_do_io (iocb, inode, iter, offset, ext2_get_block,NULL , +DIO_LOCKING );else ret =blockdev_direct_IO (iocb, inode, iter, offset, ext2_get_block);
fs/ext4/indirect.c +2 -2
@@ -690,7 +690,7 @@ retry: goto locked; }if (IS_DAX (inode)) - ret =dax_do_io (rw, iocb, inode, iter, offset, + ret =dax_do_io (iocb, inode, iter, offset, ext4_get_block,NULL ,0 );else ret = __blockdev_direct_IO(iocb, inode,
@@ -701,7 +701,7 @@ retry: }else { locked:if (IS_DAX (inode)) - ret =dax_do_io (rw, iocb, inode, iter, offset, + ret =dax_do_io (iocb, inode, iter, offset, ext4_get_block,NULL ,DIO_LOCKING );else ret = blockdev_direct_IO(iocb, inode, iter, offset,
fs/ext4/inode.c +1 -1
@@ -3035,7 +3035,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, dio_flags =DIO_LOCKING ; }if (IS_DAX (inode)) - ret =dax_do_io (rw, iocb, inode, iter, offset, get_block_func, + ret =dax_do_io (iocb, inode, iter, offset, get_block_func, ext4_end_io_dio, dio_flags);else ret = __blockdev_direct_IO(iocb, inode,
include/linux/fs.h +2 -2
@@ -2591,8 +2591,8 @@ extern loff_t fixed_size_llseek(struct file *file, loff_t offset,extern int generic_file_open (struct inode * inode,struct file * filp);extern int nonseekable_open (struct inode * inode,struct file * filp); -ssize_t dax_do_io (int rw,struct kiocb *,struct inode *,struct iov_iter *, -loff_t ,get_block_t ,dio_iodone_t ,int flags); +ssize_t dax_do_io (struct kiocb *,struct inode *,struct iov_iter *,loff_t , +get_block_t ,dio_iodone_t ,int flags);int dax_clear_blocks (struct inode *,sector_t block,long size);int dax_zero_page_range (struct inode *,loff_t from,unsigned len,get_block_t );int dax_truncate_page (struct inode *,loff_t from,get_block_t );
Signature · 1 line
2.3.3
RFC PATCH 4/5 direct_IO: use iov_iter_rw() instead of rw everywhere
In reply to Omar SandovalThe 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.
--- drivers/staging/lustre/lustre/llite/rw26.c | 18 +++++++++--------- fs/affs/file.c | 4 ++-- fs/btrfs/inode.c | 12 ++++++------ 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 +- 21 files changed, 69 insertions(+), 69 deletions(-)
drivers/staging/lustre/lustre/llite/rw26.c +9 -9
@@ -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);
fs/affs/file.c +2 -2
@@ -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; }
fs/btrfs/inode.c +6 -6
@@ -8037,8 +8037,8 @@ free_ordered:bio_endio (dio_bio, ret); } -static ssize_t check_direct_IO (struct btrfs_root *root,int rw,struct kiocb *iocb, -const struct iov_iter *iter,loff_t offset) +static ssize_t check_direct_IO (struct btrfs_root *root,struct kiocb *iocb, +const struct iov_iter *iter,loff_t offset) {int seg;int i;
@@ -8052,7 +8052,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
@@ -8081,7 +8081,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);
@@ -8099,7 +8099,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
@@ -8123,7 +8123,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 ) {if (ret <0 && ret != -EIOCBQUEUED )btrfs_delalloc_release_space (inode, count);else if (ret >=0 && (size_t )ret < count)
fs/ext2/inode.c +1 -1
@@ -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; }
fs/ext3/inode.c +4 -4
@@ -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; }
fs/ext4/ext4.h +2 -2
@@ -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);
fs/ext4/indirect.c +5 -5
@@ -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;
fs/ext4/inode.c +10 -10
@@ -2953,8 +2953,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;
@@ -2967,8 +2967,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 );
@@ -2977,7 +2977,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 */
@@ -3079,7 +3079,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) {
@@ -3108,12 +3108,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; }
fs/f2fs/data.c +8 -8
@@ -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; }
fs/fat/inode.c +2 -2
@@ -256,7 +256,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.
@@ -276,7 +276,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;
fs/fuse/file.c +7 -6
@@ -2815,11 +2815,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));
@@ -2834,7 +2834,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;/*
@@ -2849,10 +2849,11 @@ 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 (rw ==WRITE ) +if (iov_iter_rw (iter) ==WRITE ) ret =__fuse_direct_write (io, iter, &pos);else ret =__fuse_direct_read (io, iter, &pos);
@@ -2869,7 +2870,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)
fs/gfs2/aops.c +3 -4
@@ -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); }
fs/hfs/inode.c +1 -1
@@ -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;
fs/hfsplus/inode.c +1 -1
@@ -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;
fs/jfs/inode.c +1 -1
@@ -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;
fs/nfs/direct.c +1 -1
@@ -267,7 +267,7 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t#else VM_BUG_ON (iocb->ki_nbytes !=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 */
fs/nilfs2/inode.c +2 -2
@@ -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;
fs/ocfs2/aops.c +1 -1
@@ -841,7 +841,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,
fs/reiserfs/inode.c +1 -1
@@ -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;
fs/udf/inode.c +1 -1
@@ -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; }
fs/xfs/xfs_aops.c +1 -1
@@ -1504,7 +1504,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,
Signature · 6 lines
2.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH 5/5 direct_IO: remove rw from a_ops->direct_IO()
In reply to Omar SandovalNow that no one is using rw, remove it completely.
--- Documentation/filesystems/Locking | 2 +- Documentation/filesystems/vfs.txt | 2 +- drivers/staging/lustre/lustre/llite/rw26.c | 4 ++-- fs/9p/vfs_addr.c | 2 +- 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 | 2 +- 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(+), 57 deletions(-)
Documentation/filesystems/Locking +1 -1
@@ -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);
Documentation/filesystems/vfs.txt +1 -1
@@ -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 *);
drivers/staging/lustre/lustre/llite/rw26.c +2 -2
@@ -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;
fs/9p/vfs_addr.c +1 -1
@@ -259,7 +259,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) {/* * FIXME
fs/affs/file.c +1 -2
@@ -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;
fs/block_dev.c +1 -2
@@ -147,8 +147,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;
fs/btrfs/inode.c +2 -2
@@ -8070,8 +8070,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;
fs/ceph/addr.c +1 -2
@@ -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 );
fs/cifs/file.c +1 -2
@@ -3876,8 +3876,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
fs/exofs/inode.c +2 -2
@@ -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 ; }
fs/ext2/inode.c +1 -2
@@ -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;
fs/ext3/inode.c +2 -2
@@ -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;
fs/ext4/inode.c +2 -2
@@ -3090,8 +3090,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;
fs/f2fs/data.c +2 -2
@@ -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;
fs/fat/inode.c +1 -2
@@ -246,8 +246,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;
fs/fuse/file.c +1 -2
@@ -2798,8 +2798,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) {ssize_t ret =0 ;struct file *file = iocb->ki_filp;
fs/gfs2/aops.c +2 -2
@@ -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;
fs/hfs/inode.c +2 -2
@@ -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;
fs/hfsplus/inode.c +2 -2
@@ -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;
fs/jfs/inode.c +2 -2
@@ -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;
fs/nfs/direct.c +1 -1
@@ -251,7 +251,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;
fs/nilfs2/inode.c +1 -2
@@ -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;
fs/ocfs2/aops.c +1 -3
@@ -817,9 +817,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;
fs/reiserfs/inode.c +2 -2
@@ -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;
fs/udf/file.c +1 -2
@@ -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. */
fs/udf/inode.c +1 -2
@@ -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;
fs/xfs/xfs_aops.c +0 -1
@@ -1496,7 +1496,6 @@ xfs_end_io_direct_write( STATIC ssize_txfs_vm_direct_IO ( -int rw,struct kiocb *iocb,struct iov_iter *iter,loff_t offset)
include/linux/fs.h +1 -1
@@ -361,7 +361,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.
include/linux/nfs_fs.h +1 -1
@@ -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);
mm/filemap.c +2 -2
@@ -1708,7 +1708,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 ) {
@@ -2396,7 +2396,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
mm/page_io.c +1 -3
@@ -278,9 +278,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 ;
Signature · 1 line
2.3.3
Al Viro
maintainerQuoted 15 lines · Omar Sandoval
Hi,
Al, here's some cleanup that you mentioned back in December that I got around to (https://lkml.org/lkml/2014/12/15/28).
In summary, the rw parameter to
a_ops->direct_IO()is redundant with .type in structiov_iter. Additionally, rw is inconsistently checked for being a WRITE; some filesystems do rw == WRITE, others do rw & WRITE, and others do both within the same function :) The distinction is that swapout may OR in theITER_BVECflag in the rw passed to ->direct_IO(), so the two are not equivalent (although this really only happens for swap-over-NFS, but it's scary nonetheless). After looking through all of these, it definitely looks like every check means for ANY write, not just non-kernel writes.
Quoted 5 lines
So, the solution presented here is:
- Add a helper,
iov_iter_rw(), which always returns either READ or WRITE, no ITER_.* or REQ_.* nonsense mixed in. For consistency, the return value is always checked for equality
TBH, I'm not sure I like such calling conventions, but I guess we can live with that.
Quoted 4 lines
I decided to squish all of the filesystems together in patch 4 to avoid inundating the mailing lists with 20+ mostly two-line patches, but I can split those out if that's any better. Additionally, patch 1 pulls
fs.hintouio.h, which seems undesirable.
... and easily avoided if you use a macro instead of inline, without losing type safety or getting double evaluation, etc.
Look: 0 ? (struct T *)0 : (x) always evaluates to x. Now look at 6.5.15p3 in
C99: the second and the third arguments are both pointers, so we are left with p3.4 (both arguments are pointers to qualified or unqualified versions of compatible types), p3.5 (one operand is a pointer and another null pointer constant) and p3.6 (one operand is a pointer to an object or incomplete type, and the other is a pointer to qualified or unqualied version of void.
The first variant means that x is a pointer to qualified or unqualified struct T; the type of result is, per 6.5.15p6, the same as that of x.
The second variant means that x is a null pointer constant ((struct T *)0 isn't one) and result is a null pointer to T.
The third one means that x is a pointer to qualified or unqualified void. The type of result is the same as that of x.
Now note that your variant is no better wrt type safety; worse, actually, since it does accept any pointer to void. (0 ? (struct iov_iter *)0 : (x))->type will reject those. And we obviously don't have double evaluation here either.
Quoted 4 lines · Omar Sandoval
Hi,
Al, here's some cleanup that you mentioned back in December that I got around to (https://lkml.org/lkml/2014/12/15/28).
Applied. See #for-next