Skip to content

Commit f0cd2db

Browse files
dedekindAl Viro
authored and
Al Viro
committed
vfs: kill write_super and sync_supers
Finally we can kill the 'sync_supers' kernel thread along with the '->write_super()' superblock operation because all the users are gone. Now every file-system is supposed to self-manage own superblock and its dirty state. The nice thing about killing this thread is that it improves power management. Indeed, 'sync_supers' is a source of monotonic system wake-ups - it woke up every 5 seconds no matter what - even if there were no dirty superblocks and even if there were no file-systems using this service (e.g., btrfs and journalled ext4 do not need it). So it was wasting power most of the time. And because the thread was in the core of the kernel, all systems had to have it. So I am quite happy to make it go away. Interestingly, this thread is a left-over from the pdflush kernel thread which was a self-forking kernel thread responsible for all the write-back in old Linux kernels. It was turned into per-block device BDI threads, and 'sync_supers' was a left-over. Thus, R.I.P, pdflush as well. Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent d42d1da commit f0cd2db

File tree

5 files changed

+0
-97
lines changed

5 files changed

+0
-97
lines changed

fs/super.c

-40
Original file line numberDiff line numberDiff line change
@@ -536,46 +536,6 @@ void drop_super(struct super_block *sb)
536536

537537
EXPORT_SYMBOL(drop_super);
538538

539-
/**
540-
* sync_supers - helper for periodic superblock writeback
541-
*
542-
* Call the write_super method if present on all dirty superblocks in
543-
* the system. This is for the periodic writeback used by most older
544-
* filesystems. For data integrity superblock writeback use
545-
* sync_filesystems() instead.
546-
*
547-
* Note: check the dirty flag before waiting, so we don't
548-
* hold up the sync while mounting a device. (The newly
549-
* mounted device won't need syncing.)
550-
*/
551-
void sync_supers(void)
552-
{
553-
struct super_block *sb, *p = NULL;
554-
555-
spin_lock(&sb_lock);
556-
list_for_each_entry(sb, &super_blocks, s_list) {
557-
if (hlist_unhashed(&sb->s_instances))
558-
continue;
559-
if (sb->s_op->write_super && sb->s_dirt) {
560-
sb->s_count++;
561-
spin_unlock(&sb_lock);
562-
563-
down_read(&sb->s_umount);
564-
if (sb->s_root && sb->s_dirt && (sb->s_flags & MS_BORN))
565-
sb->s_op->write_super(sb);
566-
up_read(&sb->s_umount);
567-
568-
spin_lock(&sb_lock);
569-
if (p)
570-
__put_super(p);
571-
p = sb;
572-
}
573-
}
574-
if (p)
575-
__put_super(p);
576-
spin_unlock(&sb_lock);
577-
}
578-
579539
/**
580540
* iterate_supers - call function for all active superblocks
581541
* @f: function to call

include/linux/backing-dev.h

-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
124124
void bdi_start_background_writeback(struct backing_dev_info *bdi);
125125
int bdi_writeback_thread(void *data);
126126
int bdi_has_dirty_io(struct backing_dev_info *bdi);
127-
void bdi_arm_supers_timer(void);
128127
void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi);
129128
void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2);
130129

include/linux/fs.h

-3
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,6 @@ struct sb_writers {
14911491
struct super_block {
14921492
struct list_head s_list; /* Keep this first */
14931493
dev_t s_dev; /* search index; _not_ kdev_t */
1494-
unsigned char s_dirt;
14951494
unsigned char s_blocksize_bits;
14961495
unsigned long s_blocksize;
14971496
loff_t s_maxbytes; /* Max file size */
@@ -1861,7 +1860,6 @@ struct super_operations {
18611860
int (*drop_inode) (struct inode *);
18621861
void (*evict_inode) (struct inode *);
18631862
void (*put_super) (struct super_block *);
1864-
void (*write_super) (struct super_block *);
18651863
int (*sync_fs)(struct super_block *sb, int wait);
18661864
int (*freeze_fs) (struct super_block *);
18671865
int (*unfreeze_fs) (struct super_block *);
@@ -2397,7 +2395,6 @@ extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
23972395
int datasync);
23982396
extern int vfs_fsync(struct file *file, int datasync);
23992397
extern int generic_write_sync(struct file *file, loff_t pos, loff_t count);
2400-
extern void sync_supers(void);
24012398
extern void emergency_sync(void);
24022399
extern void emergency_remount(void);
24032400
#ifdef CONFIG_BLOCK

mm/backing-dev.c

-52
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ DEFINE_SPINLOCK(bdi_lock);
3939
LIST_HEAD(bdi_list);
4040
LIST_HEAD(bdi_pending_list);
4141

42-
static struct task_struct *sync_supers_tsk;
43-
static struct timer_list sync_supers_timer;
44-
45-
static int bdi_sync_supers(void *);
46-
static void sync_supers_timer_fn(unsigned long);
47-
4842
void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2)
4943
{
5044
if (wb1 < wb2) {
@@ -250,12 +244,6 @@ static int __init default_bdi_init(void)
250244
{
251245
int err;
252246

253-
sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
254-
BUG_ON(IS_ERR(sync_supers_tsk));
255-
256-
setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
257-
bdi_arm_supers_timer();
258-
259247
err = bdi_init(&default_backing_dev_info);
260248
if (!err)
261249
bdi_register(&default_backing_dev_info, NULL, "default");
@@ -270,46 +258,6 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi)
270258
return wb_has_dirty_io(&bdi->wb);
271259
}
272260

273-
/*
274-
* kupdated() used to do this. We cannot do it from the bdi_forker_thread()
275-
* or we risk deadlocking on ->s_umount. The longer term solution would be
276-
* to implement sync_supers_bdi() or similar and simply do it from the
277-
* bdi writeback thread individually.
278-
*/
279-
static int bdi_sync_supers(void *unused)
280-
{
281-
set_user_nice(current, 0);
282-
283-
while (!kthread_should_stop()) {
284-
set_current_state(TASK_INTERRUPTIBLE);
285-
schedule();
286-
287-
/*
288-
* Do this periodically, like kupdated() did before.
289-
*/
290-
sync_supers();
291-
}
292-
293-
return 0;
294-
}
295-
296-
void bdi_arm_supers_timer(void)
297-
{
298-
unsigned long next;
299-
300-
if (!dirty_writeback_interval)
301-
return;
302-
303-
next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
304-
mod_timer(&sync_supers_timer, round_jiffies_up(next));
305-
}
306-
307-
static void sync_supers_timer_fn(unsigned long unused)
308-
{
309-
wake_up_process(sync_supers_tsk);
310-
bdi_arm_supers_timer();
311-
}
312-
313261
static void wakeup_timer_fn(unsigned long data)
314262
{
315263
struct backing_dev_info *bdi = (struct backing_dev_info *)data;

mm/page-writeback.c

-1
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,6 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write,
15321532
void __user *buffer, size_t *length, loff_t *ppos)
15331533
{
15341534
proc_dointvec(table, write, buffer, length, ppos);
1535-
bdi_arm_supers_timer();
15361535
return 0;
15371536
}
15381537

0 commit comments

Comments
 (0)