Commit 959f7368 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_truncate_page() large folio conversion

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent c42b57c4
...@@ -2696,8 +2696,8 @@ static inline int range_has_data(struct bch_fs *c, u32 subvol, ...@@ -2696,8 +2696,8 @@ static inline int range_has_data(struct bch_fs *c, u32 subvol,
return ret; return ret;
} }
static int __bch2_truncate_page(struct bch_inode_info *inode, static int __bch2_truncate_folio(struct bch_inode_info *inode,
pgoff_t index, loff_t start, loff_t end) pgoff_t index, loff_t start, loff_t end)
{ {
struct bch_fs *c = inode->v.i_sb->s_fs_info; struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct address_space *mapping = inode->v.i_mapping; struct address_space *mapping = inode->v.i_mapping;
...@@ -2709,15 +2709,6 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, ...@@ -2709,15 +2709,6 @@ static int __bch2_truncate_page(struct bch_inode_info *inode,
s64 i_sectors_delta = 0; s64 i_sectors_delta = 0;
int ret = 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); folio = filemap_lock_folio(mapping, index);
if (!folio) { if (!folio) {
/* /*
...@@ -2738,6 +2729,19 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, ...@@ -2738,6 +2729,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); s = bch2_folio_create(folio, 0);
if (!s) { if (!s) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -2752,11 +2756,6 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, ...@@ -2752,11 +2756,6 @@ static int __bch2_truncate_page(struct bch_inode_info *inode,
BUG_ON(!s->uptodate); 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; for (i = round_up(start_offset, block_bytes(c)) >> 9;
i < round_down(end_offset, block_bytes(c)) >> 9; i < round_down(end_offset, block_bytes(c)) >> 9;
i++) { i++) {
...@@ -2773,8 +2772,8 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, ...@@ -2773,8 +2772,8 @@ static int __bch2_truncate_page(struct bch_inode_info *inode,
* writeback - doing an i_size update if necessary - or whether it will * writeback - doing an i_size update if necessary - or whether it will
* be responsible for the i_size update: * be responsible for the i_size update:
*/ */
ret = s->s[(min_t(u64, inode->v.i_size - (index << PAGE_SHIFT), ret = s->s[(min(inode->v.i_size, folio_end_pos(folio)) -
PAGE_SIZE) - 1) >> 9].state >= SECTOR_DIRTY; folio_pos(folio) - 1) >> 9].state >= SECTOR_DIRTY;
folio_zero_segment(folio, start_offset, end_offset); folio_zero_segment(folio, start_offset, end_offset);
...@@ -2800,23 +2799,23 @@ static int __bch2_truncate_page(struct bch_inode_info *inode, ...@@ -2800,23 +2799,23 @@ static int __bch2_truncate_page(struct bch_inode_info *inode,
return ret; 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, return __bch2_truncate_folio(inode, from >> PAGE_SHIFT,
from, round_up(from, PAGE_SIZE)); from, ANYSINT_MAX(loff_t));
} }
static int bch2_truncate_pages(struct bch_inode_info *inode, static int bch2_truncate_folios(struct bch_inode_info *inode,
loff_t start, loff_t end) loff_t start, loff_t end)
{ {
int ret = __bch2_truncate_page(inode, start >> PAGE_SHIFT, int ret = __bch2_truncate_folio(inode, start >> PAGE_SHIFT,
start, end); start, end);
if (ret >= 0 && if (ret >= 0 &&
start >> PAGE_SHIFT != end >> PAGE_SHIFT) start >> PAGE_SHIFT != end >> PAGE_SHIFT)
ret = __bch2_truncate_page(inode, ret = __bch2_truncate_folio(inode,
end >> PAGE_SHIFT, (end - 1) >> PAGE_SHIFT,
start, end); start, end);
return ret; return ret;
} }
...@@ -2911,7 +2910,7 @@ int bch2_truncate(struct mnt_idmap *idmap, ...@@ -2911,7 +2910,7 @@ int bch2_truncate(struct mnt_idmap *idmap,
iattr->ia_valid &= ~ATTR_SIZE; 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)) if (unlikely(ret < 0))
goto err; goto err;
...@@ -2989,7 +2988,7 @@ static long bchfs_fpunch(struct bch_inode_info *inode, loff_t offset, loff_t len ...@@ -2989,7 +2988,7 @@ static long bchfs_fpunch(struct bch_inode_info *inode, loff_t offset, loff_t len
bool truncated_last_page; bool truncated_last_page;
int ret = 0; int ret = 0;
ret = bch2_truncate_pages(inode, offset, end); ret = bch2_truncate_folios(inode, offset, end);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
goto err; goto err;
...@@ -3310,7 +3309,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode, ...@@ -3310,7 +3309,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
} }
if (mode & FALLOC_FL_ZERO_RANGE) { if (mode & FALLOC_FL_ZERO_RANGE) {
ret = bch2_truncate_pages(inode, offset, end); ret = bch2_truncate_folios(inode, offset, end);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment