Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit efa064b

Browse files
committed
fix(inline-write): correct filemap_get_folios_tag misuse + remove unused var
Two bug fixes against the initial INLINE write implementation (commit 4779581): 1. writepages: filemap_get_folios_tag expects pgoff_t* (unsigned long), but we were passing &wbc->range_start which is loff_t* (long long). Type mismatch caused the kernel module build to fail. Fix: simplify writepages to use filemap_get_folio(mapping, 0) directly, since the v2.0 single-block scope (write_begin rejects pos+len > 3824 with -EFBIG) guarantees there is at most one folio in the mapping. Range scan with folio_batch is over-specified for single-block; the simpler approach is also more anti-NAK clean. When multi-block INLINE write is implemented in v2.x, we will switch to the ext4 pattern: pgoff_t index = pos >> PAGE_SHIFT, while (index <= end) { filemap_get_folios_tag(...); }. 2. write_begin: 'struct inode *inode = mapping->host' was declared but never used. Removed. LOC: file_inline.c 683 -> 664 (-19 LOC, simplification) Module compile: clean, 0 warnings on file_inline.c (2 pre-existing warnings in super.c on frame size are unrelated)
1 parent 39936fb commit efa064b

1 file changed

Lines changed: 65 additions & 84 deletions

File tree

file_inline.c

