summaryrefslogtreecommitdiff
path: root/fs/bcachefs/fs-io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-11-04 14:11:53 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:31 -0400
commit54847d253ab3a4980ed8322a618a9521a2d6cd45 (patch)
treebcd9748e9d70d0c3f7180d001a9fec86a4f54911 /fs/bcachefs/fs-io.c
parent1b783a690dd51a64f58091d060468f7c32f13f20 (diff)
downloadlwn-54847d253ab3a4980ed8322a618a9521a2d6cd45.tar.gz
lwn-54847d253ab3a4980ed8322a618a9521a2d6cd45.zip
bcachefs: DIO write path only needs to shoot down pagecache once, not twice
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fs-io.c')
-rw-r--r--fs/bcachefs/fs-io.c28
1 files changed, 9 insertions, 19 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 3475b388d2fa..185a37a6705e 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -1767,24 +1767,13 @@ static long bch2_dio_write_loop(struct dio_write *dio)
struct bio_vec *bv;
unsigned unaligned;
u64 new_i_size;
- loff_t offset;
bool sync;
long ret;
if (dio->loop)
goto loop;
- /* Write and invalidate pagecache range that we're writing to: */
- offset = req->ki_pos + (dio->op.written << 9);
- ret = write_invalidate_inode_pages_range(mapping,
- offset,
- offset + iov_iter_count(&dio->iter) - 1);
- if (unlikely(ret))
- goto err;
-
while (1) {
- offset = req->ki_pos + (dio->op.written << 9);
-
if (kthread)
kthread_use_mm(dio->mm);
BUG_ON(current->faults_disabled_mapping);
@@ -1814,14 +1803,8 @@ static long bch2_dio_write_loop(struct dio_write *dio)
goto err;
}
- /* gup might have faulted pages back in: */
- ret = write_invalidate_inode_pages_range(mapping,
- offset,
- offset + bio->bi_iter.bi_size - 1);
- if (unlikely(ret))
- goto err;
-
- dio->op.pos = POS(inode->v.i_ino, offset >> 9);
+ dio->op.pos = POS(inode->v.i_ino,
+ (req->ki_pos >> 9) + dio->op.written);
task_io_account_write(bio->bi_iter.bi_size);
@@ -1896,6 +1879,7 @@ static noinline
ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
{
struct file *file = req->ki_filp;
+ struct address_space *mapping = file->f_mapping;
struct bch_inode_info *inode = file_bch_inode(file);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch_io_opts opts = io_opts(c, &inode->ei_inode);
@@ -1977,6 +1961,12 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
dio->op.opts.data_replicas))
goto err_put_bio;
+ ret = write_invalidate_inode_pages_range(mapping,
+ req->ki_pos,
+ req->ki_pos + iter->count - 1);
+ if (unlikely(ret))
+ goto err_put_bio;
+
ret = bch2_dio_write_loop(dio);
err:
if (locked)