Re: [PATCH 16/32] fs: Fold fsync_buffers_list() into sync_mapping_buffers()
Christian Brauner <[email protected]> Wed, 4 Mar 2026 14:38:47 +0100
| Newsgroups | gmane.linux.kernel.aio.general,gmane.linux.file-systems,gmane.comp.file-systems.ext4,gmane.linux.kernel.mm |
|---|---|
| Message-ID | <20260304-bildmaterial-deckname-1995a115de52@brauner> |
On Tue, Mar 03, 2026 at 11:34:05AM +0100, Jan Kara wrote: > 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. > > Signed-off-by: Jan Kara <[email protected]> > --- > fs/buffer.c | 180 +++++++++++++++++++++++----------------------------- > 1 file changed, 80 insertions(+), 100 deletions(-) > > diff --git a/fs/buffer.c b/fs/buffer.c > index 1c0e7c81a38b..18012afb8289 100644 > --- a/fs/buffer.c > +++ b/fs/buffer.c > @@ -54,7 +54,6 @@ > > #include "internal.h" > > -static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); > static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh, > enum rw_hint hint, struct writeback_control *wbc); > > @@ -531,22 +530,96 @@ EXPORT_SYMBOL_GPL(inode_has_buffers); > * @mapping: the mapping which wants those buffers written > * > * Starts I/O against the buffers at mapping->i_private_list, and waits upon > - * that I/O. > + * that I/O. Basically, this is a convenience function for fsync(). @mapping > + * is a file or directory which needs those buffers to be written for a > + * successful fsync(). > * > - * Basically, this is a convenience function for fsync(). > - * @mapping is a file or directory which needs those buffers to be written for > - * a successful fsync(). > + * We have conflicting pressures: we want to make sure that all > + * initially dirty buffers get waited on, but that any subsequently > + * dirtied buffers don't. After all, we don't want fsync to last > + * forever if somebody is actively writing to the file. > + * > + * Do this in two main stages: first we copy dirty buffers to a > + * temporary inode list, queueing the writes as we go. Then we clean > + * up, waiting for those writes to complete. mark_buffer_dirty_inode() > + * doesn't touch b_assoc_buffers list if b_assoc_map is not NULL so we > + * are sure the buffer stays on our list until IO completes (at which point > + * it can be reaped). > */ > int sync_mapping_buffers(struct address_space *mapping) > { > struct address_space *buffer_mapping = > mapping->host->i_sb->s_bdev->bd_mapping; > + struct buffer_head *bh; > + int err = 0; > + struct blk_plug plug; > + LIST_HEAD(tmp); > > if (list_empty(&mapping->i_private_list)) > return 0; > > - return fsync_buffers_list(&buffer_mapping->i_private_lock, > - &mapping->i_private_list); > + blk_start_plug(&plug); > + > + spin_lock(&buffer_mapping->i_private_lock); > + while (!list_empty(&mapping->i_private_list)) { > + bh = BH_ENTRY(list->next); Stray "list" reference? Shouldn't this be BH_ENTRY(mapping->i_private_list.next)? -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>