Skip to content

Commit 90db4d4

Browse files
Christoph Hellwigbrauner
authored andcommitted
writeback: allow the file system to override MIN_WRITEBACK_PAGES
The relatively low minimal writeback size of 4MiB means that written back inodes on rotational media are switched a lot. Besides introducing additional seeks, this also can lead to extreme file fragmentation on zoned devices when a lot of files are cached relative to the available writeback bandwidth. Add a superblock field that allows the file system to override the default size. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20251017034611.651385-3-hch@lst.de Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 151d092 commit 90db4d4

4 files changed

Lines changed: 12 additions & 9 deletions

File tree

fs/fs-writeback.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@
3232
#include <linux/memcontrol.h>
3333
#include "internal.h"
3434

35-
/*
36-
* 4MB minimal write chunk size
37-
*/
38-
#define MIN_WRITEBACK_PAGES (4096UL >> (PAGE_SHIFT - 10))
39-
4035
/*
4136
* Passed into wb_writeback(), essentially a subset of writeback_control
4237
*/
@@ -1889,8 +1884,8 @@ static int writeback_single_inode(struct inode *inode,
18891884
return ret;
18901885
}
18911886

1892-
static long writeback_chunk_size(struct bdi_writeback *wb,
1893-
struct wb_writeback_work *work)
1887+
static long writeback_chunk_size(struct super_block *sb,
1888+
struct bdi_writeback *wb, struct wb_writeback_work *work)
18941889
{
18951890
long pages;
18961891

@@ -1913,7 +1908,8 @@ static long writeback_chunk_size(struct bdi_writeback *wb,
19131908
pages = min(wb->avg_write_bandwidth / 2,
19141909
global_wb_domain.dirty_limit / DIRTY_SCOPE);
19151910
pages = min(pages, work->nr_pages);
1916-
return round_down(pages + MIN_WRITEBACK_PAGES, MIN_WRITEBACK_PAGES);
1911+
return round_down(pages + sb->s_min_writeback_pages,
1912+
sb->s_min_writeback_pages);
19171913
}
19181914

19191915
/*
@@ -2015,7 +2011,7 @@ static long writeback_sb_inodes(struct super_block *sb,
20152011
inode->i_state |= I_SYNC;
20162012
wbc_attach_and_unlock_inode(&wbc, inode);
20172013

2018-
write_chunk = writeback_chunk_size(wb, work);
2014+
write_chunk = writeback_chunk_size(inode->i_sb, wb, work);
20192015
wbc.nr_to_write = write_chunk;
20202016
wbc.pages_skipped = 0;
20212017

fs/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
389389
goto fail;
390390
if (list_lru_init_memcg(&s->s_inode_lru, s->s_shrink))
391391
goto fail;
392+
s->s_min_writeback_pages = MIN_WRITEBACK_PAGES;
392393
return s;
393394

394395
fail:

include/linux/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,7 @@ struct super_block {
15831583

15841584
spinlock_t s_inode_wblist_lock;
15851585
struct list_head s_inodes_wb; /* writeback inodes */
1586+
long s_min_writeback_pages;
15861587
} __randomize_layout;
15871588

15881589
static inline struct user_namespace *i_user_ns(const struct inode *inode)

include/linux/writeback.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,4 +374,9 @@ bool redirty_page_for_writepage(struct writeback_control *, struct page *);
374374
void sb_mark_inode_writeback(struct inode *inode);
375375
void sb_clear_inode_writeback(struct inode *inode);
376376

377+
/*
378+
* 4MB minimal write chunk size
379+
*/
380+
#define MIN_WRITEBACK_PAGES (4096UL >> (PAGE_SHIFT - 10))
381+
377382
#endif /* WRITEBACK_H */

0 commit comments

Comments
 (0)