Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs: Fold fsync_buffers_list() into sync_mapping_buffers()

There's only single caller of fsync_buffers_list() so untangle the code
a bit by folding fsync_buffers_list() into sync_mapping_buffers(). Also
merge the comments and update them to reflect current state of code.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260326095354.16340-71-jack@suse.cz
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Jan Kara and committed by
Christian Brauner
8fed8176 cae6b7a0

+80 -100
+80 -100
fs/buffer.c
··· 54 54 55 55 #include "internal.h" 56 56 57 - static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); 58 57 static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh, 59 58 enum rw_hint hint, struct writeback_control *wbc); 60 59 ··· 530 531 * @mapping: the mapping which wants those buffers written 531 532 * 532 533 * Starts I/O against the buffers at mapping->i_private_list, and waits upon 533 - * that I/O. 534 + * that I/O. Basically, this is a convenience function for fsync(). @mapping 535 + * is a file or directory which needs those buffers to be written for a 536 + * successful fsync(). 534 537 * 535 - * Basically, this is a convenience function for fsync(). 536 - * @mapping is a file or directory which needs those buffers to be written for 537 - * a successful fsync(). 538 + * We have conflicting pressures: we want to make sure that all 539 + * initially dirty buffers get waited on, but that any subsequently 540 + * dirtied buffers don't. After all, we don't want fsync to last 541 + * forever if somebody is actively writing to the file. 542 + * 543 + * Do this in two main stages: first we copy dirty buffers to a 544 + * temporary inode list, queueing the writes as we go. Then we clean 545 + * up, waiting for those writes to complete. mark_buffer_dirty_inode() 546 + * doesn't touch b_assoc_buffers list if b_assoc_map is not NULL so we 547 + * are sure the buffer stays on our list until IO completes (at which point 548 + * it can be reaped). 538 549 */ 539 550 int sync_mapping_buffers(struct address_space *mapping) 540 551 { 541 552 struct address_space *buffer_mapping = 542 553 mapping->host->i_sb->s_bdev->bd_mapping; 554 + struct buffer_head *bh; 555 + int err = 0; 556 + struct blk_plug plug; 557 + LIST_HEAD(tmp); 543 558 544 559 if (list_empty(&mapping->i_private_list)) 545 560 return 0; 546 561 547 - return fsync_buffers_list(&buffer_mapping->i_private_lock, 548 - &mapping->i_private_list); 562 + blk_start_plug(&plug); 563 + 564 + spin_lock(&buffer_mapping->i_private_lock); 565 + while (!list_empty(&mapping->i_private_list)) { 566 + bh = BH_ENTRY(mapping->i_private_list.next); 567 + WARN_ON_ONCE(bh->b_assoc_map != mapping); 568 + __remove_assoc_queue(bh); 569 + /* Avoid race with mark_buffer_dirty_inode() which does 570 + * a lockless check and we rely on seeing the dirty bit */ 571 + smp_mb(); 572 + if (buffer_dirty(bh) || buffer_locked(bh)) { 573 + list_add(&bh->b_assoc_buffers, &tmp); 574 + bh->b_assoc_map = mapping; 575 + if (buffer_dirty(bh)) { 576 + get_bh(bh); 577 + spin_unlock(&buffer_mapping->i_private_lock); 578 + /* 579 + * Ensure any pending I/O completes so that 580 + * write_dirty_buffer() actually writes the 581 + * current contents - it is a noop if I/O is 582 + * still in flight on potentially older 583 + * contents. 584 + */ 585 + write_dirty_buffer(bh, REQ_SYNC); 586 + 587 + /* 588 + * Kick off IO for the previous mapping. Note 589 + * that we will not run the very last mapping, 590 + * wait_on_buffer() will do that for us 591 + * through sync_buffer(). 592 + */ 593 + brelse(bh); 594 + spin_lock(&buffer_mapping->i_private_lock); 595 + } 596 + } 597 + } 598 + 599 + spin_unlock(&buffer_mapping->i_private_lock); 600 + blk_finish_plug(&plug); 601 + spin_lock(&buffer_mapping->i_private_lock); 602 + 603 + while (!list_empty(&tmp)) { 604 + bh = BH_ENTRY(tmp.prev); 605 + get_bh(bh); 606 + __remove_assoc_queue(bh); 607 + /* Avoid race with mark_buffer_dirty_inode() which does 608 + * a lockless check and we rely on seeing the dirty bit */ 609 + smp_mb(); 610 + if (buffer_dirty(bh)) { 611 + list_add(&bh->b_assoc_buffers, 612 + &mapping->i_private_list); 613 + bh->b_assoc_map = mapping; 614 + } 615 + spin_unlock(&buffer_mapping->i_private_lock); 616 + wait_on_buffer(bh); 617 + if (!buffer_uptodate(bh)) 618 + err = -EIO; 619 + brelse(bh); 620 + spin_lock(&buffer_mapping->i_private_lock); 621 + } 622 + spin_unlock(&buffer_mapping->i_private_lock); 623 + return err; 549 624 } 550 625 EXPORT_SYMBOL(sync_mapping_buffers); 551 626 ··· 791 718 return newly_dirty; 792 719 } 793 720 EXPORT_SYMBOL(block_dirty_folio); 794 - 795 - /* 796 - * Write out and wait upon a list of buffers. 797 - * 798 - * We have conflicting pressures: we want to make sure that all 799 - * initially dirty buffers get waited on, but that any subsequently 800 - * dirtied buffers don't. After all, we don't want fsync to last 801 - * forever if somebody is actively writing to the file. 802 - * 803 - * Do this in two main stages: first we copy dirty buffers to a 804 - * temporary inode list, queueing the writes as we go. Then we clean 805 - * up, waiting for those writes to complete. 806 - * 807 - * During this second stage, any subsequent updates to the file may end 808 - * up refiling the buffer on the original inode's dirty list again, so 809 - * there is a chance we will end up with a buffer queued for write but 810 - * not yet completed on that list. So, as a final cleanup we go through 811 - * the osync code to catch these locked, dirty buffers without requeuing 812 - * any newly dirty buffers for write. 813 - */ 814 - static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) 815 - { 816 - struct buffer_head *bh; 817 - struct address_space *mapping; 818 - int err = 0; 819 - struct blk_plug plug; 820 - LIST_HEAD(tmp); 821 - 822 - blk_start_plug(&plug); 823 - 824 - spin_lock(lock); 825 - while (!list_empty(list)) { 826 - bh = BH_ENTRY(list->next); 827 - mapping = bh->b_assoc_map; 828 - __remove_assoc_queue(bh); 829 - /* Avoid race with mark_buffer_dirty_inode() which does 830 - * a lockless check and we rely on seeing the dirty bit */ 831 - smp_mb(); 832 - if (buffer_dirty(bh) || buffer_locked(bh)) { 833 - list_add(&bh->b_assoc_buffers, &tmp); 834 - bh->b_assoc_map = mapping; 835 - if (buffer_dirty(bh)) { 836 - get_bh(bh); 837 - spin_unlock(lock); 838 - /* 839 - * Ensure any pending I/O completes so that 840 - * write_dirty_buffer() actually writes the 841 - * current contents - it is a noop if I/O is 842 - * still in flight on potentially older 843 - * contents. 844 - */ 845 - write_dirty_buffer(bh, REQ_SYNC); 846 - 847 - /* 848 - * Kick off IO for the previous mapping. Note 849 - * that we will not run the very last mapping, 850 - * wait_on_buffer() will do that for us 851 - * through sync_buffer(). 852 - */ 853 - brelse(bh); 854 - spin_lock(lock); 855 - } 856 - } 857 - } 858 - 859 - spin_unlock(lock); 860 - blk_finish_plug(&plug); 861 - spin_lock(lock); 862 - 863 - while (!list_empty(&tmp)) { 864 - bh = BH_ENTRY(tmp.prev); 865 - get_bh(bh); 866 - mapping = bh->b_assoc_map; 867 - __remove_assoc_queue(bh); 868 - /* Avoid race with mark_buffer_dirty_inode() which does 869 - * a lockless check and we rely on seeing the dirty bit */ 870 - smp_mb(); 871 - if (buffer_dirty(bh)) { 872 - list_add(&bh->b_assoc_buffers, 873 - &mapping->i_private_list); 874 - bh->b_assoc_map = mapping; 875 - } 876 - spin_unlock(lock); 877 - wait_on_buffer(bh); 878 - if (!buffer_uptodate(bh)) 879 - err = -EIO; 880 - brelse(bh); 881 - spin_lock(lock); 882 - } 883 - 884 - spin_unlock(lock); 885 - return err; 886 - } 887 721 888 722 /* 889 723 * Invalidate any and all dirty buffers on a given inode. We are