Lines changed: 65 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,6 @@ static int beamfs_inline_write_begin(const struct kiocb *iocb,
459459
loff_t pos, unsigned int len,
460460
struct folio **foliop, void **fsdata)
461461
{
462-
struct inode *inode = mapping->host;
463462
struct folio *folio;
464463
int ret;
465464

@@ -553,102 +552,84 @@ static int beamfs_inline_writepages(struct address_space *mapping,
553552
{
554553
struct inode *inode = mapping->host;
555554
struct super_block *sb = inode->i_sb;
556-
struct folio_batch fbatch;
557555
struct folio *folio;
558-
unsigned int i;
559-
int ret = 0;
560-
561-
folio_batch_init(&fbatch);
562-
563-
while (filemap_get_folios_tag(mapping, &wbc->range_start,
564-
wbc->range_end >> PAGE_SHIFT,
565-
PAGECACHE_TAG_DIRTY, &fbatch)) {
566-
for (i = 0; i < folio_batch_count(&fbatch); i++) {
567-
struct buffer_head *bh;
568-
u64 phys = 0;
569-
u8 *src;
570-
unsigned int sb_idx;
571-
572-
folio = fbatch.folios[i];
573-
574-
/* v2.0 scope: only process folio index 0. */
575-
if (folio->index != 0) {
576-
pr_warn_ratelimited("beamfs/inline: writepages: skipping folio index %lu (single-block scope)\n",
577-
folio->index);
578-
continue;
579-
}
556+
struct buffer_head *bh;
557+
u64 phys = 0;
558+
u8 *src;
559+
unsigned int sb_idx;
560+
int ret;
580561

581-
folio_lock(folio);
562+
/*
563+
* Single-block scope (v2.0): an INLINE-formatted file occupies at
564+
* most one folio (index 0). write_begin enforces pos+len <= 3824
565+
* with -EFBIG, so by the time writepages is called there is at
566+
* most one dirty folio in the mapping. Multi-block INLINE write
567+
* is part of the v2.x roadmap.
568+
*/
569+
folio = filemap_get_folio(mapping, 0);
570+
if (IS_ERR(folio))
571+
return 0; /* No folio in cache, nothing to writeback. */
582572

583-
if (!folio_test_dirty(folio) ||
584-
folio->mapping != mapping) {
585-
folio_unlock(folio);
586-
continue;
587-
}
573+
folio_lock(folio);
588574

589-
ret = beamfs_inline_lookup_or_alloc_phys(inode, 0, &phys);
590-
if (ret < 0) {
591-
folio_unlock(folio);
592-
goto out_release;
593-
}
575+
/* Re-check after lock: folio may have been evicted/cleaned. */
576+
if (!folio_test_dirty(folio) || folio->mapping != mapping) {
577+
folio_unlock(folio);
578+
folio_put(folio);
579+
return 0;
580+
}
594581

595-
bh = sb_bread(sb, phys);
596-
if (!bh) {
597-
pr_err_ratelimited("beamfs/inline: writepages: sb_bread phys=%llu failed\n",
598-
(unsigned long long)phys);
599-
ret = -EIO;
600-
folio_unlock(folio);
601-
goto out_release;
602-
}
582+
ret = beamfs_inline_lookup_or_alloc_phys(inode, 0, &phys);
583+
if (ret < 0)
584+
goto out_unlock;
603585

604-
folio_clear_dirty_for_io(folio);
605-
folio_start_writeback(folio);
586+
bh = sb_bread(sb, phys);
587+
if (!bh) {
588+
pr_err_ratelimited("beamfs/inline: writepages: sb_bread phys=%llu failed\n",
589+
(unsigned long long)phys);
590+
ret = -EIO;
591+
goto out_unlock;
592+
}
606593

607-
/* Scatter folio bytes into bh: 16 segments of 239 bytes. */
608-
src = kmap_local_folio(folio, 0);
609-
for (sb_idx = 0; sb_idx < BEAMFS_DATA_INLINE_SUBBLOCKS; sb_idx++) {
610-
memcpy((u8 *)bh->b_data + (size_t)sb_idx * BEAMFS_SUBBLOCK_TOTAL,
611-
src + (size_t)sb_idx * BEAMFS_SUBBLOCK_DATA,
612-
BEAMFS_SUBBLOCK_DATA);
613-
}
614-
kunmap_local(src);
615-
616-
/* RS encode all 16 subblocks: parity at offset 239 within each 255-byte stride. */
617-
ret = beamfs_rs_encode_region(
618-
(u8 *)bh->b_data, BEAMFS_SUBBLOCK_TOTAL,
619-
(u8 *)bh->b_data + BEAMFS_SUBBLOCK_DATA, BEAMFS_SUBBLOCK_TOTAL,
620-
BEAMFS_SUBBLOCK_DATA, BEAMFS_DATA_INLINE_SUBBLOCKS);
621-
if (ret < 0) {
622-
pr_err_ratelimited("beamfs/inline: writepages: rs_encode_region failed: %d\n",
623-
ret);
624-
brelse(bh);
625-
folio_end_writeback(folio);
626-
folio_unlock(folio);
627-
goto out_release;
628-
}
594+
folio_clear_dirty_for_io(folio);
595+
folio_start_writeback(folio);
629596

630-
/* Zero the 16-byte pad zone (4080..4096). */
631-
memset((u8 *)bh->b_data + BEAMFS_DATA_INLINE_TOTAL, 0,
632-
BEAMFS_DATA_INLINE_PAD);
597+
/* Scatter folio bytes into bh: 16 segments of 239 bytes. */
598+
src = kmap_local_folio(folio, 0);
599+
for (sb_idx = 0; sb_idx < BEAMFS_DATA_INLINE_SUBBLOCKS; sb_idx++) {
600+
memcpy((u8 *)bh->b_data + (size_t)sb_idx * BEAMFS_SUBBLOCK_TOTAL,
601+
src + (size_t)sb_idx * BEAMFS_SUBBLOCK_DATA,
602+
BEAMFS_SUBBLOCK_DATA);
603+
}
604+
kunmap_local(src);
633605

634-
/* Autonomic durability: sync the encoded block to disk. */
635-
mark_buffer_dirty(bh);
636-
ret = sync_dirty_buffer(bh);
637-
brelse(bh);
606+
/* RS encode all 16 subblocks: parity at offset 239 within each 255-byte stride. */
607+
ret = beamfs_rs_encode_region(
608+
(u8 *)bh->b_data, BEAMFS_SUBBLOCK_TOTAL,
609+
(u8 *)bh->b_data + BEAMFS_SUBBLOCK_DATA, BEAMFS_SUBBLOCK_TOTAL,
610+
BEAMFS_SUBBLOCK_DATA, BEAMFS_DATA_INLINE_SUBBLOCKS);
611+
if (ret < 0) {
612+
pr_err_ratelimited("beamfs/inline: writepages: rs_encode_region failed: %d\n",
613+
ret);
614+
brelse(bh);
615+
folio_end_writeback(folio);
616+
goto out_unlock;
617+
}
638618

639-
folio_end_writeback(folio);
640-
folio_unlock(folio);
619+
/* Zero the 16-byte pad zone (4080..4096). */
620+
memset((u8 *)bh->b_data + BEAMFS_DATA_INLINE_TOTAL, 0,
621+
BEAMFS_DATA_INLINE_PAD);
641622

642-
if (ret < 0)
643-
goto out_release;
644-
}
645-
folio_batch_release(&fbatch);
646-
}
623+
/* Autonomic durability: sync the encoded block to disk. */
624+
mark_buffer_dirty(bh);
625+
ret = sync_dirty_buffer(bh);
626+
brelse(bh);
647627

648-
return 0;
628+
folio_end_writeback(folio);
649629

650-
out_release:
651-
folio_batch_release(&fbatch);
630+
out_unlock:
631+
folio_unlock(folio);
632+
folio_put(folio);
652633
return ret;
653634
}
654635

0 commit comments

Comments
 (0)