* lock ordering than usbfs:
*/
lockdep_set_class(&s->s_lock, &type->s_lock_key);
- down_write(&s->s_umount);
+ /*
+ * sget() can have s_umount recursion.
+ *
+ * When it cannot find a suitable sb, it allocates a new
+ * one (this one), and tries again to find a suitable old
+ * one.
+ *
+ * In case that succeeds, it will acquire the s_umount
+ * lock of the old one. Since these are clearly distrinct
+ * locks, and this object isn't exposed yet, there's no
+ * risk of deadlocks.
+ *
+ * Annotate this by putting this lock in a different
+ * subclass.
+ */
+ down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING);
s->s_count = S_BIAS;
atomic_set(&s->s_active, 1);
mutex_init(&s->s_vfs_rename_mutex);
if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
s->s_count -= S_BIAS-1;
spin_unlock(&sb_lock);
- DQUOT_OFF(s, 0);
+ vfs_dq_off(s, 0);
down_write(&s->s_umount);
fs->kill_sb(s);
put_filesystem(fs);
void __fsync_super(struct super_block *sb)
{
sync_inodes_sb(sb, 0);
- DQUOT_SYNC(sb);
+ vfs_dq_sync(sb);
lock_super(sb);
if (sb->s_dirt && sb->s_op->write_super)
sb->s_op->write_super(sb);
continue;
if (!grab_super(old))
goto retry;
- if (s)
+ if (s) {
+ up_write(&s->s_umount);
destroy_super(s);
+ }
return old;
}
}
err = set(s, data);
if (err) {
spin_unlock(&sb_lock);
+ up_write(&s->s_umount);
destroy_super(s);
return ERR_PTR(err);
}
mark_files_ro(sb);
else if (!fs_may_remount_ro(sb))
return -EBUSY;
- retval = DQUOT_OFF(sb, 1);
+ retval = vfs_dq_off(sb, 1);
if (retval < 0 && retval != -ENOSYS)
return -EBUSY;
}
}
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
if (remount_rw)
- DQUOT_ON_REMOUNT(sb);
+ vfs_dq_quota_on_remount(sb);
return 0;
}
-static void do_emergency_remount(unsigned long foo)
+static void do_emergency_remount(struct work_struct *work)
{
struct super_block *sb;
spin_lock(&sb_lock);
}
spin_unlock(&sb_lock);
+ kfree(work);
printk("Emergency Remount complete\n");
}
void emergency_remount(void)
{
- pdflush_operation(do_emergency_remount, 0);
+ struct work_struct *work;
+
+ work = kmalloc(sizeof(*work), GFP_ATOMIC);
+ if (work) {
+ INIT_WORK(work, do_emergency_remount);
+ schedule_work(work);
+ }
}
/*
bdev->bd_super = s;
}
- return simple_set_mnt(mnt, s);
+ simple_set_mnt(mnt, s);
+ return 0;
error_s:
error = PTR_ERR(s);
return error;
}
s->s_flags |= MS_ACTIVE;
- return simple_set_mnt(mnt, s);
+ simple_set_mnt(mnt, s);
+ return 0;
}
EXPORT_SYMBOL(get_sb_nodev);
s->s_flags |= MS_ACTIVE;
}
do_remount_sb(s, flags, data, 0);
- return simple_set_mnt(mnt, s);
+ simple_set_mnt(mnt, s);
+ return 0;
}
EXPORT_SYMBOL(get_sb_single);