Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/bouyer-quota2]: src/sys/ufs/ufs Implement 'set' command for quota2.



details:   https://anonhg.NetBSD.org/src/rev/f74c0a860b23
branches:  bouyer-quota2
changeset: 761082:f74c0a860b23
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sun Jan 30 00:25:19 2011 +0000

description:
Implement 'set' command for quota2.

diffstat:

 sys/ufs/ufs/quota2_prop.c |  18 ++++++++++-
 sys/ufs/ufs/quota2_prop.h |   3 +-
 sys/ufs/ufs/ufs_quota.c   |  76 +++++++++++++++++++++++++++++++++++++++++++++-
 sys/ufs/ufs/ufs_quota.h   |   6 +-
 sys/ufs/ufs/ufs_quota2.c  |  71 ++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 165 insertions(+), 9 deletions(-)

diffs (272 lines):

diff -r 35207ef402c1 -r f74c0a860b23 sys/ufs/ufs/quota2_prop.c
--- a/sys/ufs/ufs/quota2_prop.c Sun Jan 30 00:21:08 2011 +0000
+++ b/sys/ufs/ufs/quota2_prop.c Sun Jan 30 00:25:19 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: quota2_prop.c,v 1.1.2.2 2011/01/21 16:58:06 bouyer Exp $ */
+/* $NetBSD: quota2_prop.c,v 1.1.2.3 2011/01/30 00:25:19 bouyer Exp $ */
 /*-
   * Copyright (c) 2010 Manuel Bouyer
   * All rights reserved.
@@ -72,6 +72,22 @@
 }
 
 int
+quota2_dict_update_q2e_limits(prop_dictionary_t data, struct quota2_entry *q2e)
+{
+       int i, error;
+       prop_dictionary_t val;
+       for (i = 0; i < NQ2V; i++) {
+               val = prop_dictionary_get_dict(data, quota2_valnames[i]);
+               if (val == NULL)
+                       continue;
+               error = quota2_dict_get_q2v_limits(val, &q2e->q2e_val[i], 1);
+               if (error)
+                       return error;
+       }
+       return 0;
+}
+
+int
 quota2_dict_get_q2v_usage(prop_dictionary_t dict, struct quota2_val *q2v)
 {
        uint64_t vu;
diff -r 35207ef402c1 -r f74c0a860b23 sys/ufs/ufs/quota2_prop.h
--- a/sys/ufs/ufs/quota2_prop.h Sun Jan 30 00:21:08 2011 +0000
+++ b/sys/ufs/ufs/quota2_prop.h Sun Jan 30 00:25:19 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: quota2_prop.h,v 1.1.2.2 2011/01/21 16:58:06 bouyer Exp $ */
+/* $NetBSD: quota2_prop.h,v 1.1.2.3 2011/01/30 00:25:19 bouyer Exp $ */
 /*-
   * Copyright (c) 2010 Manuel Bouyer
   * All rights reserved.
@@ -32,6 +32,7 @@
 
 prop_dictionary_t prop_dictionary_get_dict(prop_dictionary_t, const char *);
 int quota2_dict_get_q2v_limits(prop_dictionary_t, struct quota2_val *, bool);
+int quota2_dict_update_q2e_limits(prop_dictionary_t, struct quota2_entry *);
 int quota2_dict_get_q2v_usage(prop_dictionary_t, struct quota2_val *);
 int quota2_dict_get_q2e_usage(prop_dictionary_t, struct quota2_entry *);
 int quota2_get_cmds(prop_dictionary_t, prop_array_t *);
diff -r 35207ef402c1 -r f74c0a860b23 sys/ufs/ufs/ufs_quota.c
--- a/sys/ufs/ufs/ufs_quota.c   Sun Jan 30 00:21:08 2011 +0000
+++ b/sys/ufs/ufs/ufs_quota.c   Sun Jan 30 00:25:19 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_quota.c,v 1.68.4.3 2011/01/29 23:22:00 bouyer Exp $        */
+/*     $NetBSD: ufs_quota.c,v 1.68.4.4 2011/01/30 00:25:19 bouyer Exp $        */
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.3 2011/01/29 23:22:00 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.4 2011/01/30 00:25:19 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -62,6 +62,8 @@
 
 static int quota_handle_cmd_get(struct mount *, struct lwp *,
     prop_dictionary_t, int, prop_array_t);
