@@ -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