|
@@ -424,8 +424,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
|
|
|
* WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so
|
|
|
* that it can be located for waiting on in __writeback_single_inode().
|
|
|
*
|
|
|
- * Called under inode_lock.
|
|
|
- *
|
|
|
* If `bdi' is non-zero then we're being asked to writeback a specific queue.
|
|
|
* This function assumes that the blockdev superblock's inodes are backed by
|
|
|
* a variety of queues, so all inodes are searched. For other superblocks,
|
|
@@ -446,6 +444,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
|
|
|
{
|
|
|
const unsigned long start = jiffies; /* livelock avoidance */
|
|
|
|
|
|
+ spin_lock(&inode_lock);
|
|
|
if (!wbc->for_kupdate || list_empty(&sb->s_io))
|
|
|
queue_io(sb, wbc->older_than_this);
|
|
|
|
|
@@ -524,6 +523,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
|
|
|
if (!list_empty(&sb->s_more_io))
|
|
|
wbc->more_io = 1;
|
|
|
}
|
|
|
+ spin_unlock(&inode_lock);
|
|
|
return; /* Leave any unwritten inodes on s_io */
|
|
|
}
|
|
|
|
|
@@ -565,11 +565,8 @@ restart:
|
|
|
* be unmounted by the time it is released.
|
|
|
*/
|
|
|
if (down_read_trylock(&sb->s_umount)) {
|
|
|
- if (sb->s_root) {
|
|
|
- spin_lock(&inode_lock);
|
|
|
+ if (sb->s_root)
|
|
|
sync_sb_inodes(sb, wbc);
|
|
|
- spin_unlock(&inode_lock);
|
|
|
- }
|
|
|
up_read(&sb->s_umount);
|
|
|
}
|
|
|
spin_lock(&sb_lock);
|
|
@@ -607,9 +604,7 @@ void sync_inodes_sb(struct super_block *sb, int wait)
|
|
|
(inodes_stat.nr_inodes - inodes_stat.nr_unused) +
|
|
|
nr_dirty + nr_unstable;
|
|
|
wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */
|
|
|
- spin_lock(&inode_lock);
|
|
|
sync_sb_inodes(sb, &wbc);
|
|
|
- spin_unlock(&inode_lock);
|
|
|
}
|
|
|
|
|
|
/*
|