+static int quota_handle_cmd_set(struct mount *, struct lwp *,
+    prop_dictionary_t, int, prop_array_t);
 static int quota_handle_cmd_getall(struct mount *, struct lwp *,
     prop_dictionary_t, int, prop_array_t);
 /*
@@ -153,6 +155,10 @@
                error = quota_handle_cmd_get(mp, l, cmddict, q2type, datas);
                goto end;
        }
+       if (strcmp(cmd, "set") == 0) {
+               error = quota_handle_cmd_set(mp, l, cmddict, q2type, datas);
+               goto end;
+       }
        if (strcmp(cmd, "getall") == 0) {
                error = quota_handle_cmd_getall(mp, l, cmddict, q2type, datas);
                goto end;
@@ -243,6 +249,72 @@
 }
 
 static int 
+quota_handle_cmd_set(struct mount *mp, struct lwp *l, 
+    prop_dictionary_t cmddict, int type, prop_array_t datas)
+{
+       prop_array_t replies;
+       prop_object_iterator_t iter;
+       prop_dictionary_t data;
+       uint32_t id;
+       struct ufsmount *ump = VFSTOUFS(mp);
+       int error, defaultq = 0;
+       const char *idstr;
+
+       if ((ump->um_flags & (UFS_QUOTA|UFS_QUOTA2)) == 0)
+               return EOPNOTSUPP;
+       
+       replies = prop_array_create();
+       if (replies == NULL)
+               return ENOMEM;
+
+       iter = prop_array_iterator(datas);
+       if (iter == NULL) {
+               prop_object_release(replies);
+               return ENOMEM;
+       }
+       while ((data = prop_object_iterator_next(iter)) != NULL) {
+               if (!prop_dictionary_get_uint32(data, "id", &id)) {
+                       if (!prop_dictionary_get_cstring_nocopy(data, "id",
+                           &idstr))
+                               continue;
+                       if (strcmp(idstr, "default"))
+                               continue;
+                       id = 0;
+                       defaultq = 1;
+               }
+               error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA,
+                   KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE, mp, KAUTH_ARG(id), NULL);
+               if (error != 0) {
+                       prop_object_release(replies);
+                       return error;
+               }
+#ifdef QUOTA
+               if (ump->um_flags & UFS_QUOTA)
+                       error = quota1_handle_cmd_get(ump, type, id, data);
+               else
+#endif
+#ifdef QUOTA2
+               if (ump->um_flags & UFS_QUOTA2) {
+                       error = quota2_handle_cmd_set(ump, type, id, defaultq,
+                           data);
+               } else
+#endif
+                       panic("quota_handle_cmd_get: no support ?");
+               
+               if (error && error != ENOENT) {
+                       prop_object_release(replies);
+                       return error;
+               }
+       }
+       if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) {
+               error = ENOMEM;
+       } else {
+               error = 0;
+       }
+       return error;
+}
+
+static int 
 quota_handle_cmd_getall(struct mount *mp, struct lwp *l, 
     prop_dictionary_t cmddict, int type, prop_array_t datas)
 {
diff -r 35207ef402c1 -r f74c0a860b23 sys/ufs/ufs/ufs_quota.h
--- a/sys/ufs/ufs/ufs_quota.h   Sun Jan 30 00:21:08 2011 +0000
+++ b/sys/ufs/ufs/ufs_quota.h   Sun Jan 30 00:25:19 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_quota.h,v 1.1.2.2 2011/01/21 16:58:06 bouyer Exp $ */
+/*     $NetBSD: ufs_quota.h,v 1.1.2.3 2011/01/30 00:25:20 bouyer Exp $ */
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -128,8 +128,8 @@
 
 int chkdq2(struct inode *, int64_t, kauth_cred_t, int);
 int chkiq2(struct inode *, int32_t, kauth_cred_t, int);
