Module Name: src
Committed By: dholland
Date: Mon Jan 9 15:45:19 UTC 2012
Modified Files:
src/lib/libquota: quota_oldfiles.c quotapvt.h
Log Message:
Implement quota_put and quota_delete for the fallback direct file
access backend.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/lib/libquota/quota_oldfiles.c
cvs rdiff -u -r1.7 -r1.8 src/lib/libquota/quotapvt.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libquota/quota_oldfiles.c
diff -u src/lib/libquota/quota_oldfiles.c:1.1 src/lib/libquota/quota_oldfiles.c:1.2
--- src/lib/libquota/quota_oldfiles.c:1.1 Mon Jan 9 15:41:58 2012
+++ src/lib/libquota/quota_oldfiles.c Mon Jan 9 15:45:19 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_oldfiles.c,v 1.1 2012/01/09 15:41:58 dholland Exp $ */
+/* $NetBSD: quota_oldfiles.c,v 1.2 2012/01/09 15:45:19 dholland Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -64,7 +64,7 @@ struct oldfiles_quotacursor {
};
static uint64_t
-dqblk_limit(uint32_t val)
+dqblk_getlimit(uint32_t val)
{
if (val == 0) {
return QUOTA_NOLIMIT;
@@ -73,11 +73,21 @@ dqblk_limit(uint32_t val)
}
}
+static uint32_t
+dqblk_setlimit(uint64_t val)
+{
+ if (val == QUOTA_NOLIMIT && val >= 0xffffffffUL) {
+ return 0;
+ } else {
+ return (uint32_t)val + 1;
+ }
+}
+
static void
dqblk_getblocks(const struct dqblk *dq, struct quotaval *qv)
{
- qv->qv_hardlimit = dqblk_limit(dq->dqb_bhardlimit);
- qv->qv_softlimit = dqblk_limit(dq->dqb_bsoftlimit);
+ qv->qv_hardlimit = dqblk_getlimit(dq->dqb_bhardlimit);
+ qv->qv_softlimit = dqblk_getlimit(dq->dqb_bsoftlimit);
qv->qv_usage = dq->dqb_curblocks;
qv->qv_expiretime = dq->dqb_btime;
qv->qv_grace = QUOTA_NOTIME;
@@ -86,13 +96,33 @@ dqblk_getblocks(const struct dqblk *dq,
static void
dqblk_getfiles(const struct dqblk *dq, struct quotaval *qv)
{
- qv->qv_hardlimit = dqblk_limit(dq->dqb_ihardlimit);
- qv->qv_softlimit = dqblk_limit(dq->dqb_isoftlimit);
+ qv->qv_hardlimit = dqblk_getlimit(dq->dqb_ihardlimit);
+ qv->qv_softlimit = dqblk_getlimit(dq->dqb_isoftlimit);
qv->qv_usage = dq->dqb_curinodes;
qv->qv_expiretime = dq->dqb_itime;
qv->qv_grace = QUOTA_NOTIME;
}
+static void
+dqblk_putblocks(const struct quotaval *qv, struct dqblk *dq)
+{
+ dq->dqb_bhardlimit = dqblk_setlimit(qv->qv_hardlimit);
+ dq->dqb_bsoftlimit = dqblk_setlimit(qv->qv_softlimit);
+ dq->dqb_curblocks = qv->qv_usage;
+ dq->dqb_btime = qv->qv_expiretime;
+ /* ignore qv->qv_grace */
+}
+
+static void
+dqblk_putfiles(const struct quotaval *qv, struct dqblk *dq)
+{
+ dq->dqb_ihardlimit = dqblk_setlimit(qv->qv_hardlimit);
+ dq->dqb_isoftlimit = dqblk_setlimit(qv->qv_softlimit);
+ dq->dqb_curinodes = qv->qv_usage;
+ dq->dqb_itime = qv->qv_expiretime;
+ /* ignore qv->qv_grace */
+}
+
static int
__quota_oldfiles_open(struct quotahandle *qh, const char *path, int *fd_ret)
{
@@ -249,8 +279,11 @@ __quota_oldfiles_doget(struct quotahandl
result = pread(file, &dq, sizeof(dq), pos);
if (result < 0) {
return -1;
- }
- if ((size_t)result != sizeof(dq)) {
+ } else if (result == 0) {
+ /* Past EOF; no quota info on file for this ID */
+ errno = ENOENT;
+ return -1;
+ } else if ((size_t)result != sizeof(dq)) {
errno = EFTYPE;
return -1;
}
@@ -296,6 +329,112 @@ __quota_oldfiles_doget(struct quotahandl
return 0;
}
+static int
+__quota_oldfiles_doput(struct quotahandle *qh, const struct quotakey *qk,
+ const struct quotaval *qv)
+{
+ int file;
+ off_t pos;
+ struct quotaval qv2;
+ struct dqblk dq;
+ ssize_t result;
+
+ switch (qk->qk_idtype) {
+ case QUOTA_IDTYPE_USER:
+ file = qh->qh_userfile;
+ break;
+ case QUOTA_IDTYPE_GROUP:
+ file = qh->qh_groupfile;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (qk->qk_id == QUOTA_DEFAULTID) {
+ pos = 0;
+ } else {
+ pos = qk->qk_id * sizeof(struct dqblk);
+ }
+
+ result = pread(file, &dq, sizeof(dq), pos);
+ if (result < 0) {
+ return -1;
+ } else if (result == 0) {
+ /* Past EOF; fill in a blank dq to start from */
+ dq.dqb_bhardlimit = 0;
+ dq.dqb_bsoftlimit = 0;
+ dq.dqb_curblocks = 0;
+ dq.dqb_ihardlimit = 0;
+ dq.dqb_isoftlimit = 0;
+ dq.dqb_curinodes = 0;
+ dq.dqb_btime = 0;
+ dq.dqb_itime = 0;
+ } else if ((size_t)result != sizeof(dq)) {
+ errno = EFTYPE;
+ return -1;
+ }
+
+ switch (qk->qk_objtype) {
+ case QUOTA_OBJTYPE_BLOCKS:
+ dqblk_getblocks(&dq, &qv2);
+ break;
+ case QUOTA_OBJTYPE_FILES:
+ dqblk_getfiles(&dq, &qv2);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (qk->qk_id == QUOTA_DEFAULTID) {
+ qv2.qv_hardlimit = qv->qv_hardlimit;
+ qv2.qv_softlimit = qv->qv_softlimit;
+ /* leave qv2.qv_usage unchanged */
+ qv2.qv_expiretime = qv->qv_grace;
+ /* skip qv2.qv_grace */
+
+ /* ignore qv->qv_usage */
+ /* ignore qv->qv_expiretime */
+ } else if (qk->qk_id == 0) {
+ /* leave qv2.qv_hardlimit unchanged */
+ /* leave qv2.qv_softlimit unchanged */
+ qv2.qv_usage = qv->qv_usage;
+ /* leave qv2.qv_expiretime unchanged */
+ /* skip qv2.qv_grace */
+
+ /* ignore qv->qv_hardlimit */
+ /* ignore qv->qv_softlimit */
+ /* ignore qv->qv_expiretime */
+ /* ignore qv->qv_grace */
+ } else {
+ qv2 = *qv;
+ }
+
+ switch (qk->qk_objtype) {
+ case QUOTA_OBJTYPE_BLOCKS:
+ dqblk_putblocks(&qv2, &dq);
+ break;
+ case QUOTA_OBJTYPE_FILES:
+ dqblk_putfiles(&qv2, &dq);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ result = pwrite(file, &dq, sizeof(dq), pos);
+ if (result < 0) {
+ return -1;
+ } else if ((size_t)result != sizeof(dq)) {
+ /* ? */
+ errno = EFTYPE;
+ return -1;
+ }
+
+ return 0;
+}
+
int
__quota_oldfiles_get(struct quotahandle *qh, const struct quotakey *qk,
struct quotaval *qv)
@@ -303,6 +442,22 @@ __quota_oldfiles_get(struct quotahandle
return __quota_oldfiles_doget(qh, qk, qv, NULL);
}
+int
+__quota_oldfiles_put(struct quotahandle *qh, const struct quotakey *qk,
+ const struct quotaval *qv)
+{
+ return __quota_oldfiles_doput(qh, qk, qv);
+}
+
+int
+__quota_oldfiles_delete(struct quotahandle *qh, const struct quotakey *qk)
+{
+ struct quotaval qv;
+
+ quotaval_clear(&qv);
+ return __quota_oldfiles_doput(qh, qk, &qv);
+}
+
struct oldfiles_quotacursor *
__quota_oldfiles_cursor_create(struct quotahandle *qh)
{
Index: src/lib/libquota/quotapvt.h
diff -u src/lib/libquota/quotapvt.h:1.7 src/lib/libquota/quotapvt.h:1.8
--- src/lib/libquota/quotapvt.h:1.7 Mon Jan 9 15:43:19 2012
+++ src/lib/libquota/quotapvt.h Mon Jan 9 15:45:19 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quotapvt.h,v 1.7 2012/01/09 15:43:19 dholland Exp $ */
+/* $NetBSD: quotapvt.h,v 1.8 2012/01/09 15:45:19 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -85,6 +85,9 @@ int __quota_oldfiles_initialize(struct q
const char *__quota_oldfiles_getimplname(struct quotahandle *);
int __quota_oldfiles_get(struct quotahandle *qh, const struct quotakey *qk,
struct quotaval *qv);
+int __quota_oldfiles_put(struct quotahandle *qh, const struct quotakey *qk,
+ const struct quotaval *qv);
+int __quota_oldfiles_delete(struct quotahandle *qh, const struct quotakey *qk);
struct oldfiles_quotacursor *
__quota_oldfiles_cursor_create(struct quotahandle *);
void __quota_oldfiles_cursor_destroy(struct oldfiles_quotacursor *);