|
@@ -100,11 +100,11 @@ void __mark_inode_dirty(struct inode *inode, int flags)
|
|
inode->i_state |= flags;
|
|
inode->i_state |= flags;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * If the inode is locked, just update its dirty state.
|
|
|
|
|
|
+ * If the inode is being synced, just update its dirty state.
|
|
* The unlocker will place the inode on the appropriate
|
|
* The unlocker will place the inode on the appropriate
|
|
* superblock list, based upon its state.
|
|
* superblock list, based upon its state.
|
|
*/
|
|
*/
|
|
- if (inode->i_state & I_LOCK)
|
|
|
|
|
|
+ if (inode->i_state & I_SYNC)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -172,6 +172,15 @@ static void requeue_io(struct inode *inode)
|
|
list_move(&inode->i_list, &inode->i_sb->s_more_io);
|
|
list_move(&inode->i_list, &inode->i_sb->s_more_io);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void inode_sync_complete(struct inode *inode)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * Prevent speculative execution through spin_unlock(&inode_lock);
|
|
|
|
+ */
|
|
|
|
+ smp_mb();
|
|
|
|
+ wake_up_bit(&inode->i_state, __I_SYNC);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Move expired dirty inodes from @delaying_queue to @dispatch_queue.
|
|
* Move expired dirty inodes from @delaying_queue to @dispatch_queue.
|
|
*/
|
|
*/
|
|
@@ -225,11 +234,11 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
|
|
int wait = wbc->sync_mode == WB_SYNC_ALL;
|
|
int wait = wbc->sync_mode == WB_SYNC_ALL;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- BUG_ON(inode->i_state & I_LOCK);
|
|
|
|
|
|
+ BUG_ON(inode->i_state & I_SYNC);
|
|
|
|
|
|
- /* Set I_LOCK, reset I_DIRTY */
|
|
|
|
|
|
+ /* Set I_SYNC, reset I_DIRTY */
|
|
dirty = inode->i_state & I_DIRTY;
|
|
dirty = inode->i_state & I_DIRTY;
|
|
- inode->i_state |= I_LOCK;
|
|
|
|
|
|
+ inode->i_state |= I_SYNC;
|
|
inode->i_state &= ~I_DIRTY;
|
|
inode->i_state &= ~I_DIRTY;
|
|
|
|
|
|
spin_unlock(&inode_lock);
|
|
spin_unlock(&inode_lock);
|
|
@@ -250,7 +259,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
|
|
}
|
|
}
|
|
|
|
|
|
spin_lock(&inode_lock);
|
|
spin_lock(&inode_lock);
|
|
- inode->i_state &= ~I_LOCK;
|
|
|
|
|
|
+ inode->i_state &= ~I_SYNC;
|
|
if (!(inode->i_state & I_FREEING)) {
|
|
if (!(inode->i_state & I_FREEING)) {
|
|
if (!(inode->i_state & I_DIRTY) &&
|
|
if (!(inode->i_state & I_DIRTY) &&
|
|
mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
|
|
mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
|
|
@@ -305,7 +314,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
|
|
list_move(&inode->i_list, &inode_unused);
|
|
list_move(&inode->i_list, &inode_unused);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- wake_up_inode(inode);
|
|
|
|
|
|
+ inode_sync_complete(inode);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -324,7 +333,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
|
|
else
|
|
else
|
|
WARN_ON(inode->i_state & I_WILL_FREE);
|
|
WARN_ON(inode->i_state & I_WILL_FREE);
|
|
|
|
|
|
- if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
|
|
|
|
|
|
+ if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_SYNC)) {
|
|
struct address_space *mapping = inode->i_mapping;
|
|
struct address_space *mapping = inode->i_mapping;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
@@ -350,16 +359,16 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
|
|
/*
|
|
/*
|
|
* It's a data-integrity sync. We must wait.
|
|
* It's a data-integrity sync. We must wait.
|
|
*/
|
|
*/
|
|
- if (inode->i_state & I_LOCK) {
|
|
|
|
- DEFINE_WAIT_BIT(wq, &inode->i_state, __I_LOCK);
|
|
|
|
|
|
+ if (inode->i_state & I_SYNC) {
|
|
|
|
+ DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
|
|
|
|
|
|
- wqh = bit_waitqueue(&inode->i_state, __I_LOCK);
|
|
|
|
|
|
+ wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
|
|
do {
|
|
do {
|
|
spin_unlock(&inode_lock);
|
|
spin_unlock(&inode_lock);
|
|
__wait_on_bit(wqh, &wq, inode_wait,
|
|
__wait_on_bit(wqh, &wq, inode_wait,
|
|
TASK_UNINTERRUPTIBLE);
|
|
TASK_UNINTERRUPTIBLE);
|
|
spin_lock(&inode_lock);
|
|
spin_lock(&inode_lock);
|
|
- } while (inode->i_state & I_LOCK);
|
|
|
|
|
|
+ } while (inode->i_state & I_SYNC);
|
|
}
|
|
}
|
|
return __sync_single_inode(inode, wbc);
|
|
return __sync_single_inode(inode, wbc);
|
|
}
|
|
}
|
|
@@ -392,7 +401,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
|
|
* The inodes to be written are parked on sb->s_io. They are moved back onto
|
|
* The inodes to be written are parked on sb->s_io. They are moved back onto
|
|
* sb->s_dirty as they are selected for writing. This way, none can be missed
|
|
* sb->s_dirty as they are selected for writing. This way, none can be missed
|
|
* on the writer throttling path, and we get decent balancing between many
|
|
* on the writer throttling path, and we get decent balancing between many
|
|
- * throttled threads: we don't want them all piling up on __wait_on_inode.
|
|
|
|
|
|
+ * throttled threads: we don't want them all piling up on inode_sync_wait.
|
|
*/
|
|
*/
|
|
static void
|
|
static void
|
|
sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
|
|
sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
|
|
@@ -661,7 +670,7 @@ int write_inode_now(struct inode *inode, int sync)
|
|
ret = __writeback_single_inode(inode, &wbc);
|
|
ret = __writeback_single_inode(inode, &wbc);
|
|
spin_unlock(&inode_lock);
|
|
spin_unlock(&inode_lock);
|
|
if (sync)
|
|
if (sync)
|
|
- wait_on_inode(inode);
|
|
|
|
|
|
+ inode_sync_wait(inode);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(write_inode_now);
|
|
EXPORT_SYMBOL(write_inode_now);
|
|
@@ -736,7 +745,7 @@ int generic_osync_inode(struct inode *inode, struct address_space *mapping, int
|
|
err = err2;
|
|
err = err2;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
- wait_on_inode(inode);
|
|
|
|
|
|
+ inode_sync_wait(inode);
|
|
|
|
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|