summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/fs-io.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index de4e5effca06..eaee546c0fb9 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -443,10 +443,10 @@ static void __bch2_folio_set(struct folio *folio,
unsigned nr_ptrs, unsigned state)
{
struct bch_folio *s = bch2_folio_create(folio, __GFP_NOFAIL);
- unsigned i;
+ unsigned i, sectors = folio_sectors(folio);
- BUG_ON(pg_offset >= PAGE_SECTORS);
- BUG_ON(pg_offset + pg_len > PAGE_SECTORS);
+ BUG_ON(pg_offset >= sectors);
+ BUG_ON(pg_offset + pg_len > sectors);
spin_lock(&s->lock);
@@ -455,7 +455,7 @@ static void __bch2_folio_set(struct folio *folio,
s->s[i].state = state;
}
- if (i == PAGE_SECTORS)
+ if (i == sectors)
s->uptodate = true;
spin_unlock(&s->lock);
@@ -552,15 +552,13 @@ static void mark_pagecache_unallocated(struct bch_inode_info *inode,
&index, end_index, &fbatch)) {
for (i = 0; i < folio_batch_count(&fbatch); i++) {
struct folio *folio = fbatch.folios[i];
- u64 folio_start = folio->index << PAGE_SECTORS_SHIFT;
- u64 folio_end = (folio->index + 1) << PAGE_SECTORS_SHIFT;
+ u64 folio_start = folio_sector(folio);
+ u64 folio_end = folio_end_sector(folio);
unsigned folio_offset = max(start, folio_start) - folio_start;
unsigned folio_len = min(end, folio_end) - folio_offset - folio_start;
struct bch_folio *s;
BUG_ON(end <= folio_start);
- BUG_ON(folio_offset >= PAGE_SECTORS);
- BUG_ON(folio_offset + folio_len > PAGE_SECTORS);
folio_lock(folio);
s = bch2_folio(folio);
@@ -598,15 +596,13 @@ static void mark_pagecache_reserved(struct bch_inode_info *inode,
&index, end_index, &fbatch)) {
for (i = 0; i < folio_batch_count(&fbatch); i++) {
struct folio *folio = fbatch.folios[i];
- u64 folio_start = folio->index << PAGE_SECTORS_SHIFT;
- u64 folio_end = (folio->index + 1) << PAGE_SECTORS_SHIFT;
+ u64 folio_start = folio_sector(folio);
+ u64 folio_end = folio_end_sector(folio);
unsigned folio_offset = max(start, folio_start) - folio_start;
unsigned folio_len = min(end, folio_end) - folio_offset - folio_start;
struct bch_folio *s;
BUG_ON(end <= folio_start);
- BUG_ON(folio_offset >= PAGE_SECTORS);
- BUG_ON(folio_offset + folio_len > PAGE_SECTORS);
folio_lock(folio);
s = bch2_folio(folio);
@@ -660,13 +656,13 @@ static int bch2_get_folio_disk_reservation(struct bch_fs *c,
struct bch_folio *s = bch2_folio_create(folio, 0);
unsigned nr_replicas = inode_nr_replicas(c, inode);
struct disk_reservation disk_res = { 0 };
- unsigned i, disk_res_sectors = 0;
+ unsigned i, sectors = folio_sectors(folio), disk_res_sectors = 0;
int ret;
if (!s)
return -ENOMEM;
- for (i = 0; i < ARRAY_SIZE(s->s); i++)
+ for (i = 0; i < sectors; i++)
disk_res_sectors += sectors_to_reserve(&s->s[i], nr_replicas);
if (!disk_res_sectors)
@@ -680,7 +676,7 @@ static int bch2_get_folio_disk_reservation(struct bch_fs *c,
if (unlikely(ret))
return ret;
- for (i = 0; i < ARRAY_SIZE(s->s); i++)
+ for (i = 0; i < sectors; i++)
s->s[i].replicas_reserved +=
sectors_to_reserve(&s->s[i], nr_replicas);
@@ -761,7 +757,7 @@ static void bch2_clear_folio_bits(struct folio *folio)
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch_folio *s = bch2_folio(folio);
struct disk_reservation disk_res = { 0 };
- int i, dirty_sectors = 0;
+ int i, sectors = folio_sectors(folio), dirty_sectors = 0;
if (!s)
return;
@@ -769,7 +765,7 @@ static void bch2_clear_folio_bits(struct folio *folio)
EBUG_ON(!folio_test_locked(folio));
EBUG_ON(folio_test_writeback(folio));
- for (i = 0; i < ARRAY_SIZE(s->s); i++) {
+ for (i = 0; i < sectors; i++) {
disk_res.sectors += s->s[i].replicas_reserved;
s->s[i].replicas_reserved = 0;
@@ -915,7 +911,7 @@ vm_fault_t bch2_page_mkwrite(struct vm_fault *vmf)
goto out;
}
- len = min_t(loff_t, PAGE_SIZE, isize - folio_pos(folio));
+ len = min_t(loff_t, folio_size(folio), isize - folio_pos(folio));
if (!bch2_folio_create(folio, __GFP_NOFAIL)->uptodate) {
if (bch2_folio_set(c, inode_inum(inode), &folio, 1)) {
@@ -1429,18 +1425,16 @@ static int __bch2_writepage(struct folio *folio,
struct bch_folio *s, orig;
unsigned i, offset, f_sectors, nr_replicas_this_write = U32_MAX;
loff_t i_size = i_size_read(&inode->v);
- pgoff_t end_index = i_size >> PAGE_SHIFT;
int ret;
EBUG_ON(!folio_test_uptodate(folio));
/* Is the folio fully inside i_size? */
- if (folio->index < end_index)
+ if (folio_end_pos(folio) <= i_size)
goto do_io;
/* Is the folio fully outside i_size? (truncate in progress) */
- offset = i_size & (PAGE_SIZE - 1);
- if (folio->index > end_index || !offset) {
+ if (folio_pos(folio) >= i_size) {
folio_unlock(folio);
return 0;
}
@@ -1452,7 +1446,9 @@ static int __bch2_writepage(struct folio *folio,
* the folio size, the remaining memory is zeroed when mapped, and
* writes to that region are not written out to the file."
*/
- folio_zero_segment(folio, offset, folio_size(folio));
+ folio_zero_segment(folio,
+ i_size - folio_pos(folio),
+ folio_size(folio));
do_io:
f_sectors = folio_sectors(folio);
s = bch2_folio_create(folio, __GFP_NOFAIL);
@@ -1521,7 +1517,7 @@ do_io:
if (w->io &&
(w->io->op.res.nr_replicas != nr_replicas_this_write ||
- bio_full(&w->io->op.wbio.bio, PAGE_SIZE) ||
+ bio_full(&w->io->op.wbio.bio, sectors << 9) ||
w->io->op.wbio.bio.bi_iter.bi_size + (sectors << 9) >=
(BIO_MAX_VECS * PAGE_SIZE) ||
bio_end_sector(&w->io->op.wbio.bio) != sector))
@@ -1584,9 +1580,8 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
struct bch_inode_info *inode = to_bch_ei(mapping->host);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch2_folio_reservation *res;
- pgoff_t index = pos >> PAGE_SHIFT;
- unsigned offset = pos & (PAGE_SIZE - 1);
struct folio *folio;
+ unsigned offset;
int ret = -ENOMEM;
res = kmalloc(sizeof(*res), GFP_KERNEL);
@@ -1598,7 +1593,7 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
bch2_pagecache_add_get(inode);
- folio = __filemap_get_folio(mapping, index,
+ folio = __filemap_get_folio(mapping, pos >> PAGE_SHIFT,
FGP_LOCK|FGP_WRITE|FGP_CREAT|FGP_STABLE,
mapping_gfp_mask(mapping));
if (!folio)
@@ -1607,8 +1602,11 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
if (folio_test_uptodate(folio))
goto out;
+ offset = pos - folio_pos(folio);
+ len = min_t(size_t, len, folio_end_pos(folio) - pos);
+
/* If we're writing entire folio, don't need to read it in first: */
- if (len == folio_size(folio))
+ if (!offset && len == folio_size(folio))
goto out;
if (!offset && pos + len >= inode->v.i_size) {
@@ -1617,7 +1615,7 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
goto out;
}
- if (index > inode->v.i_size >> PAGE_SHIFT) {
+ if (folio_pos(folio) >= inode->v.i_size) {
folio_zero_segments(folio, 0, offset, offset + len, folio_size(folio));
flush_dcache_folio(folio);
goto out;
@@ -1669,9 +1667,10 @@ int bch2_write_end(struct file *file, struct address_space *mapping,
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch2_folio_reservation *res = fsdata;
struct folio *folio = page_folio(page);
- unsigned offset = pos & (PAGE_SIZE - 1);
+ unsigned offset = pos - folio_pos(folio);
lockdep_assert_held(&inode->v.i_rwsem);
+ BUG_ON(offset + copied > folio_size(folio));
if (unlikely(copied < len && !folio_test_uptodate(folio))) {
/*