[PATCH] knfsd: svcrpc: WARN() instead of returning an error from svc_take_page
[sfrench/cifs-2.6.git] / fs / quota.c
index f5d1cff551965ba30fa88d12d50d3a597c9a1245..d6a2be826e29880abd0f6873caa2344f88f2c5f8 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/buffer_head.h>
+#include <linux/capability.h>
+#include <linux/quotaops.h>
 
 /* Check validity of generic quotactl commands */
 static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
@@ -118,6 +120,10 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i
                        if (!sb->s_qcop->get_xquota)
                                return -ENOSYS;
                        break;
+               case Q_XQUOTASYNC:
+                       if (!sb->s_qcop->quota_sync)
+                               return -ENOSYS;
+                       break;
                default:
                        return -EINVAL;
        }
@@ -128,7 +134,7 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i
                     (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
                     !capable(CAP_SYS_ADMIN))
                        return -EPERM;
-       } else if (cmd != Q_XGETQSTAT) {
+       } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
        }
@@ -163,11 +169,11 @@ static void quota_sync_sb(struct super_block *sb, int type)
        sync_blockdev(sb->s_bdev);
 
        /* Now when everything is written we can discard the pagecache so
-        * that userspace sees the changes. We need i_sem and so we could
-        * not do it inside dqonoff_sem. Moreover we need to be carefull
+        * that userspace sees the changes. We need i_mutex and so we could
+        * not do it inside dqonoff_mutex. Moreover we need to be carefull
         * about races with quotaoff() (that is the reason why we have own
         * reference to inode). */
-       down(&sb_dqopt(sb)->dqonoff_sem);
+       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                discard[cnt] = NULL;
                if (type != -1 && cnt != type)
@@ -176,12 +182,12 @@ static void quota_sync_sb(struct super_block *sb, int type)
                        continue;
                discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);
        }
-       up(&sb_dqopt(sb)->dqonoff_sem);
+       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                if (discard[cnt]) {
-                       down(&discard[cnt]->i_sem);
+                       mutex_lock(&discard[cnt]->i_mutex);
                        truncate_inode_pages(&discard[cnt]->i_data, 0);
-                       up(&discard[cnt]->i_sem);
+                       mutex_unlock(&discard[cnt]->i_mutex);
                        iput(discard[cnt]);
                }
        }
@@ -322,6 +328,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
                                return -EFAULT;
                        return 0;
                }
+               case Q_XQUOTASYNC:
+                       return sb->s_qcop->quota_sync(sb, type);
                /* We never reach here unless validity check is broken */
                default:
                        BUG();