History

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.

Artem Bityutskiy committed 14 years ago

Commit f0cd2db1 parent d42d1da5 files · +0 −97Browse files

Unified · Split

5 files
  1. fs/super.c +0 −40
  2. include/linux/backing-dev.h +0 −1
  3. include/linux/fs.h +0 −3
  4. mm/backing-dev.c +0 −52
  5. mm/page-writeback.c +0 −1
fs/super.c+0−40
@@ -536,46 +536,6 @@ void drop_super(struct super_block *sb) · 535 unmodified lines
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+0−1
@@ -124,7 +124,6 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, · 123 unmodified lines
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+0−3
@@ -1491,7 +1491,6 @@ struct sb_writers { · 1490 unmodified lines
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 { · 363 unmodified lines
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, · 529 unmodified lines
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+0−52
@@ -39,12 +39,6 @@ DEFINE_SPINLOCK(bdi_lock); · 38 unmodified lines
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) · 199 unmodified lines
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) · 8 unmodified lines
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+0−1
@@ -1532,7 +1532,6 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write, · 1531 unmodified lines
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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t