Module Name:    src
Committed By:   dholland
Date:           Sun Jan 29 06:57:15 UTC 2012

Modified Files:
        src/sys/kern: vfs_quotactl.c
        src/sys/sys: quotactl.h
        src/sys/ufs/ufs: ufs_quota.c ufs_quota.h ufs_quota2.c

Log Message:
Begin adding quota cursor/iteration interface to VFS_QUOTACTL.

Add struct quotakcursor.
Add QUOTACTL_CURSOROPEN and QUOTACTL_CURSORCLOSE operations.
Implement the plumbing for them.
Add trivial implementations of them for quota2.
(iteration is not supported on quota1 for the time being, just as
getall isn't)
Have the proplib interpreter open and close a cursor around doing
QUOTACTL_GETALL.

Note: this change requires a kernel version bump.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/kern/vfs_quotactl.c
cvs rdiff -u -r1.18 -r1.19 src/sys/sys/quotactl.h
cvs rdiff -u -r1.92 -r1.93 src/sys/ufs/ufs/ufs_quota.c
cvs rdiff -u -r1.14 -r1.15 src/sys/ufs/ufs/ufs_quota.h
cvs rdiff -u -r1.15 -r1.16 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/kern/vfs_quotactl.c
diff -u src/sys/kern/vfs_quotactl.c:1.20 src/sys/kern/vfs_quotactl.c:1.21
--- src/sys/kern/vfs_quotactl.c:1.20	Sun Jan 29 06:55:44 2012
+++ src/sys/kern/vfs_quotactl.c	Sun Jan 29 06:57:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_quotactl.c,v 1.20 2012/01/29 06:55:44 dholland Exp $	*/
+/*	$NetBSD: vfs_quotactl.c,v 1.21 2012/01/29 06:57:15 dholland Exp $	*/
 
 /*
  * Copyright (c) 1991, 1993, 1994
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.20 2012/01/29 06:55:44 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.21 2012/01/29 06:57:15 dholland Exp $");
 
 #include <sys/mount.h>
 #include <sys/quota.h>
@@ -442,13 +442,32 @@ vfs_quotactl_getall(struct mount *mp,
 			prop_dictionary_t cmddict, int q2type,
 			prop_array_t datas)
 {
+	struct quotakcursor cursor;
 	struct vfs_quotactl_args args;
+	int error, error2;
+
+	args.qc_type = QCT_CURSOROPEN;
+	args.u.cursoropen.qc_cursor = &cursor;
+	error = VFS_QUOTACTL(mp, QUOTACTL_CURSOROPEN, &args);
+	if (error) {
+		return error;
+	}
 
 	args.qc_type = QCT_PROPLIB;
 	args.u.proplib.qc_cmddict = cmddict;
 	args.u.proplib.qc_q2type = q2type;
 	args.u.proplib.qc_datas = datas;
-	return VFS_QUOTACTL(mp, QUOTACTL_GETALL, &args);
+	error = VFS_QUOTACTL(mp, QUOTACTL_GETALL, &args);
+
+	args.qc_type = QCT_CURSORCLOSE;
+	args.u.cursorclose.qc_cursor = &cursor;
+	error2 = VFS_QUOTACTL(mp, QUOTACTL_CURSORCLOSE, &args);
+
+	if (error) {
+		return error;
+	}
+	error = error2;
+	return error;
 }
 
 static int

Index: src/sys/sys/quotactl.h
diff -u src/sys/sys/quotactl.h:1.18 src/sys/sys/quotactl.h:1.19
--- src/sys/sys/quotactl.h:1.18	Sun Jan 29 06:55:44 2012
+++ src/sys/sys/quotactl.h	Sun Jan 29 06:57:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: quotactl.h,v 1.18 2012/01/29 06:55:44 dholland Exp $	*/
+/*	$NetBSD: quotactl.h,v 1.19 2012/01/29 06:57:15 dholland Exp $	*/
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -37,6 +37,20 @@
  * use the <quota.h> API instead.
  */
 
+/*
+ * Semi-opaque structure for cursors. This holds the cursor state in
+ * userland; the size is exposed only to libquota, not to client code,
+ * and is meant to be large enough to accomodate all likely future
+ * expansion without being unduly bloated, as it will need to be
+ * copied in and out for every call using it.
+ */
+struct quotakcursor {
+	union {
+		char qkc_space[64];
+		uintmax_t __qkc_forcealign;
+	} u;
+};
+
 /* Command codes. */
 #define QUOTACTL_GETVERSION	0
 #define QUOTACTL_QUOTAON	1
@@ -45,6 +59,8 @@
 #define QUOTACTL_PUT		4
 #define QUOTACTL_GETALL		5
 #define QUOTACTL_DELETE		6
+#define QUOTACTL_CURSOROPEN	7
+#define QUOTACTL_CURSORCLOSE	8
 
 /* Argument encoding. */
 enum vfs_quotactl_argtypes {
@@ -53,6 +69,8 @@ enum vfs_quotactl_argtypes {
 	QCT_GET,	/* get */
 	QCT_PUT,	/* put */
 	QCT_DELETE,	/* delete */
+	QCT_CURSOROPEN,	/* open cursor */
+	QCT_CURSORCLOSE,/* close cursor */
 };
 struct vfs_quotactl_args {
 	enum vfs_quotactl_argtypes qc_type;
@@ -76,6 +94,12 @@ struct vfs_quotactl_args {
 		struct {
 			const struct quotakey *qc_key;
 		} delete;
+		struct {
+			struct quotakcursor *qc_cursor;
+		} cursoropen;
+		struct {
+			struct quotakcursor *qc_cursor;
+		} cursorclose;
 	} u;
 };
 

Index: src/sys/ufs/ufs/ufs_quota.c
diff -u src/sys/ufs/ufs/ufs_quota.c:1.92 src/sys/ufs/ufs/ufs_quota.c:1.93
--- src/sys/ufs/ufs/ufs_quota.c:1.92	Sun Jan 29 06:55:44 2012
+++ src/sys/ufs/ufs/ufs_quota.c	Sun Jan 29 06:57:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_quota.c,v 1.92 2012/01/29 06:55:44 dholland Exp $	*/
+/*	$NetBSD: ufs_quota.c,v 1.93 2012/01/29 06:57:15 dholland 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.92 2012/01/29 06:55:44 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.93 2012/01/29 06:57:15 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -85,6 +85,10 @@ static int quota_handle_cmd_quotaon(stru
     struct vfs_quotactl_args *args);
 static int quota_handle_cmd_quotaoff(struct mount *, struct lwp *, 
     struct vfs_quotactl_args *args);
+static int quota_handle_cmd_cursoropen(struct mount *, struct lwp *,
+    struct vfs_quotactl_args *args);
+static int quota_handle_cmd_cursorclose(struct mount *, struct lwp *,
+    struct vfs_quotactl_args *args);
 
 /*
  * Initialize the quota fields of an inode.
@@ -181,6 +185,12 @@ quota_handle_cmd(struct mount *mp, struc
 	    case QUOTACTL_DELETE:
 		error = quota_handle_cmd_delete(mp, l, args);
 		break;
+	    case QUOTACTL_CURSOROPEN:
+		error = quota_handle_cmd_cursoropen(mp, l, args);
+		break;
+	    case QUOTACTL_CURSORCLOSE:
+		error = quota_handle_cmd_cursorclose(mp, l, args);
+		break;
 	    default:
 		panic("Invalid quotactl operation %d\n", op);
 	}
@@ -400,6 +410,58 @@ quota_handle_cmd_getall(struct mount *mp
 }
 
 static int 
+quota_handle_cmd_cursoropen(struct mount *mp, struct lwp *l, 
+    struct vfs_quotactl_args *args)
+{
+	struct ufsmount *ump = VFSTOUFS(mp);
+	struct quotakcursor *cursor;
+	int error;
+
+	KASSERT(args->qc_type == QCT_CURSOROPEN);
+	cursor = args->u.cursoropen.qc_cursor;
+
+	error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA,
+	    KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, NULL, NULL);
+	if (error)
+		return error;
+
+#ifdef QUOTA2
+	if (ump->um_flags & UFS_QUOTA2) {
+		error = quota2_handle_cmd_cursoropen(ump, cursor);
+	} else
+#endif
+		error = EOPNOTSUPP;
+
+	return error;
+}
+
+static int 
+quota_handle_cmd_cursorclose(struct mount *mp, struct lwp *l, 
+    struct vfs_quotactl_args *args)
+{
+	struct ufsmount *ump = VFSTOUFS(mp);
+	struct quotakcursor *cursor;
+	int error;
+
+	KASSERT(args->qc_type == QCT_CURSORCLOSE);
+	cursor = args->u.cursorclose.qc_cursor;
+
+	error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA,
+	    KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, NULL, NULL);
+	if (error)
+		return error;
+
+#ifdef QUOTA2
+	if (ump->um_flags & UFS_QUOTA2) {
+		error = quota2_handle_cmd_cursorclose(ump, cursor);
+	} else
+#endif
+		error = EOPNOTSUPP;
+
+	return error;
+}
+
+static int 
 quota_handle_cmd_quotaon(struct mount *mp, struct lwp *l, 
     struct vfs_quotactl_args *args)
 {

Index: src/sys/ufs/ufs/ufs_quota.h
diff -u src/sys/ufs/ufs/ufs_quota.h:1.14 src/sys/ufs/ufs/ufs_quota.h:1.15
--- src/sys/ufs/ufs/ufs_quota.h:1.14	Sun Jan 29 06:55:44 2012
+++ src/sys/ufs/ufs/ufs_quota.h	Sun Jan 29 06:57:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_quota.h,v 1.14 2012/01/29 06:55:44 dholland Exp $	*/
+/*	$NetBSD: ufs_quota.h,v 1.15 2012/01/29 06:57:15 dholland Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -36,6 +36,9 @@
 #include <ufs/ufs/quota1.h>
 #include <ufs/ufs/quota2.h>
 
+struct quotakcursor; /* from <sys/quotactl.h> */
+
+
 /* link to this quota in the quota inode (for QUOTA2) */
 struct dq2_desc {
 	uint64_t dq2_lblkno; /* logical disk block holding this quota */
@@ -129,6 +132,8 @@ int quota2_handle_cmd_put(struct ufsmoun
     const struct quotaval *);
 int quota2_handle_cmd_delete(struct ufsmount *, const struct quotakey *);
 int quota2_handle_cmd_getall(struct ufsmount *, int, prop_array_t);
+int quota2_handle_cmd_cursoropen(struct ufsmount *, struct quotakcursor *);
+int quota2_handle_cmd_cursorclose(struct ufsmount *, struct quotakcursor *);
 int q2sync(struct mount *);
 int dq2get(struct vnode *, u_long, struct ufsmount *, int, struct dquot *);
 int dq2sync(struct vnode *, struct dquot *);

Index: src/sys/ufs/ufs/ufs_quota2.c
diff -u src/sys/ufs/ufs/ufs_quota2.c:1.15 src/sys/ufs/ufs/ufs_quota2.c:1.16
--- src/sys/ufs/ufs/ufs_quota2.c:1.15	Sun Jan 29 06:55:44 2012
+++ src/sys/ufs/ufs/ufs_quota2.c	Sun Jan 29 06:57:15 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_quota2.c,v 1.15 2012/01/29 06:55:44 dholland Exp $ */
+/* $NetBSD: ufs_quota2.c,v 1.16 2012/01/29 06:57:15 dholland Exp $ */
 /*-
   * Copyright (c) 2010 Manuel Bouyer
   * All rights reserved.
@@ -26,7 +26,7 @@
   */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.15 2012/01/29 06:55:44 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.16 2012/01/29 06:57:15 dholland Exp $");
 
 #include <sys/buf.h>
 #include <sys/param.h>
@@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c
 #include <sys/kauth.h>
 #include <sys/wapbl.h>
 #include <sys/quota.h>
+#include <sys/quotactl.h>
 
 #include <ufs/ufs/quota2.h>
 #include <ufs/ufs/inode.h>
@@ -1038,6 +1039,39 @@ error_bp:
 	return error;
 }
 
+struct ufsq2_cursor {
+	uint32_t q2c_magic;
+};
+
+#define Q2C_MAGIC (0xbeebe111)
+
+#define Q2CURSOR(qkc) ((struct ufsq2_cursor *)&qkc->u.qkc_space[0])
+
+int
+quota2_handle_cmd_cursoropen(struct ufsmount *ump, struct quotakcursor *qkc)
+{
+	struct ufsq2_cursor *cursor;
+
+	CTASSERT(sizeof(*cursor) <= sizeof(qkc->u.qkc_space));
+	cursor = Q2CURSOR(qkc);
+
+	cursor->q2c_magic = Q2C_MAGIC;
+	return 0;
+}
+
+int
+quota2_handle_cmd_cursorclose(struct ufsmount *ump, struct quotakcursor *qkc)
+{
+	struct ufsq2_cursor *cursor;
+
+	cursor = Q2CURSOR(qkc);
+	if (cursor->q2c_magic != Q2C_MAGIC) {
+		return EINVAL;
+	}
+
+	return 0;
+}
+
 int
 q2sync(struct mount *mp)
 {

Reply via email to