block: remove i_bdev
[linux-2.6-microblaze.git] / fs / quota / quota.c
index 9af95c7..6d16b2b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/writeback.h>
 #include <linux/nospec.h>
 #include "compat.h"
+#include "../internal.h"
 
 static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
                                     qid_t id)
@@ -865,27 +866,42 @@ static bool quotactl_cmd_onoff(int cmd)
 static struct super_block *quotactl_block(const char __user *special, int cmd)
 {
 #ifdef CONFIG_BLOCK
-       struct block_device *bdev;
        struct super_block *sb;
        struct filename *tmp = getname(special);
+       bool excl = false, thawed = false;
+       int error;
+       dev_t dev;
 
        if (IS_ERR(tmp))
                return ERR_CAST(tmp);
-       bdev = lookup_bdev(tmp->name);
+       error = lookup_bdev(tmp->name, &dev);
        putname(tmp);
-       if (IS_ERR(bdev))
-               return ERR_CAST(bdev);
-       if (quotactl_cmd_onoff(cmd))
-               sb = get_super_exclusive_thawed(bdev);
-       else if (quotactl_cmd_write(cmd))
-               sb = get_super_thawed(bdev);
-       else
-               sb = get_super(bdev);
-       bdput(bdev);
+       if (error)
+               return ERR_PTR(error);
+
+       if (quotactl_cmd_onoff(cmd)) {
+               excl = true;
+               thawed = true;
+       } else if (quotactl_cmd_write(cmd)) {
+               thawed = true;
+       }
+
+retry:
+       sb = user_get_super(dev, excl);
        if (!sb)
                return ERR_PTR(-ENODEV);
-
+       if (thawed && sb->s_writers.frozen != SB_UNFROZEN) {
+               if (excl)
+                       up_write(&sb->s_umount);
+               else
+                       up_read(&sb->s_umount);
+               wait_event(sb->s_writers.wait_unfrozen,
+                          sb->s_writers.frozen == SB_UNFROZEN);
+               put_super(sb);
+               goto retry;
+       }
        return sb;
+
 #else
        return ERR_PTR(-ENODEV);
 #endif