summaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-05-05 16:08:56 +0200
committerAl Viro <viro@zeniv.linux.org.uk>2009-06-11 21:36:06 -0400
commite5004753388dcf5e1b8a52ac0ab807d232340fbb (patch)
tree4a74a93f1468acb111ba9a3e9ed4a55f338f51fe /fs/super.c
parentf3da392e9ff14b9f388e74319e6d195848991c07 (diff)
downloadlinux-stable-e5004753388dcf5e1b8a52ac0ab807d232340fbb.tar.gz
linux-stable-e5004753388dcf5e1b8a52ac0ab807d232340fbb.tar.bz2
linux-stable-e5004753388dcf5e1b8a52ac0ab807d232340fbb.zip
cleanup sync_supers
Merge the write_super helper into sync_super and move the check for ->write_super earlier so that we can avoid grabbing a reference to a superblock that doesn't have it. While we're at it also add a little comment documenting sync_supers. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/fs/super.c b/fs/super.c
index d9a29d5b1d28..cb19fffc7681 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -399,16 +399,14 @@ void drop_super(struct super_block *sb)
EXPORT_SYMBOL(drop_super);
-static inline void write_super(struct super_block *sb)
-{
- lock_super(sb);
- if (sb->s_root && sb->s_dirt)
- if (sb->s_op->write_super)
- sb->s_op->write_super(sb);
- unlock_super(sb);
-}
-
-/*
+/**
+ * sync_supers - helper for periodic superblock writeback
+ *
+ * Call the write_super method if present on all dirty superblocks in
+ * the system. This is for the periodic writeback used by most older
+ * filesystems. For data integrity superblock writeback use
+ * sync_filesystems() instead.
+ *
* Note: check the dirty flag before waiting, so we don't
* hold up the sync while mounting a device. (The newly
* mounted device won't need syncing.)
@@ -420,12 +418,17 @@ void sync_supers(void)
spin_lock(&sb_lock);
restart:
list_for_each_entry(sb, &super_blocks, s_list) {
- if (sb->s_dirt) {
+ if (sb->s_op->write_super && sb->s_dirt) {
sb->s_count++;
spin_unlock(&sb_lock);
+
down_read(&sb->s_umount);
- write_super(sb);
+ lock_super(sb);
+ if (sb->s_root && sb->s_dirt)
+ sb->s_op->write_super(sb);
+ unlock_super(sb);
up_read(&sb->s_umount);
+
spin_lock(&sb_lock);
if (__put_super_and_need_restart(sb))
goto restart;