-int quota2_handle_cmd_get(struct ufsmount *, int, int, int,
-    prop_array_t);
+int quota2_handle_cmd_get(struct ufsmount *, int, int, int, prop_array_t);
+int quota2_handle_cmd_set(struct ufsmount *, int, int, int, prop_dictionary_t);
 int quota2_handle_cmd_getall(struct ufsmount *, int, prop_array_t);
 int q2sync(struct mount *);
 int dq2get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *);
diff -r 35207ef402c1 -r f74c0a860b23 sys/ufs/ufs/ufs_quota2.c
--- a/sys/ufs/ufs/ufs_quota2.c  Sun Jan 30 00:21:08 2011 +0000
+++ b/sys/ufs/ufs/ufs_quota2.c  Sun Jan 30 00:25:19 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_quota2.c,v 1.1.2.4 2011/01/29 23:22:00 bouyer Exp $ */
+/* $NetBSD: ufs_quota2.c,v 1.1.2.5 2011/01/30 00:25:20 bouyer Exp $ */
 /*-
   * Copyright (c) 2010 Manuel Bouyer
   * All rights reserved.
@@ -28,7 +28,7 @@
   */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.1.2.4 2011/01/29 23:22:00 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.1.2.5 2011/01/30 00:25:20 bouyer Exp $");
 
 #include <sys/buf.h>
 #include <sys/param.h>
@@ -409,6 +409,73 @@
        return quota2_check(ip, Q2V_FILE, change, cred, flags);
 }
 
+int
+quota2_handle_cmd_set(struct ufsmount *ump, int type, int id,
+    int defaultq, prop_dictionary_t data)
+{
+       int error;
+       struct dquot *dq;
+       struct quota2_header *q2h;
+       struct quota2_entry q2e, *q2ep;
+       struct buf *bp;
+       const int needswap = UFS_MPNEEDSWAP(ump);
+
+       if (ump->um_quotas[type] == NULLVP)
+               return ENODEV;
+       if (defaultq) {
+               mutex_enter(&dqlock);
+               error = getq2h(ump, type, &bp, &q2h, B_MODIFY);
+               if (error) {
+                       mutex_exit(&dqlock);
+                       return error;
+               }
+               quota2_ufs_rwq2e(&q2h->q2h_defentry, &q2e, needswap);
+               error = quota2_dict_update_q2e_limits(data, &q2e);
+               if (error) {
+                       mutex_exit(&dqlock);
+                       brelse(bp, 0);
+                       return error;
+               }
+               quota2_ufs_rwq2e(&q2e, &q2h->q2h_defentry, needswap);
+               mutex_exit(&dqlock);
+               VOP_BWRITE(bp);
+               return error;
+       }
+
+       error = dqget(NULLVP, id, ump, type, &dq);
+       if (error)
+               return error;
+
+       if (dq->dq2_lblkno == 0 && dq->dq2_blkoff == 0) {
+               /* need to alloc a new on-disk quot */
+               mutex_enter(&dqlock);
+               error = quota2_q2ealloc(ump, type, id, dq, &bp, &q2ep);
+               mutex_exit(&dqlock);
+       } else {
+               error = getq2e(ump, type, dq->dq2_lblkno, dq->dq2_blkoff,
+                   &bp, &q2ep, B_MODIFY);
+       }
+       if (error) {
+               dqrele(NULLVP, dq);
+               return error;
+       }
+       mutex_enter(&dq->dq_interlock);
+       quota2_ufs_rwq2e(q2ep, &q2e, needswap);
+       error = quota2_dict_update_q2e_limits(data, &q2e);
+       if (error) {
+               mutex_exit(&dq->dq_interlock);
+               dqrele(NULLVP, dq);
+               brelse(bp, 0);
+               return error;
+       }
+       quota2_ufs_rwq2e(&q2e, q2ep, needswap);
+       mutex_exit(&dq->dq_interlock);
+       dqrele(NULLVP, dq);
+       VOP_BWRITE(bp);
+       
+       return error;
+}
+
 static int
 quota2_array_add_q2e(struct ufsmount *ump, int type,
     int id, prop_array_t replies)



Home | Main Index | Thread Index | Old Index