]> git.hungrycats.org Git - linux/commitdiff
[PATCH] quotactl(): sync all quotas
authorAndrew Morton <akpm@digeo.com>
Sun, 20 Apr 2003 07:27:50 +0000 (00:27 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 20 Apr 2003 07:27:50 +0000 (00:27 -0700)
From: Jan Kara <jack@suse.cz>

  I'm resending a patch which implements quotactl(2) call for syncing
all devices. Particulary it allows the caller not to specify the device
for syncing and in that case quotas on all the devices are written.
The patch is rather trivial (mostly moving the code).

fs/dquot.c
fs/quota.c

index 737b9f1d54ab4b2855c8154db07b99e92e2778fe..f3c0f63265c3776811866cef88e48f08eee1dd25 100644 (file)
@@ -345,50 +345,6 @@ restart:
        return 0;
 }
 
-static struct super_block *get_super_to_sync(int type)
-{
-       struct list_head *head;
-       int cnt, dirty;
-
-restart:
-       spin_lock(&sb_lock);
-       list_for_each(head, &super_blocks) {
-               struct super_block *sb = list_entry(head, struct super_block, s_list);
-
-               for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
-                       if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
-                           && info_any_dquot_dirty(&sb_dqopt(sb)->info[cnt]))
-                               dirty = 1;
-               if (!dirty)
-                       continue;
-               sb->s_count++;
-               spin_unlock(&sb_lock);
-               down_read(&sb->s_umount);
-               if (!sb->s_root) {
-                       drop_super(sb);
-                       goto restart;
-               }
-               return sb;
-       }
-       spin_unlock(&sb_lock);
-       return NULL;
-}
-
-void sync_dquots(struct super_block *sb, int type)
-{
-       if (sb) {
-               if (sb->s_qcop->quota_sync)
-                       sb->s_qcop->quota_sync(sb, type);
-       }
-       else {
-               while ((sb = get_super_to_sync(type))) {
-                       if (sb->s_qcop->quota_sync)
-                               sb->s_qcop->quota_sync(sb, type);
-                       drop_super(sb);
-               }
-       }
-}
-
 /* Free unused dquots from cache */
 static void prune_dqcache(int count)
 {
index 3daa619013639338f589d7f8da82961cb2cd5704..ce929f581b53e17ab5fb09cdc6a7bf4f2e9c05b3 100644 (file)
@@ -19,8 +19,10 @@ static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t
 {
        if (type >= MAXQUOTAS)
                return -EINVAL;
+       if (!sb && cmd != Q_SYNC)
+               return -ENODEV;
        /* Is operation supported? */
-       if (!sb->s_qcop)
+       if (sb && !sb->s_qcop)
                return -ENOSYS;
 
        switch (cmd) {
@@ -51,7 +53,7 @@ static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t
                                return -ENOSYS;
                        break;
                case Q_SYNC:
-                       if (!sb->s_qcop->quota_sync)
+                       if (sb && !sb->s_qcop->quota_sync)
                                return -ENOSYS;
                        break;
                case Q_XQUOTAON:
@@ -102,6 +104,50 @@ static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t
        return security_quotactl (cmd, type, id, sb);
 }
 
+static struct super_block *get_super_to_sync(int type)
+{
+       struct list_head *head;
+       int cnt, dirty;
+
+restart:
+       spin_lock(&sb_lock);
+       list_for_each(head, &super_blocks) {
+               struct super_block *sb = list_entry(head, struct super_block, s_list);
+
+               for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
+                       if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
+                           && info_any_dquot_dirty(&sb_dqopt(sb)->info[cnt]))
+                               dirty = 1;
+               if (!dirty)
+                       continue;
+               sb->s_count++;
+               spin_unlock(&sb_lock);
+               down_read(&sb->s_umount);
+               if (!sb->s_root) {
+                       drop_super(sb);
+                       goto restart;
+               }
+               return sb;
+       }
+       spin_unlock(&sb_lock);
+       return NULL;
+}
+
+void sync_dquots(struct super_block *sb, int type)
+{
+       if (sb) {
+               if (sb->s_qcop->quota_sync)
+                       sb->s_qcop->quota_sync(sb, type);
+       }
+       else {
+               while ((sb = get_super_to_sync(type))) {
+                       if (sb->s_qcop->quota_sync)
+                               sb->s_qcop->quota_sync(sb, type);
+                       drop_super(sb);
+               }
+       }
+}
+
 /* Copy parameters and call proper function */
 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr)
 {
@@ -167,7 +213,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, cadd
                        return sb->s_qcop->set_dqblk(sb, type, id, &idq);
                }
                case Q_SYNC:
-                       return sb->s_qcop->quota_sync(sb, type);
+                       sync_dquots(sb, type);
+                       return 0;
 
                case Q_XQUOTAON:
                case Q_XQUOTAOFF:
@@ -222,27 +269,30 @@ asmlinkage long sys_quotactl(unsigned int cmd, const char *special, qid_t id, ca
        struct super_block *sb = NULL;
        struct block_device *bdev;
        char *tmp;
-       int ret = -ENODEV;
+       int ret;
 
        cmds = cmd >> SUBCMDSHIFT;
        type = cmd & SUBCMDMASK;
 
-       tmp = getname(special);
-       if (IS_ERR(tmp))
-               return PTR_ERR(tmp);
-       bdev = lookup_bdev(tmp);
-       putname(tmp);
-       if (IS_ERR(bdev))
-               return PTR_ERR(bdev);
-       sb = get_super(bdev);
-       bdput(bdev);
+       if (cmds != Q_SYNC || special) {
+               tmp = getname(special);
+               if (IS_ERR(tmp))
+                       return PTR_ERR(tmp);
+               bdev = lookup_bdev(tmp);
+               putname(tmp);
+               if (IS_ERR(bdev))
+                       return PTR_ERR(bdev);
+               sb = get_super(bdev);
+               bdput(bdev);
+               if (!sb)
+                       return -ENODEV;
+       }
 
-       if (sb) {
-               ret = check_quotactl_valid(sb, type, cmds, id);
-               if (ret >= 0)
-                       ret = do_quotactl(sb, type, cmds, id, addr);
+       ret = check_quotactl_valid(sb, type, cmds, id);
+       if (ret >= 0)
+               ret = do_quotactl(sb, type, cmds, id, addr);
+       if (sb)
                drop_super(sb);
-       }
 
        return ret;
 }