diff options
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r-- | fs/fs-writeback.c | 92 |
1 files changed, 24 insertions, 68 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 91013ff7dd53..40308e98c6a4 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -64,6 +64,28 @@ static void writeback_release(struct backing_dev_info *bdi) | |||
64 | clear_bit(BDI_pdflush, &bdi->state); | 64 | clear_bit(BDI_pdflush, &bdi->state); |
65 | } | 65 | } |
66 | 66 | ||
67 | static noinline void block_dump___mark_inode_dirty(struct inode *inode) | ||
68 | { | ||
69 | if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) { | ||
70 | struct dentry *dentry; | ||
71 | const char *name = "?"; | ||
72 | |||
73 | dentry = d_find_alias(inode); | ||
74 | if (dentry) { | ||
75 | spin_lock(&dentry->d_lock); | ||
76 | name = (const char *) dentry->d_name.name; | ||
77 | } | ||
78 | printk(KERN_DEBUG | ||
79 | "%s(%d): dirtied inode %lu (%s) on %s\n", | ||
80 | current->comm, task_pid_nr(current), inode->i_ino, | ||
81 | name, inode->i_sb->s_id); | ||
82 | if (dentry) { | ||
83 | spin_unlock(&dentry->d_lock); | ||
84 | dput(dentry); | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | |||
67 | /** | 89 | /** |
68 | * __mark_inode_dirty - internal function | 90 | * __mark_inode_dirty - internal function |
69 | * @inode: inode to mark | 91 | * @inode: inode to mark |
@@ -114,23 +136,8 @@ void __mark_inode_dirty(struct inode *inode, int flags) | |||
114 | if ((inode->i_state & flags) == flags) | 136 | if ((inode->i_state & flags) == flags) |
115 | return; | 137 | return; |
116 | 138 | ||
117 | if (unlikely(block_dump)) { | 139 | if (unlikely(block_dump)) |
118 | struct dentry *dentry = NULL; | 140 | block_dump___mark_inode_dirty(inode); |
119 | const char *name = "?"; | ||
120 | |||
121 | if (!list_empty(&inode->i_dentry)) { | ||
122 | dentry = list_entry(inode->i_dentry.next, | ||
123 | struct dentry, d_alias); | ||
124 | if (dentry && dentry->d_name.name) | ||
125 | name = (const char *) dentry->d_name.name; | ||
126 | } | ||
127 | |||
128 | if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) | ||
129 | printk(KERN_DEBUG | ||
130 | "%s(%d): dirtied inode %lu (%s) on %s\n", | ||
131 | current->comm, task_pid_nr(current), inode->i_ino, | ||
132 | name, inode->i_sb->s_id); | ||
133 | } | ||
134 | 141 | ||
135 | spin_lock(&inode_lock); | 142 | spin_lock(&inode_lock); |
136 | if ((inode->i_state & flags) != flags) { | 143 | if ((inode->i_state & flags) != flags) { |
@@ -289,7 +296,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
289 | int ret; | 296 | int ret; |
290 | 297 | ||
291 | BUG_ON(inode->i_state & I_SYNC); | 298 | BUG_ON(inode->i_state & I_SYNC); |
292 | WARN_ON(inode->i_state & I_NEW); | ||
293 | 299 | ||
294 | /* Set I_SYNC, reset I_DIRTY */ | 300 | /* Set I_SYNC, reset I_DIRTY */ |
295 | dirty = inode->i_state & I_DIRTY; | 301 | dirty = inode->i_state & I_DIRTY; |
@@ -314,7 +320,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
314 | } | 320 | } |
315 | 321 | ||
316 | spin_lock(&inode_lock); | 322 | spin_lock(&inode_lock); |
317 | WARN_ON(inode->i_state & I_NEW); | ||
318 | inode->i_state &= ~I_SYNC; | 323 | inode->i_state &= ~I_SYNC; |
319 | if (!(inode->i_state & I_FREEING)) { | 324 | if (!(inode->i_state & I_FREEING)) { |
320 | if (!(inode->i_state & I_DIRTY) && | 325 | if (!(inode->i_state & I_DIRTY) && |
@@ -679,55 +684,6 @@ void sync_inodes_sb(struct super_block *sb, int wait) | |||
679 | } | 684 | } |
680 | 685 | ||
681 | /** | 686 | /** |
682 | * sync_inodes - writes all inodes to disk | ||
683 | * @wait: wait for completion | ||
684 | * | ||
685 | * sync_inodes() goes through each super block's dirty inode list, writes the | ||
686 | * inodes out, waits on the writeout and puts the inodes back on the normal | ||
687 | * list. | ||
688 | * | ||
689 | * This is for sys_sync(). fsync_dev() uses the same algorithm. The subtle | ||
690 | * part of the sync functions is that the blockdev "superblock" is processed | ||
691 | * last. This is because the write_inode() function of a typical fs will | ||
692 | * perform no I/O, but will mark buffers in the blockdev mapping as dirty. | ||
693 | * What we want to do is to perform all that dirtying first, and then write | ||
694 | * back all those inode blocks via the blockdev mapping in one sweep. So the | ||
695 | * additional (somewhat redundant) sync_blockdev() calls here are to make | ||
696 | * sure that really happens. Because if we call sync_inodes_sb(wait=1) with | ||
697 | * outstanding dirty inodes, the writeback goes block-at-a-time within the | ||
698 | * filesystem's write_inode(). This is extremely slow. | ||
699 | */ | ||
700 | static void __sync_inodes(int wait) | ||
701 | { | ||
702 | struct super_block *sb; | ||
703 | |||
704 | spin_lock(&sb_lock); | ||
705 | restart: | ||
706 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
707 | sb->s_count++; | ||
708 | spin_unlock(&sb_lock); | ||
709 | down_read(&sb->s_umount); | ||
710 | if (sb->s_root) { | ||
711 | sync_inodes_sb(sb, wait); | ||
712 | sync_blockdev(sb->s_bdev); | ||
713 | } | ||
714 | up_read(&sb->s_umount); | ||
715 | spin_lock(&sb_lock); | ||
716 | if (__put_super_and_need_restart(sb)) | ||
717 | goto restart; | ||
718 | } | ||
719 | spin_unlock(&sb_lock); | ||
720 | } | ||
721 | |||
722 | void sync_inodes(int wait) | ||
723 | { | ||
724 | __sync_inodes(0); | ||
725 | |||
726 | if (wait) | ||
727 | __sync_inodes(1); | ||
728 | } | ||
729 | |||
730 | /** | ||
731 | * write_inode_now - write an inode to disk | 687 | * write_inode_now - write an inode to disk |
732 | * @inode: inode to write to disk | 688 | * @inode: inode to write to disk |
733 | * @sync: whether the write should be synchronous or not | 689 | * @sync: whether the write should be synchronous or not |