[PATCH V8 25/33] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 42 ++ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a005fe2..ca28faa 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -453,7 +453,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, write_bytes -= copied; total_copied += copied; - /* Return to btrfs_file_aio_write to fault page */ + /* Return to btrfs_file_write_iter to fault page */ if (unlikely(copied == 0)) break; @@ -1548,27 +1548,23 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) +struct iov_iter *iter, loff_t pos, + loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); if (written < 0 || written == count) return written; pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1603,9 +1599,8 @@ static void update_time_for_write(struct inode *inode) inode_inc_iversion(inode); } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); @@ -1614,17 +1609,12 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1677,14 +1667,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, atomic_inc(&BTRFS_I(inode)->sync_writers); if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -2543,9 +2529,9 @@ const struct file_operations btrfs_file_operations = { .llseek = btrfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, - .aio_write = btrfs_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap, .open = generic_file_open, .release= btrfs_release_file, -- 1.8.3.4 -- To unsubscribe from
[PATCH 21/22] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 55 ++- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 9ab1bed..576d2f0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1361,27 +1361,23 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) +struct iov_iter *iter, loff_t pos, + loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); if (written < 0 || written == count) return written; pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1398,9 +1394,8 @@ out: return written ? written : err; } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = fdentry(file)->d_inode; @@ -1409,18 +1404,13 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; sb_start_write(inode->i_sb); mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1468,14 +1458,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, } if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -1506,6 +1492,23 @@ out: return num_written ? num_written : err; } +static ssize_t btrfs_file_aio_write(struct kiocb *iocb, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + struct iov_iter i; + int ret; + size_t count; + + ret = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); + if (ret) + return ret; + + iov_iter_init(&i, iov, nr_segs, count, 0); + + return btrfs_file_write_iter(iocb, &i, pos); +} + int btrfs_release_file(struct inode *inode, struct file *filp) { /* @@ -2282,7 +2285,9 @@ const struct file_operations btrfs_file_operations = { .write = do_sync_write, .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, + .read_iter = generic_file_read_iter, .aio_write = btrfs_file_aio_write, + .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap, .open = generic_file_open, .release
[PATCH v4 24/31] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 42 ++ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 9ab1bed..b691dd5 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -375,7 +375,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, write_bytes -= copied; total_copied += copied; - /* Return to btrfs_file_aio_write to fault page */ + /* Return to btrfs_file_write_iter to fault page */ if (unlikely(copied == 0)) break; @@ -1361,27 +1361,23 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) +struct iov_iter *iter, loff_t pos, + loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); if (written < 0 || written == count) return written; pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1398,9 +1394,8 @@ out: return written ? written : err; } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = fdentry(file)->d_inode; @@ -1409,18 +1404,13 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; sb_start_write(inode->i_sb); mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1468,14 +1458,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, } if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -2280,9 +2266,9 @@ const struct file_operations btrfs_file_operations = { .llseek = btrfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, - .aio_write = btrfs_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap, .open = generic_file_open, .release= btrfs_release_file, -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V5 23/30] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 42 ++ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 77061bf..010404a 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -437,7 +437,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, write_bytes -= copied; total_copied += copied; - /* Return to btrfs_file_aio_write to fault page */ + /* Return to btrfs_file_write_iter to fault page */ if (unlikely(copied == 0)) break; @@ -1426,27 +1426,23 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) +struct iov_iter *iter, loff_t pos, + loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); if (written < 0 || written == count) return written; pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1481,9 +1477,8 @@ static void update_time_for_write(struct inode *inode) inode_inc_iversion(inode); } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = fdentry(file)->d_inode; @@ -1492,19 +1487,14 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); sb_start_write(inode->i_sb); mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1557,14 +1547,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, atomic_inc(&BTRFS_I(inode)->sync_writers); if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -2383,9 +2369,9 @@ const struct file_operations btrfs_file_operations = { .llseek = btrfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, - .aio_write = btrfs_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap, .open = generic_file_open, .release= btrfs_
[PATCH V6 23/30] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 42 ++ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f76b1fd..f23e24b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -437,7 +437,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, write_bytes -= copied; total_copied += copied; - /* Return to btrfs_file_aio_write to fault page */ + /* Return to btrfs_file_write_iter to fault page */ if (unlikely(copied == 0)) break; @@ -1426,27 +1426,23 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) +struct iov_iter *iter, loff_t pos, + loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); if (written < 0 || written == count) return written; pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1481,9 +1477,8 @@ static void update_time_for_write(struct inode *inode) inode_inc_iversion(inode); } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = fdentry(file)->d_inode; @@ -1492,19 +1487,14 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); sb_start_write(inode->i_sb); mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1557,14 +1547,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, atomic_inc(&BTRFS_I(inode)->sync_writers); if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -2387,9 +2373,9 @@ const struct file_operations btrfs_file_operations = { .llseek = btrfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, - .aio_write = btrfs_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap, .open = generic_file_open, .release= btrfs_re
[PATCH V7 -next 25/33] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 42 ++ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index b400e5d..1e8e734 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -457,7 +457,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, write_bytes -= copied; total_copied += copied; - /* Return to btrfs_file_aio_write to fault page */ + /* Return to btrfs_file_write_iter to fault page */ if (unlikely(copied == 0)) break; @@ -1445,27 +1445,23 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) +struct iov_iter *iter, loff_t pos, + loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); if (written < 0 || written == count) return written; pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1500,9 +1496,8 @@ static void update_time_for_write(struct inode *inode) inode_inc_iversion(inode); } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); @@ -1511,7 +1506,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); if (!sb_start_file_write(file)) @@ -1519,12 +1514,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1577,14 +1567,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, atomic_inc(&BTRFS_I(inode)->sync_writers); if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -2441,9 +2427,9 @@ const struct file_operations btrfs_file_operations = { .llseek = btrfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, - .aio_write = btrfs_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap,
Re: [PATCH v2 1/5] direct-io: don't dirty ITER_BVEC pages on read
On 11/21/2014 04:08 AM, Omar Sandoval wrote: > Reads through the iov_iter infrastructure for kernel pages shouldn't be > dirtied > by the direct I/O code. > > This is based on Dave Kleikamp's and Ming Lei's previously posted patches. Acked-by: Dave Kleikamp > Cc: Ming Lei > Signed-off-by: Omar Sandoval > --- > fs/direct-io.c | 8 +--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/fs/direct-io.c b/fs/direct-io.c > index e181b6b..e542ce4 100644 > --- a/fs/direct-io.c > +++ b/fs/direct-io.c > @@ -120,6 +120,7 @@ struct dio { > spinlock_t bio_lock;/* protects BIO fields below */ > int page_errors;/* errno from get_user_pages() */ > int is_async; /* is IO async ? */ > + int should_dirty; /* should we mark read pages dirty? */ > bool defer_completion; /* defer AIO completion to workqueue? */ > int io_error; /* IO error in completion path */ > unsigned long refcount; /* direct_io_worker() and bios */ > @@ -392,7 +393,7 @@ static inline void dio_bio_submit(struct dio *dio, struct > dio_submit *sdio) > dio->refcount++; > spin_unlock_irqrestore(&dio->bio_lock, flags); > > - if (dio->is_async && dio->rw == READ) > + if (dio->is_async && dio->rw == READ && dio->should_dirty) > bio_set_pages_dirty(bio); > > if (sdio->submit_io) > @@ -463,13 +464,13 @@ static int dio_bio_complete(struct dio *dio, struct bio > *bio) > if (!uptodate) > dio->io_error = -EIO; > > - if (dio->is_async && dio->rw == READ) { > + if (dio->is_async && dio->rw == READ && dio->should_dirty) { > bio_check_pages_dirty(bio); /* transfers ownership */ > } else { > bio_for_each_segment_all(bvec, bio, i) { > struct page *page = bvec->bv_page; > > - if (dio->rw == READ && !PageCompound(page)) > + if (dio->rw == READ && !PageCompound(page) && > dio->should_dirty) > set_page_dirty_lock(page); > page_cache_release(page); > } > @@ -1177,6 +1178,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, > struct inode *inode, > > dio->inode = inode; > dio->rw = rw; > + dio->should_dirty = !(iter->type & ITER_BVEC); > > /* >* For AIO O_(D)SYNC writes we need to defer completions to a workqueue > -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V9 25/33] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 42 ++ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 72da4df..5e70fc2 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -453,7 +453,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, write_bytes -= copied; total_copied += copied; - /* Return to btrfs_file_aio_write to fault page */ + /* Return to btrfs_file_write_iter to fault page */ if (unlikely(copied == 0)) break; @@ -1557,27 +1557,23 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) +struct iov_iter *iter, loff_t pos, + loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); if (written < 0 || written == count) return written; pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1612,9 +1608,8 @@ static void update_time_for_write(struct inode *inode) inode_inc_iversion(inode); } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); @@ -1623,17 +1618,12 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1686,14 +1676,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, atomic_inc(&BTRFS_I(inode)->sync_writers); if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -2552,9 +2538,9 @@ const struct file_operations btrfs_file_operations = { .llseek = btrfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, - .aio_write = btrfs_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap, .open = generic_file_open, .release= btrfs_release_file, -- 1.8.4 -- To unsubscribe from this
Re: [Jfs-discussion] [PATCH 15/18] jfs: use generic posix ACL infrastructure
On 12/01/2013 05:59 AM, Christoph Hellwig wrote: > Copy the scheme I introduced to btrfs many years ago to only use the > xattr handler for ACLs, but pass plain attrs straight through. Looks good. > > Signed-off-by: Christoph Hellwig Reviewed-by: Dave Kleikamp > --- > fs/jfs/acl.c | 105 -- > fs/jfs/file.c |4 +- > fs/jfs/jfs_acl.h |7 +--- > fs/jfs/jfs_xattr.h |2 + > fs/jfs/namei.c |1 + > fs/jfs/super.c |2 + > fs/jfs/xattr.c | 108 > ++-- > 7 files changed, 89 insertions(+), 140 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2 v2] fs: add SEEK_HOLE and SEEK_DATA flags
On 05/04/2011 02:10 PM, Josef Bacik wrote: On 05/04/2011 03:04 PM, valdis.kletni...@vt.edu wrote: On Wed, 04 May 2011 13:58:39 EDT, Josef Bacik said: -SEEK_HOLE: this moves the file pos to the nearest hole in the file from the given position. Nearest, or next? Solaris defines it as "next", for a good reason - otherwise you can get stuck in a case where the "nearest" hole is back towards the start of the file - and "seek data" will bounce back to the next byte at the other end of the hole. Yeah sorry the log says "nearest" but the code says "next", if you look at it thats how it works. Thanks, The comments in fs.h say "closest". You may want to change them to "next" as well. Thanks, Shaggy -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2 v2] fs: add SEEK_HOLE and SEEK_DATA flags
On 05/04/2011 04:54 PM, Dave Kleikamp wrote: The comments in fs.h say "closest". You may want to change them to "next" as well. Sorry. Missed some of the replies before I responded. Already addressed. Shaggy -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Notes on support for multiple devices for a single filesystem
On Wed, 2008-12-17 at 15:04 -0700, Andreas Dilger wrote: > On Dec 17, 2008 08:23 -0500, Christoph Hellwig wrote: > > An alternative way, supported by optionally by ext3 and reiserfs and > > exclusively supported by jfs is to open the journal device by the device > > number (dev_t) of the block special device. While this doesn't require > > an additional mount option when the device number is stored in the > > filesystem > > superblock it relies on the device number being stable which is getting > > increasingly unlikely in complex storage topologies. > > Just as an FYI here - the dev_t stored in the ext3/4 superblock for the > journal device is only a "cached" device. The journal is properly > identified by its UUID, and should the device mapping change there is a > "journal_dev=" option that can be used to specify the new device. The > one shortcoming is that there is no mount.ext3 helper which does this > journal UUID->dev mapping and automatically passes "journal_dev=" if > needed. An additional FYI. JFS also treats the dev_t in its superblock the same way. Since jfs relies on jfs_fsck running at boot time to ensure that the journal is replayed, jfs_fsck makes sure that the dev_t is accurate. If not, then it scans all of the block devices until it finds the uuid of the journal device, updating the superblock so that the kernel will find the journal. Shaggy -- David Kleikamp IBM Linux Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH -v5][RFC]: mutex: implement adaptive spinning
On Wed, 2009-01-07 at 13:58 -0800, Linus Torvalds wrote: > > On Wed, 7 Jan 2009, Peter Zijlstra wrote: > > > > Do we really have to re-do all that code every loop? > > No, you're right, we can just look up the cpu once. Which makes Andrew's > argument that "probe_kernel_address()" isn't in any hot path even more > true. Do you need to even do that if CONFIG_DEBUG_PAGEALLOC is unset? Something like: #ifdef CONFIG_DEBUG_PAGEALLOC /* * Need to access the cpu field knowing that * DEBUG_PAGEALLOC could have unmapped it if * the mutex owner just released it and exited. */ if (probe_kernel_address(&thread->cpu, cpu)) break; #else cpu = thread->cpu; #endif Shaggy -- David Kleikamp IBM Linux Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 21/22] btrfs: add support for read_iter, write_iter, and direct_IO_bvec
Some helpers were broken out of btrfs_direct_IO() in order to avoid code duplication in new bio_vec-based function. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c |2 + fs/btrfs/inode.c | 116 +- 2 files changed, 82 insertions(+), 36 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 859ba2d..7a2fbc0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1880,6 +1880,8 @@ const struct file_operations btrfs_file_operations = { .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, .aio_write = btrfs_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = generic_file_write_iter, .mmap = btrfs_file_mmap, .open = generic_file_open, .release= btrfs_release_file, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 32214fe..52199e7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6151,24 +6151,14 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io out: return retval; } -static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, - const struct iovec *iov, loff_t offset, - unsigned long nr_segs) + +static ssize_t btrfs_pre_direct_IO(int writing, loff_t offset, size_t count, + struct inode *inode, int *write_bits) { - struct file *file = iocb->ki_filp; - struct inode *inode = file->f_mapping->host; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; u64 lockstart, lockend; ssize_t ret; - int writing = rw & WRITE; - int write_bits = 0; - size_t count = iov_length(iov, nr_segs); - - if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, - offset, nr_segs)) { - return 0; - } lockstart = offset; lockend = offset + count - 1; @@ -6176,7 +6166,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, if (writing) { ret = btrfs_delalloc_reserve_space(inode, count); if (ret) - goto out; + return ret; } while (1) { @@ -6191,8 +6181,8 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, lockend - lockstart + 1); if (!ordered) break; - unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, -&cached_state, GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, +lockend, &cached_state, GFP_NOFS); btrfs_start_ordered_extent(inode, ordered, 1); btrfs_put_ordered_extent(ordered); cond_resched(); @@ -6203,46 +6193,99 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, * the dirty or uptodate bits */ if (writing) { - write_bits = EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING; - ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, -EXTENT_DELALLOC, 0, NULL, &cached_state, -GFP_NOFS); - if (ret) { + *write_bits = EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING; + ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, +lockend, EXTENT_DELALLOC, 0, NULL, +&cached_state, GFP_NOFS); + if (ret) clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, -lockend, EXTENT_LOCKED | write_bits, +lockend, EXTENT_LOCKED | *write_bits, 1, 0, &cached_state, GFP_NOFS); - goto out; - } } - free_extent_state(cached_state); - cached_state = NULL; - ret = __blockdev_direct_IO(rw, iocb, inode, - BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, - iov, offset, nr_segs, btrfs_get_blocks_direct, NULL, - btrfs_submit_direct, 0); + return ret; +} + +static ssize_t btrfs_post_direct_IO(ssize_t ret, loff_t offset, size_t count, + struct inode *inode, int *write_bits) +{ + struct extent_state *cached_state = NULL; if (ret < 0 && ret != -EIOCBQUEUED) { clear_extent_bit(&BTRFS_I(inode)->io_tree, offset, -
[RFC PATCH v2 09/21] dio: Convert direct_IO to use iov_iter
Change the direct_IO aop to take an iov_iter argument rather than an iovec. This will get passed down through most filesystems so that only the __blockdev_direct_IO helper need be aware of whether user or kernel memory is being passed to the function. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: v9fs-develo...@lists.sourceforge.net Cc: linux-btrfs@vger.kernel.org Cc: ceph-de...@vger.kernel.org Cc: linux-e...@vger.kernel.org Cc: OGAWA Hirofumi Cc: jfs-discuss...@lists.sourceforge.net Cc: linux-...@vger.kernel.org Cc: linux-ni...@vger.kernel.org Cc: ocfs2-de...@oss.oracle.com Cc: reiserfs-de...@vger.kernel.org Cc: x...@oss.sgi.com --- Documentation/filesystems/Locking |4 +-- Documentation/filesystems/vfs.txt |4 +-- fs/9p/vfs_addr.c |8 ++--- fs/block_dev.c|8 ++--- fs/btrfs/inode.c | 70 ++--- fs/ceph/addr.c|3 +- fs/direct-io.c| 19 +- fs/ext2/inode.c |8 ++--- fs/ext3/inode.c | 15 fs/ext4/ext4.h|3 +- fs/ext4/indirect.c| 16 - fs/ext4/inode.c | 23 ++-- fs/fat/inode.c| 10 +++--- fs/gfs2/aops.c|7 ++-- fs/hfs/inode.c|7 ++-- fs/hfsplus/inode.c|6 ++-- fs/jfs/inode.c|7 ++-- fs/nfs/direct.c |8 ++--- fs/nilfs2/inode.c |8 ++--- fs/ocfs2/aops.c |8 ++--- fs/reiserfs/inode.c |7 ++-- fs/xfs/xfs_aops.c | 11 +++--- include/linux/fs.h| 18 +- include/linux/nfs_fs.h|3 +- mm/filemap.c | 13 +-- 25 files changed, 144 insertions(+), 150 deletions(-) diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 4fca82e..1e725f7 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -194,8 +194,8 @@ prototypes: int (*invalidatepage) (struct page *, unsigned long); int (*releasepage) (struct page *, int); void (*freepage)(struct page *); - int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, - loff_t offset, unsigned long nr_segs); + int (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, + loff_t offset); int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **, unsigned long *); int (*migratepage)(struct address_space *, struct page *, struct page *); diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 3d9393b..0029302 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -573,8 +573,8 @@ struct address_space_operations { int (*invalidatepage) (struct page *, unsigned long); int (*releasepage) (struct page *, int); void (*freepage)(struct page *); - ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, - loff_t offset, unsigned long nr_segs); + ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, + loff_t offset); struct page* (*get_xip_page)(struct address_space *, sector_t, int); /* migrate the contents of a page to the specified target */ diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 0ad61c6..e70f239 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -239,9 +239,8 @@ 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 + * @iter: array of vectors that define I/O buffer * @pos: offset in file to begin the operation - * @nr_segs: size of iovec array * * The presence of v9fs_direct_IO() in the address space ops vector * allowes open() O_DIRECT flags which would have failed otherwise. @@ -255,8 +254,7 @@ static int v9fs_launder_page(struct page *page) * */ static ssize_t -v9fs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, - loff_t pos, unsigned long nr_segs) +v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) { /* * FIXME @@ -265,7 +263,7 @@ v9fs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, */ p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%s) off/no(%lld/%lu) EINVAL\n", iocb->ki_filp->f_path.dentry->d_name.name, -(long long)pos, nr_segs); +(long long)pos, iter->nr_segs); return -EINVAL; } diff --git a/fs/block_dev.c
[RFC PATCH v2 20/21] btrfs: add support for read_iter and write_iter
btrfs can use generic_file_read_iter(). Base btrfs_file_write_iter() on btrfs_file_aio_write(), then have the latter call the former. Signed-off-by: Dave Kleikamp Cc: Zach Brown Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org --- fs/btrfs/file.c | 55 ++- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e8d06b6..31275d1 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1285,20 +1285,17 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } static ssize_t __btrfs_direct_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos, - loff_t *ppos, size_t count, size_t ocount) + struct iov_iter *iter, + loff_t pos, loff_t *ppos, size_t count) { struct file *file = iocb->ki_filp; struct inode *inode = fdentry(file)->d_inode; - struct iov_iter i; ssize_t written; ssize_t written_buffered; loff_t endbyte; int err; - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, - count, ocount); + written = generic_file_direct_write_iter(iocb, iter, pos, ppos, count); /* * the generic O_DIRECT will update in-memory i_size after the @@ -1317,8 +1314,7 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, pos += written; count -= written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = __btrfs_buffered_write(file, &i, pos); + written_buffered = __btrfs_buffered_write(file, iter, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1335,9 +1331,8 @@ out: return written ? written : err; } -static ssize_t btrfs_file_aio_write(struct kiocb *iocb, - const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static ssize_t btrfs_file_write_iter(struct kiocb *iocb, +struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = fdentry(file)->d_inode; @@ -1346,18 +1341,13 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count, ocount; + size_t count; vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); mutex_lock(&inode->i_mutex); - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); - if (err) { - mutex_unlock(&inode->i_mutex); - goto out; - } - count = ocount; + count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1406,14 +1396,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, } if (unlikely(file->f_flags & O_DIRECT)) { - num_written = __btrfs_direct_write(iocb, iov, nr_segs, - pos, ppos, count, ocount); + num_written = __btrfs_direct_write(iocb, iter, pos, ppos, + count); } else { - struct iov_iter i; - - iov_iter_init(&i, iov, nr_segs, count, num_written); - - num_written = __btrfs_buffered_write(file, &i, pos); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; } @@ -1443,6 +1429,23 @@ out: return num_written ? num_written : err; } +static ssize_t btrfs_file_aio_write(struct kiocb *iocb, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + struct iov_iter i; + int ret; + size_t count; + + ret = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); + if (ret) + return ret; + + iov_iter_init(&i, iov, nr_segs, count, 0); + + return btrfs_file_write_iter(iocb, &i, pos); +} + int btrfs_release_file(struct inode *inode, struct file *filp) { /* @@ -1874,7 +1877,9 @@ const struct file_operations btrfs_file_operations = { .write = do_sync_write, .aio_read = generic_file_aio_read, .splice_read= generic_file_splice_read, + .read_iter = generic_file_read_iter, .aio_write = btrfs_file_aio_write,