From: Artem Bityutskiy <Artem.Bityutskiy@xxxxxxxxx> The proper way for file-systems to synchronize the superblock should be as follows: 1. when modifying the SB, first modify it, then mark it as dirty; 2. when synchronizing the SB, first mark as clean, then start synchronizing. And to make ensure the order, we need memory barriers in 'sb_mark_clean()' and 'sb_mark_dirty()'. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@xxxxxxxxx> --- include/linux/fs.h | 14 ++++++++++++++ mm/backing-dev.c | 5 +++++ 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index ca1e993..3acaccf 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1783,10 +1783,24 @@ extern int get_sb_pseudo(struct file_system_type *, char *, struct vfsmount *mnt); extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); +/* + * The SB clean/dirty state manipulations should be done as follows: + * 1. modification: first modify the SB-related data, then mark the SB as + * dirty; + * 2. synchronization: first mark the SB as clean, then start synchronizing it. + * + * This order makes sure that races are harmless and we never end up in a + * situation when the SB is modified but is nevertheless marked as clean. + */ void sb_mark_dirty(struct super_block *sb); static inline void sb_mark_clean(struct super_block *sb) { sb->s_dirty = 0; + /* + * Normally FSes first unset the sb->s_dirty flag, and then start + * synchronizing the SB. The memory barrier ensures this order. + */ + smp_mb(); } static inline int sb_is_dirty(struct super_block *sb) { diff --git a/mm/backing-dev.c b/mm/backing-dev.c index d751284..d861bd4 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -352,6 +352,11 @@ static void bdi_flush_io(struct backing_dev_info *bdi) void sb_mark_dirty(struct super_block *sb) { + /* + * Normally FSes modify the SB, and then mark it as dirty. The memory + * barrier ensures this order. + */ + smp_mb(); sb->s_dirty = 1; /* * sb->s_dirty store must be visible to sync_supers before we load -- 1.7.0.1 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html