Update bcachefs sources to 512f2a45a090 bcachefs: opts.writeback_timeout

This commit is contained in:
Kent Overstreet 2025-11-21 00:26:31 -05:00
parent 98a1d8d560
commit 8010df5f2f
9 changed files with 58 additions and 8 deletions

View File

@ -1 +1 @@
0eb07772a42c4617bb788f9fccade67a69c3da81
512f2a45a090f75801b5c9b26fe44e4337282b47

View File

@ -1105,6 +1105,7 @@ struct bch_fs {
struct mutex vfs_inodes_lock;
struct rhashtable vfs_inodes_table;
struct rhltable vfs_inodes_by_inum_table;
struct workqueue_struct *vfs_writeback_wq;
/* VFS IO PATH - fs-io.c */
struct bio_set writepage_bioset;

View File

@ -887,6 +887,7 @@ LE64_BITMASK(BCH_SB_CSUM_ERR_RETRY_NR, struct bch_sb, flags[6], 14, 20);
LE64_BITMASK(BCH_SB_DEGRADED_ACTION, struct bch_sb, flags[6], 20, 22);
LE64_BITMASK(BCH_SB_CASEFOLD, struct bch_sb, flags[6], 22, 23);
LE64_BITMASK(BCH_SB_REBALANCE_AC_ONLY, struct bch_sb, flags[6], 23, 24);
LE64_BITMASK(BCH_SB_WRITEBACK_TIMEOUT, struct bch_sb, flags[6], 24, 40);
static inline __u64 BCH_SB_COMPRESSION_TYPE(const struct bch_sb *sb)
{

View File

@ -163,6 +163,7 @@ write_attribute(trigger_btree_write_buffer_flush);
write_attribute(trigger_btree_updates);
write_attribute(trigger_freelist_wakeup);
write_attribute(trigger_recalc_capacity);
write_attribute(trigger_reconcile_wakeup);
write_attribute(trigger_delete_dead_snapshots);
write_attribute(trigger_emergency_read_only);
read_attribute(gc_gens_pos);
@ -473,6 +474,9 @@ STORE(bch2_fs)
bch2_recalc_capacity(c);
}
if (attr == &sysfs_trigger_reconcile_wakeup)
bch2_reconcile_wakeup(c);
if (attr == &sysfs_trigger_delete_dead_snapshots)
__bch2_delete_dead_snapshots(c);
@ -620,6 +624,7 @@ struct attribute *bch2_fs_internal_files[] = {
&sysfs_trigger_btree_updates,
&sysfs_trigger_freelist_wakeup,
&sysfs_trigger_recalc_capacity,
&sysfs_trigger_reconcile_wakeup,
&sysfs_trigger_delete_dead_snapshots,
&sysfs_trigger_emergency_read_only,

View File

@ -351,6 +351,11 @@ enum fsck_err_opts {
OPT_UINT(0, U32_MAX), \
BCH_SB_JOURNAL_RECLAIM_DELAY, 100, \
NULL, "Delay in milliseconds before automatic journal reclaim")\
x(writeback_timeout, u16, \
OPT_FS|OPT_MOUNT|OPT_RUNTIME, \
OPT_UINT(0, U16_MAX), \
BCH_SB_WRITEBACK_TIMEOUT, 0, \
NULL, "Delay seconds before writing back dirty data, overriding vm sysctls")\
x(move_bytes_in_flight, u32, \
OPT_HUMAN_READABLE|OPT_FS|OPT_MOUNT|OPT_RUNTIME, \
OPT_UINT(1024, U32_MAX), \

View File

@ -883,12 +883,12 @@ static noinline void folios_trunc(folios *fs, struct folio **fi)
}
}
static int __bch2_buffered_write(struct bch_inode_info *inode,
static int __bch2_buffered_write(struct bch_fs *c,
struct bch_inode_info *inode,
struct address_space *mapping,
struct iov_iter *iter,
loff_t pos, unsigned len)
{
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch2_folio_reservation res;
folios fs;
struct folio *f;
@ -1056,6 +1056,7 @@ static ssize_t bch2_buffered_write(struct kiocb *iocb, struct iov_iter *iter)
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct bch_inode_info *inode = file_bch_inode(file);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
loff_t pos = iocb->ki_pos;
ssize_t written = 0;
int ret = 0;
@ -1094,7 +1095,7 @@ again:
break;
}
ret = __bch2_buffered_write(inode, mapping, iter, pos, bytes);
ret = __bch2_buffered_write(c, inode, mapping, iter, pos, bytes);
if (unlikely(ret < 0))
break;
@ -1120,6 +1121,9 @@ again:
balance_dirty_pages_ratelimited(mapping);
} while (iov_iter_count(iter));
if (written)
bch2_dirty_inode(c, inode);
return written ? written : ret;
}

