Annotation of src/lib/libquota/quota_kernel.c, Revision 1.6
1.6 ! dholland 1: /* $NetBSD: quota_kernel.c,v 1.5 2014/06/12 21:39:45 joerg Exp $ */
1.1 dholland 2: /*-
3: * Copyright (c) 2012 The NetBSD Foundation, Inc.
4: * All rights reserved.
5: *
6: * This code is derived from software contributed to The NetBSD Foundation
7: * by David A. Holland.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28: * POSSIBILITY OF SUCH DAMAGE.
29: */
30:
31: #include <sys/cdefs.h>
1.6 ! dholland 32: __RCSID("$NetBSD: quota_kernel.c,v 1.5 2014/06/12 21:39:45 joerg Exp $");
1.1 dholland 33:
34: #include <stdlib.h>
35: #include <err.h>
36: #include <errno.h>
37: #include <limits.h>
38:
39: #include <quota.h>
40: #include <sys/quotactl.h>
41:
42: #include "quotapvt.h"
43:
44: struct kernel_quotacursor {
45: /* just wrap the kernel interface type */
46: struct quotakcursor kcursor;
47: };
48:
49: static int
50: __quota_kernel_stat(struct quotahandle *qh, struct quotastat *stat)
51: {
52: struct quotactl_args args;
53:
54: args.qc_op = QUOTACTL_STAT;
1.2 dholland 55: args.u.stat.qc_info = stat;
1.1 dholland 56: return __quotactl(qh->qh_mountpoint, &args);
57: }
58:
59: const char *
60: __quota_kernel_getimplname(struct quotahandle *qh)
61: {
62: static struct quotastat stat;
63:
64: if (__quota_kernel_stat(qh, &stat)) {
65: return NULL;
66: }
67: return stat.qs_implname;
68: }
69:
70: unsigned
71: __quota_kernel_getrestrictions(struct quotahandle *qh)
72: {
73: struct quotastat stat;
74:
75: if (__quota_kernel_stat(qh, &stat)) {
76: /* XXX no particularly satisfactory thing to do here */
77: return 0;
78: }
79: return stat.qs_restrictions;
80: }
81:
1.3 dholland 82: int
1.1 dholland 83: __quota_kernel_getnumidtypes(struct quotahandle *qh)
84: {
85: struct quotastat stat;
86:
87: if (__quota_kernel_stat(qh, &stat)) {
88: return 0;
89: }
90: return stat.qs_numidtypes;
91: }
92:
93: const char *
94: __quota_kernel_idtype_getname(struct quotahandle *qh, int idtype)
95: {
96: static struct quotaidtypestat stat;
97: struct quotactl_args args;
98:
99: args.qc_op = QUOTACTL_IDTYPESTAT;
100: args.u.idtypestat.qc_idtype = idtype;
101: args.u.idtypestat.qc_info = &stat;
102: if (__quotactl(qh->qh_mountpoint, &args)) {
103: return NULL;
104: }
105: return stat.qis_name;
106: }
107:
1.3 dholland 108: int
1.1 dholland 109: __quota_kernel_getnumobjtypes(struct quotahandle *qh)
110: {
111: struct quotastat stat;
112:
113: if (__quota_kernel_stat(qh, &stat)) {
114: return 0;
115: }
116: return stat.qs_numobjtypes;
117: }
118:
119: const char *
120: __quota_kernel_objtype_getname(struct quotahandle *qh, int objtype)
121: {
122: static struct quotaobjtypestat stat;
123: struct quotactl_args args;
124:
125: args.qc_op = QUOTACTL_OBJTYPESTAT;
126: args.u.objtypestat.qc_objtype = objtype;
127: args.u.objtypestat.qc_info = &stat;
128: if (__quotactl(qh->qh_mountpoint, &args)) {
129: return NULL;
130: }
131: return stat.qos_name;
132: }
133:
134: int
135: __quota_kernel_objtype_isbytes(struct quotahandle *qh, int objtype)
136: {
137: struct quotaobjtypestat stat;
138: struct quotactl_args args;
139:
140: args.qc_op = QUOTACTL_OBJTYPESTAT;
141: args.u.objtypestat.qc_objtype = objtype;
142: args.u.objtypestat.qc_info = &stat;
143: if (__quotactl(qh->qh_mountpoint, &args)) {
144: return 0;
145: }
146: return stat.qos_isbytes;
147: }
148:
149: int
150: __quota_kernel_quotaon(struct quotahandle *qh, int idtype)
151: {
152: struct quotactl_args args;
153: const char *file;
154: char path[PATH_MAX];
155:
156: /*
157: * Note that while it is an error to call quotaon on something
158: * that isn't a volume with old-style quotas that expects
159: * quotaon to be called, it's not our responsibility to check
160: * for that; the filesystem will. Also note that it is not an
161: * error to call quotaon repeatedly -- apparently this is to
162: * permit changing the quota file in use on the fly or
163: * something. So all we need to do here is ask the oldfiles
164: * code if the mount option was set in fstab and fetch back
165: * the filename.
166: */
167:
168: file = __quota_oldfiles_getquotafile(qh, idtype, path, sizeof(path));
169: if (file == NULL) {
170: /*
171: * This idtype (or maybe any idtype) was not enabled
172: * in fstab.
173: */
174: errno = ENXIO;
175: return -1;
176: }
177:
178: args.qc_op = QUOTACTL_QUOTAON;
179: args.u.quotaon.qc_idtype = idtype;
180: args.u.quotaon.qc_quotafile = file;
181: return __quotactl(qh->qh_mountpoint, &args);
182: }
183:
184: int
185: __quota_kernel_quotaoff(struct quotahandle *qh, int idtype)
186: {
187: struct quotactl_args args;
188:
189: args.qc_op = QUOTACTL_QUOTAOFF;
190: args.u.quotaoff.qc_idtype = idtype;
191: return __quotactl(qh->qh_mountpoint, &args);
192: }
193:
194: int
195: __quota_kernel_get(struct quotahandle *qh, const struct quotakey *qk,
196: struct quotaval *qv)
197: {
198: struct quotactl_args args;
199:
200: args.qc_op = QUOTACTL_GET;
201: args.u.get.qc_key = qk;
1.2 dholland 202: args.u.get.qc_val = qv;
1.1 dholland 203: return __quotactl(qh->qh_mountpoint, &args);
204: }
205:
206: int
207: __quota_kernel_put(struct quotahandle *qh, const struct quotakey *qk,
208: const struct quotaval *qv)
209: {
210: struct quotactl_args args;
211:
212: args.qc_op = QUOTACTL_PUT;
213: args.u.put.qc_key = qk;
214: args.u.put.qc_val = qv;
215: return __quotactl(qh->qh_mountpoint, &args);
216: }
217:
218: int
219: __quota_kernel_delete(struct quotahandle *qh, const struct quotakey *qk)
220: {
221: struct quotactl_args args;
222:
1.6 ! dholland 223: args.qc_op = QUOTACTL_DEL;
! 224: args.u.del.qc_key = qk;
1.1 dholland 225: return __quotactl(qh->qh_mountpoint, &args);
226: }
227:
228: struct kernel_quotacursor *
229: __quota_kernel_cursor_create(struct quotahandle *qh)
230: {
231: struct quotactl_args args;
232: struct kernel_quotacursor *cursor;
233: int sverrno;
234:
235: cursor = malloc(sizeof(*cursor));
236: if (cursor == NULL) {
237: return NULL;
238: }
239:
240: args.qc_op = QUOTACTL_CURSOROPEN;
241: args.u.cursoropen.qc_cursor = &cursor->kcursor;
242: if (__quotactl(qh->qh_mountpoint, &args)) {
243: sverrno = errno;
244: free(cursor);
245: errno = sverrno;
246: return NULL;
247: }
248: return cursor;
249: }
250:
251: void
252: __quota_kernel_cursor_destroy(struct quotahandle *qh,
253: struct kernel_quotacursor *cursor)
254: {
255: struct quotactl_args args;
256:
257: args.qc_op = QUOTACTL_CURSORCLOSE;
258: args.u.cursorclose.qc_cursor = &cursor->kcursor;
259: if (__quotactl(qh->qh_mountpoint, &args)) {
260: /* XXX should we really print from inside the library? */
261: warn("__quotactl cursorclose");
262: }
263: free(cursor);
264: }
265:
266: int
267: __quota_kernel_cursor_skipidtype(struct quotahandle *qh,
268: struct kernel_quotacursor *cursor,
1.3 dholland 269: int idtype)
1.1 dholland 270: {
271: struct quotactl_args args;
272:
273: args.qc_op = QUOTACTL_CURSORSKIPIDTYPE;
274: args.u.cursorskipidtype.qc_cursor = &cursor->kcursor;
275: args.u.cursorskipidtype.qc_idtype = idtype;
276: return __quotactl(qh->qh_mountpoint, &args);
277: }
278:
279: int
280: __quota_kernel_cursor_get(struct quotahandle *qh,
281: struct kernel_quotacursor *cursor,
282: struct quotakey *key, struct quotaval *val)
283: {
284: int ret;
285:
286: ret = __quota_kernel_cursor_getn(qh, cursor, key, val, 1);
287: if (ret < 0) {
288: return -1;
289: }
290: return 0;
291: }
292:
293: int
294: __quota_kernel_cursor_getn(struct quotahandle *qh,
295: struct kernel_quotacursor *cursor,
296: struct quotakey *keys, struct quotaval *vals,
297: unsigned maxnum)
298: {
299: struct quotactl_args args;
300: unsigned ret;
301:
1.4 dholland 302: if (maxnum > INT_MAX) {
303: /* joker, eh? */
304: errno = EINVAL;
305: return -1;
306: }
307:
1.1 dholland 308: args.qc_op = QUOTACTL_CURSORGET;
309: args.u.cursorget.qc_cursor = &cursor->kcursor;
310: args.u.cursorget.qc_keys = keys;
311: args.u.cursorget.qc_vals = vals;
312: args.u.cursorget.qc_maxnum = maxnum;
313: args.u.cursorget.qc_ret = &ret;
1.4 dholland 314: if (__quotactl(qh->qh_mountpoint, &args) < 0) {
315: return -1;
316: }
317: return ret;
1.1 dholland 318: }
319:
320: int
321: __quota_kernel_cursor_atend(struct quotahandle *qh,
322: struct kernel_quotacursor *cursor)
323: {
324: struct quotactl_args args;
325: int ret;
326:
327: args.qc_op = QUOTACTL_CURSORATEND;
328: args.u.cursoratend.qc_cursor = &cursor->kcursor;
329: args.u.cursoratend.qc_ret = &ret;
330: if (__quotactl(qh->qh_mountpoint, &args)) {
331: /*
332: * Return -1 so naive callers, who test for the return
333: * value being nonzero, stop iterating, and
334: * sophisticated callers can tell an error from
335: * end-of-data.
336: */
337: return -1;
338: }
339: return ret;
340: }
341:
342: int
343: __quota_kernel_cursor_rewind(struct quotahandle *qh,
344: struct kernel_quotacursor *cursor)
345: {
346: struct quotactl_args args;
347:
348: args.qc_op = QUOTACTL_CURSORREWIND;
349: args.u.cursorrewind.qc_cursor = &cursor->kcursor;
350: return __quotactl(qh->qh_mountpoint, &args);
351: }
CVSweb <webmaster@jp.NetBSD.org>