diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-03-19 18:03:22 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-05-12 19:42:32 -0400 |
commit | 34a92769f712a8b967d67ab8db105eda7fa7aef0 (patch) | |
tree | 6487b4f05654776522aff83c426fe594250bd02e | |
parent | 534d669e39c84bce6def81af3ec11d33904ae2d2 (diff) |
bcachefs: bch2_truncate_page() large folio conversion
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/fs-io.c | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index 4f437163efb5..cf5dcade995d 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -2694,8 +2694,8 @@ err: return ret; } -static int __bch2_truncate_page(struct bch_inode_info *inode, - pgoff_t index, loff_t start, loff_t end) +static int __bch2_truncate_folio(struct bch_inode_info *inode, + pgoff_t index, loff_t start, loff_t end) { struct bch_fs *c = inode->v.i_sb->s_fs_info; struct address_space *mapping = inode->v.i_mapping; @@ -2707,15 +2707,6 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, s64 i_sectors_delta = 0; int ret = 0; - /* Page boundary? Nothing to do */ - if (!((index == start >> PAGE_SHIFT && start_offset) || - (index == end >> PAGE_SHIFT && end_offset != PAGE_SIZE))) - return 0; - - /* Above i_size? */ - if (index << PAGE_SHIFT >= inode->v.i_size) - return 0; - folio = filemap_lock_folio(mapping, index); if (!folio) { /* @@ -2736,6 +2727,19 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, } } + BUG_ON(start >= folio_end_pos(folio)); + BUG_ON(end <= folio_pos(folio)); + + start_offset = max(start, folio_pos(folio)) - folio_pos(folio); + end_offset = min(end, folio_end_pos(folio)) - folio_pos(folio); + + /* Folio boundary? Nothing to do */ + if (start_offset == 0 && + end_offset == folio_size(folio)) { + ret = 0; + goto unlock; + } + s = bch2_folio_create(folio, 0); if (!s) { ret = -ENOMEM; @@ -2750,11 +2754,6 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, BUG_ON(!s->uptodate); - if (index != start >> PAGE_SHIFT) - start_offset = 0; - if (index != end >> PAGE_SHIFT) - end_offset = PAGE_SIZE; - for (i = round_up(start_offset, block_bytes(c)) >> 9; i < round_down(end_offset, block_bytes(c)) >> 9; i++) { @@ -2771,8 +2770,8 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, * writeback - doing an i_size update if necessary - or whether it will * be responsible for the i_size update: */ - ret = s->s[(min_t(u64, inode->v.i_size - (index << PAGE_SHIFT), - PAGE_SIZE) - 1) >> 9].state >= SECTOR_DIRTY; + ret = s->s[(min(inode->v.i_size, folio_end_pos(folio)) - + folio_pos(folio) - 1) >> 9].state >= SECTOR_DIRTY; folio_zero_segment(folio, start_offset, end_offset); @@ -2798,23 +2797,23 @@ out: return ret; } -static int bch2_truncate_page(struct bch_inode_info *inode, loff_t from) +static int bch2_truncate_folio(struct bch_inode_info *inode, loff_t from) { - return __bch2_truncate_page(inode, from >> PAGE_SHIFT, - from, round_up(from, PAGE_SIZE)); + return __bch2_truncate_folio(inode, from >> PAGE_SHIFT, + from, ANYSINT_MAX(loff_t)); } -static int bch2_truncate_pages(struct bch_inode_info *inode, - loff_t start, loff_t end) +static int bch2_truncate_folios(struct bch_inode_info *inode, + loff_t start, loff_t end) { - int ret = __bch2_truncate_page(inode, start >> PAGE_SHIFT, - start, end); + int ret = __bch2_truncate_folio(inode, start >> PAGE_SHIFT, + start, end); if (ret >= 0 && start >> PAGE_SHIFT != end >> PAGE_SHIFT) - ret = __bch2_truncate_page(inode, - end >> PAGE_SHIFT, - start, end); + ret = __bch2_truncate_folio(inode, + (end - 1) >> PAGE_SHIFT, + start, end); return ret; } @@ -2909,7 +2908,7 @@ int bch2_truncate(struct mnt_idmap *idmap, iattr->ia_valid &= ~ATTR_SIZE; - ret = bch2_truncate_page(inode, iattr->ia_size); + ret = bch2_truncate_folio(inode, iattr->ia_size); if (unlikely(ret < 0)) goto err; @@ -2987,7 +2986,7 @@ static long bchfs_fpunch(struct bch_inode_info *inode, loff_t offset, loff_t len bool truncated_last_page; int ret = 0; - ret = bch2_truncate_pages(inode, offset, end); + ret = bch2_truncate_folios(inode, offset, end); if (unlikely(ret < 0)) goto err; @@ -3308,7 +3307,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode, } if (mode & FALLOC_FL_ZERO_RANGE) { - ret = bch2_truncate_pages(inode, offset, end); + ret = bch2_truncate_folios(inode, offset, end); if (unlikely(ret < 0)) return ret; |