View File

@ -427,10 +427,20 @@ static struct inode *bch2_alloc_inode(struct super_block *sb)
BUG();
}
static void bch2_vfs_writeback_fn(struct work_struct *work)
{
struct bch_inode_info *inode = container_of(work, struct bch_inode_info, ei_writeback_timer.work);
if (!igrab(&inode->v))
return;
write_inode_now(&inode->v, false);
iput(&inode->v);
}
static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c, gfp_t gfp)
{
struct bch_inode_info *inode = alloc_inode_sb(c->vfs_sb,
bch2_inode_cache, gfp);
struct bch_inode_info *inode = alloc_inode_sb(c->vfs_sb, bch2_inode_cache, gfp);
if (!inode)
return NULL;
@ -441,6 +451,7 @@ static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c, gfp_t gfp)
inode->ei_flags = 0;
mutex_init(&inode->ei_quota_lock);
memset(&inode->ei_devs_need_flush, 0, sizeof(inode->ei_devs_need_flush));
INIT_DELAYED_WORK(&inode->ei_writeback_timer, bch2_vfs_writeback_fn);
if (unlikely(inode_init_always_gfp(c->vfs_sb, &inode->v, gfp))) {
kmem_cache_free(bch2_inode_cache, inode);
@ -1820,6 +1831,8 @@ static void bch2_evict_inode(struct inode *vinode)
truncate_inode_pages_final(&inode->v.i_data);
cancel_delayed_work_sync(&inode->ei_writeback_timer);
clear_inode(&inode->v);
BUG_ON(!is_bad_inode(&inode->v) && inode->ei_quota_reserved);
@ -2367,6 +2380,8 @@ static int bch2_init_fs_context(struct fs_context *fc)
void bch2_fs_vfs_exit(struct bch_fs *c)
{
if (c->vfs_writeback_wq)
destroy_workqueue(c->vfs_writeback_wq);
if (c->vfs_inodes_by_inum_table.ht.tbl)
rhltable_destroy(&c->vfs_inodes_by_inum_table);
if (c->vfs_inodes_table.tbl)
@ -2375,8 +2390,15 @@ void bch2_fs_vfs_exit(struct bch_fs *c)
int bch2_fs_vfs_init(struct bch_fs *c)
{
return rhashtable_init(&c->vfs_inodes_table, &bch2_vfs_inodes_params) ?:
rhltable_init(&c->vfs_inodes_by_inum_table, &bch2_vfs_inodes_by_inum_params);
try(rhashtable_init(&c->vfs_inodes_table, &bch2_vfs_inodes_params));
try(rhltable_init(&c->vfs_inodes_by_inum_table, &bch2_vfs_inodes_by_inum_params));
c->vfs_writeback_wq = alloc_workqueue("bcachefs_vfs_writeback",
WQ_PERCPU|WQ_MEM_RECLAIM|WQ_FREEZABLE, 1);
if (!c->vfs_writeback_wq)
return bch_err_throw(c, ENOMEM_fs_other_alloc);
return 0;
}
static struct file_system_type bcache_fs_type = {

View File

@ -41,6 +41,8 @@ struct bch_inode_info {
/* copy of inode in btree: */
struct bch_inode_unpacked ei_inode;
struct delayed_work ei_writeback_timer;
};
#define bch2_pagecache_add_put(i) bch2_two_state_unlock(&(i)->ei_pagecache_lock, 0)
@ -205,6 +207,13 @@ int bch2_fs_vfs_init(struct bch_fs *);
void bch2_vfs_exit(void);
int bch2_vfs_init(void);
static inline void bch2_dirty_inode(struct bch_fs *c, struct bch_inode_info *inode)
{
if (c->opts.writeback_timeout)
queue_delayed_work(c->vfs_writeback_wq, &inode->ei_writeback_timer,
c->opts.writeback_timeout * HZ);
}
#else
#define bch2_inode_update_after_write(_trans, _inode, _inode_u, _fields) ({ do {} while (0); })

View File

@ -638,6 +638,9 @@ vm_fault_t bch2_page_mkwrite(struct vm_fault *vmf)
bch2_folio_reservation_put(c, inode, &res);
folio_wait_stable(folio);
bch2_dirty_inode(c, inode);
ret = VM_FAULT_LOCKED;
out:
sb_end_pagefault(inode->v.i_sb);