Commit f0cd2dbb6cf387c11f87265462e370bb5469299e

Authored by Artem Bityutskiy
Committed by Al Viro
1 parent d42d1dabf3

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>

Showing 5 changed files with 0 additions and 97 deletions Side-by-side Diff

... ... @@ -537,46 +537,6 @@
537 537 EXPORT_SYMBOL(drop_super);
538 538  
539 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   -
579   -/**
580 540 * iterate_supers - call function for all active superblocks
581 541 * @f: function to call
582 542 * @arg: argument to pass to it
include/linux/backing-dev.h
... ... @@ -124,7 +124,6 @@
124 124 void bdi_start_background_writeback(struct backing_dev_info *bdi);
125 125 int bdi_writeback_thread(void *data);
126 126 int bdi_has_dirty_io(struct backing_dev_info *bdi);
127   -void bdi_arm_supers_timer(void);
128 127 void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi);
129 128 void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2);
130 129  
... ... @@ -1491,7 +1491,6 @@
1491 1491 struct super_block {
1492 1492 struct list_head s_list; /* Keep this first */
1493 1493 dev_t s_dev; /* search index; _not_ kdev_t */
1494   - unsigned char s_dirt;
1495 1494 unsigned char s_blocksize_bits;
1496 1495 unsigned long s_blocksize;
1497 1496 loff_t s_maxbytes; /* Max file size */
... ... @@ -1861,7 +1860,6 @@
1861 1860 int (*drop_inode) (struct inode *);
1862 1861 void (*evict_inode) (struct inode *);
1863 1862 void (*put_super) (struct super_block *);
1864   - void (*write_super) (struct super_block *);
1865 1863 int (*sync_fs)(struct super_block *sb, int wait);
1866 1864 int (*freeze_fs) (struct super_block *);
1867 1865 int (*unfreeze_fs) (struct super_block *);
... ... @@ -2397,7 +2395,6 @@
2397 2395 int datasync);
2398 2396 extern int vfs_fsync(struct file *file, int datasync);
2399 2397 extern int generic_write_sync(struct file *file, loff_t pos, loff_t count);
2400   -extern void sync_supers(void);
2401 2398 extern void emergency_sync(void);
2402 2399 extern void emergency_remount(void);
2403 2400 #ifdef CONFIG_BLOCK
... ... @@ -39,12 +39,6 @@
39 39 LIST_HEAD(bdi_list);
40 40 LIST_HEAD(bdi_pending_list);
41 41  
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   -
48 42 void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2)
49 43 {
50 44 if (wb1 < wb2) {
... ... @@ -250,12 +244,6 @@
250 244 {
251 245 int err;
252 246  
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   -
259 247 err = bdi_init(&default_backing_dev_info);
260 248 if (!err)
261 249 bdi_register(&default_backing_dev_info, NULL, "default");
... ... @@ -268,46 +256,6 @@
268 256 int bdi_has_dirty_io(struct backing_dev_info *bdi)
269 257 {
270 258 return wb_has_dirty_io(&bdi->wb);
271   -}
272   -
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 259 }
312 260  
313 261 static void wakeup_timer_fn(unsigned long data)
... ... @@ -1532,7 +1532,6 @@
1532 1532 void __user *buffer, size_t *length, loff_t *ppos)
1533 1533 {
1534 1534 proc_dointvec(table, write, buffer, length, ppos);
1535   - bdi_arm_supers_timer();
1536 1535 return 0;
1537 1536 }
1538 1537