Skip to content

Commit cbed828

Browse files
author
Kent Overstreet
committed
bcachefs: mkwrite() now only dirties one page
Don't dirty the whole folio - fixes write amplification with applications doing mmaped writes. https://www.reddit.com/r/bcachefs/comments/1klzcg1/incredible_amounts_of_write_amplification_when/ Signed-off-by: Kent Overstreet <[email protected]>
1 parent 494d458 commit cbed828

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

fs/bcachefs/fs-io-pagecache.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -605,10 +605,14 @@ vm_fault_t bch2_page_mkwrite(struct vm_fault *vmf)
605605
struct address_space *mapping = file->f_mapping;
606606
struct bch_fs *c = inode->v.i_sb->s_fs_info;
607607
struct bch2_folio_reservation res;
608-
unsigned len;
609-
loff_t isize;
610608
vm_fault_t ret;
611609

610+
loff_t file_offset = round_down(vmf->pgoff << PAGE_SHIFT, block_bytes(c));
611+
unsigned offset = file_offset - folio_pos(folio);
612+
unsigned len = max(PAGE_SIZE, block_bytes(c));
613+
614+
BUG_ON(offset + len > folio_size(folio));
615+
612616
bch2_folio_reservation_init(c, inode, &res);
613617

614618
sb_start_pagefault(inode->v.i_sb);
@@ -623,24 +627,24 @@ vm_fault_t bch2_page_mkwrite(struct vm_fault *vmf)
623627
bch2_pagecache_add_get(inode);
624628

625629
folio_lock(folio);
626-
isize = i_size_read(&inode->v);
630+
u64 isize = i_size_read(&inode->v);
627631

628-
if (folio->mapping != mapping || folio_pos(folio) >= isize) {
632+
if (folio->mapping != mapping || file_offset >= isize) {
629633
folio_unlock(folio);
630634
ret = VM_FAULT_NOPAGE;
631635
goto out;
632636
}
633637

634-
len = min_t(loff_t, folio_size(folio), isize - folio_pos(folio));
638+
len = min_t(unsigned, len, isize - file_offset);
635639

636640
if (bch2_folio_set(c, inode_inum(inode), &folio, 1) ?:
637-
bch2_folio_reservation_get(c, inode, folio, &res, 0, len)) {
641+
bch2_folio_reservation_get(c, inode, folio, &res, offset, len)) {
638642
folio_unlock(folio);
639643
ret = VM_FAULT_SIGBUS;
640644
goto out;
641645
}
642646

643-
bch2_set_folio_dirty(c, inode, folio, &res, 0, len);
647+
bch2_set_folio_dirty(c, inode, folio, &res, offset, len);
644648
bch2_folio_reservation_put(c, inode, &res);
645649

646650
folio_wait_stable(folio);

0 commit comments

Comments
 (0)