spin_lock(&inode_lock);
spin_lock(&sb_lock);
+restart:
sb = sb_entry(super_blocks.prev);
for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
if (!list_empty(&sb->s_dirty) || !list_empty(&sb->s_io)) {
+ sb->s_count++;
spin_unlock(&sb_lock);
sync_sb_inodes(sb, wbc);
spin_lock(&sb_lock);
+ if (__put_super(sb))
+ goto restart;
}
if (wbc->nr_to_write <= 0)
break;
/* Superblock refcounting */
+/*
+ * Drop a superblock's refcount. Returns non-zero if the superblock was
+ * destroyed. The caller must hold sb_lock.
+ */
+int __put_super(struct super_block *sb)
+{
+ int ret = 0;
+
+ if (!--sb->s_count) {
+ destroy_super(sb);
+ ret = 1;
+ }
+ return ret;
+}
+
/**
* put_super - drop a temporary reference to superblock
* @s: superblock in question
* Drops a temporary reference, frees superblock if there's no
* references left.
*/
-static inline void put_super(struct super_block *s)
+static void put_super(struct super_block *sb)
{
spin_lock(&sb_lock);
- if (!--s->s_count)
- destroy_super(s);
+ __put_super(sb);
spin_unlock(&sb_lock);
}
+
/**
* deactivate_super - drop an active reference to superblock
* @s: superblock to deactivate
void *data);
struct super_block *get_sb_pseudo(struct file_system_type *, char *,
struct super_operations *ops, unsigned long);
+int __put_super(struct super_block *sb);
void unnamed_dev_init(void);
/* Alas, no aliases. Too much hassle with bringing module.h everywhere */