summaryrefslogtreecommitdiff
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 7c75ed7e8979..3c75ee025bda 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1711,6 +1711,19 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
}
}
+static bool __sync_lazytime(struct inode *inode)
+{
+ spin_lock(&inode->i_lock);
+ if (!(inode_state_read(inode) & I_DIRTY_TIME)) {
+ spin_unlock(&inode->i_lock);
+ return false;
+ }
+ inode_state_clear(inode, I_DIRTY_TIME);
+ spin_unlock(&inode->i_lock);
+ inode->i_op->sync_lazytime(inode);
+ return true;
+}
+
bool sync_lazytime(struct inode *inode)
{
if (!(inode_state_read_once(inode) & I_DIRTY_TIME))
@@ -1718,9 +1731,8 @@ bool sync_lazytime(struct inode *inode)
trace_writeback_lazytime(inode);
if (inode->i_op->sync_lazytime)
- inode->i_op->sync_lazytime(inode);
- else
- mark_inode_dirty_sync(inode);
+ return __sync_lazytime(inode);
+ mark_inode_dirty_sync(inode);
return true;
}
@@ -2775,13 +2787,8 @@ static void wait_sb_inodes(struct super_block *sb)
* The mapping can appear untagged while still on-list since we
* do not have the mapping lock. Skip it here, wb completion
* will remove it.
- *
- * If the mapping does not have data integrity semantics,
- * there's no need to wait for the writeout to complete, as the
- * mapping cannot guarantee that data is persistently stored.
*/
- if (!mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK) ||
- mapping_no_data_integrity(mapping))
+ if (!mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK))
continue;
spin_unlock_irq(&sb->s_inode_wblist_lock);
@@ -2916,6 +2923,17 @@ void sync_inodes_sb(struct super_block *sb)
*/
if (bdi == &noop_backing_dev_info)
return;
+
+ /*
+ * If the superblock has SB_I_NO_DATA_INTEGRITY set, there's no need to
+ * wait for the writeout to complete, as the filesystem cannot guarantee
+ * data persistence on sync. Just kick off writeback and return.
+ */
+ if (sb->s_iflags & SB_I_NO_DATA_INTEGRITY) {
+ wakeup_flusher_threads_bdi(bdi, WB_REASON_SYNC);
+ return;
+ }
+
WARN_ON(!rwsem_is_locked(&sb->s_umount));
/* protect against inode wb switch, see inode_switch_wbs_work_fn() */