Module Name:    src
Committed By:   bouyer
Date:           Sun Jan 30 00:25:20 UTC 2011

Modified Files:
        src/sys/ufs/ufs [bouyer-quota2]: quota2_prop.c quota2_prop.h
            ufs_quota.c ufs_quota.h ufs_quota2.c

Log Message:
Implement 'set' command for quota2.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/ufs/ufs/quota2_prop.c \
    src/sys/ufs/ufs/quota2_prop.h src/sys/ufs/ufs/ufs_quota.h
cvs rdiff -u -r1.68.4.3 -r1.68.4.4 src/sys/ufs/ufs/ufs_quota.c
cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/sys/ufs/ufs/ufs_quota2.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/ufs/quota2_prop.c
diff -u src/sys/ufs/ufs/quota2_prop.c:1.1.2.2 src/sys/ufs/ufs/quota2_prop.c:1.1.2.3
--- src/sys/ufs/ufs/quota2_prop.c:1.1.2.2	Fri Jan 21 16:58:06 2011
+++ src/sys/ufs/ufs/quota2_prop.c	Sun Jan 30 00:25:19 2011
@@ -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;
Index: src/sys/ufs/ufs/quota2_prop.h
diff -u src/sys/ufs/ufs/quota2_prop.h:1.1.2.2 src/sys/ufs/ufs/quota2_prop.h:1.1.2.3
--- src/sys/ufs/ufs/quota2_prop.h:1.1.2.2	Fri Jan 21 16:58:06 2011
+++ src/sys/ufs/ufs/quota2_prop.h	Sun Jan 30 00:25:19 2011
@@ -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 *);
Index: src/sys/ufs/ufs/ufs_quota.h
diff -u src/sys/ufs/ufs/ufs_quota.h:1.1.2.2 src/sys/ufs/ufs/ufs_quota.h:1.1.2.3
--- src/sys/ufs/ufs/ufs_quota.h:1.1.2.2	Fri Jan 21 16:58:06 2011
+++ src/sys/ufs/ufs/ufs_quota.h	Sun Jan 30 00:25:20 2011
@@ -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 *);

Index: src/sys/ufs/ufs/ufs_quota.c
diff -u src/sys/ufs/ufs/ufs_quota.c:1.68.4.3 src/sys/ufs/ufs/ufs_quota.c:1.68.4.4
--- src/sys/ufs/ufs/ufs_quota.c:1.68.4.3	Sat Jan 29 23:22:00 2011
+++ src/sys/ufs/ufs/ufs_quota.c	Sun Jan 30 00:25:19 2011
@@ -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)
 {

Index: src/sys/ufs/ufs/ufs_quota2.c
diff -u src/sys/ufs/ufs/ufs_quota2.c:1.1.2.4 src/sys/ufs/ufs/ufs_quota2.c:1.1.2.5
--- src/sys/ufs/ufs/ufs_quota2.c:1.1.2.4	Sat Jan 29 23:22:00 2011
+++ src/sys/ufs/ufs/ufs_quota2.c	Sun Jan 30 00:25:20 2011
@@ -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)

Reply via email to