dovecot: Added support for group quotas.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Aug 6 22:48:52 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/9a3a7ad297cf
changeset: 6186:9a3a7ad297cf
user: Timo Sirainen <tss at iki.fi>
date: Mon Aug 06 22:48:48 2007 +0300
description:
Added support for group quotas.
diffstat:
1 file changed, 79 insertions(+), 20 deletions(-)
src/plugins/quota/quota-fs.c | 99 +++++++++++++++++++++++++++++++++---------
diffs (172 lines):
diff -r 685a6f165193 -r 9a3a7ad297cf src/plugins/quota/quota-fs.c
--- a/src/plugins/quota/quota-fs.c Mon Aug 06 22:14:16 2007 +0300
+++ b/src/plugins/quota/quota-fs.c Mon Aug 06 22:48:48 2007 +0300
@@ -58,8 +58,12 @@ struct fs_quota_root {
struct quota_root root;
uid_t uid;
+ gid_t gid;
struct fs_quota_mountpoint *mount;
- bool inode_per_mail;
+
+ unsigned int inode_per_mail:1;
+ unsigned int user_disabled:1;
+ unsigned int group_disabled:1;
};
extern struct quota_backend quota_backend_fs;
@@ -70,6 +74,7 @@ static struct quota_root *fs_quota_alloc
root = i_new(struct fs_quota_root, 1);
root->uid = geteuid();
+ root->gid = getegid();
return &root->root;
}
@@ -313,23 +318,40 @@ static int do_rquota(struct fs_quota_roo
}
#endif
+#if defined(FS_QUOTA_LINUX) || defined(FS_QUOTA_BSDAIX)
+static void fs_quota_root_disable(struct fs_quota_root *root, bool group)
+{
+ if (group)
+ root->group_disabled = TRUE;
+ else
+ root->user_disabled = TRUE;
+}
+#endif
+
#ifdef FS_QUOTA_LINUX
static int
-fs_quota_get_linux(struct fs_quota_root *root, bool bytes,
+fs_quota_get_linux(struct fs_quota_root *root, bool group, bool bytes,
uint64_t *value_r, uint64_t *limit_r)
{
struct dqblk dqblk;
+ int type, id;
+
+ type = group ? GRPQUOTA : USRQUOTA;
+ id = group ? root->gid : root->uid;
#ifdef HAVE_XFS_QUOTA
if (strcmp(root->mount->type, "xfs") == 0) {
- /* XFS */
struct fs_disk_quota xdqblk;
- if (quotactl(QCMD(Q_XGETQUOTA, USRQUOTA),
+ if (quotactl(QCMD(Q_XGETQUOTA, type),
root->mount->device_path,
- root->uid, (caddr_t)&xdqblk) < 0) {
- i_error("quotactl(Q_XGETQUOTA, %s) failed: %m",
- root->mount->device_path);
+ id, (caddr_t)&xdqblk) < 0) {
+ if (errno == ESRCH) {
+ fs_quota_root_disable(root, group);
+ return 0;
+ }
+ i_error("%d quotactl(Q_XGETQUOTA, %s) failed: %m",
+ errno, root->mount->device_path);
return -1;
}
@@ -345,9 +367,13 @@ fs_quota_get_linux(struct fs_quota_root
#endif
{
/* ext2, ext3 */
- if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA),
+ if (quotactl(QCMD(Q_GETQUOTA, type),
root->mount->device_path,
- root->uid, (caddr_t)&dqblk) < 0) {
+ id, (caddr_t)&dqblk) < 0) {
+ if (errno == ESRCH) {
+ fs_quota_root_disable(root, group);
+ return 0;
+ }
i_error("quotactl(Q_GETQUOTA, %s) failed: %m",
root->mount->device_path);
if (errno == EINVAL) {
@@ -377,13 +403,21 @@ fs_quota_get_linux(struct fs_quota_root
#ifdef FS_QUOTA_BSDAIX
static int
-fs_quota_get_bsdaix(struct fs_quota_root *root, bool bytes,
+fs_quota_get_bsdaix(struct fs_quota_root *root, bool group, bool bytes,
uint64_t *value_r, uint64_t *limit_r)
{
struct dqblk dqblk;
-
- if (quotactl(root->mount->mount_path, QCMD(Q_GETQUOTA, USRQUOTA),
- root->uid, (void *)&dqblk) < 0) {
+ int type, id;
+
+ type = group ? GRPQUOTA : USRQUOTA;
+ id = group ? root->gid : root->uid;
+
+ if (quotactl(root->mount->mount_path, QCMD(Q_GETQUOTA, type),
+ id, (void *)&dqblk) < 0) {
+ if (errno == ESRCH) {
+ fs_quota_root_disable(root, group);
+ return 0;
+ }
i_error("quotactl(Q_GETQUOTA, %s) failed: %m",
root->mount->mount_path);
return -1;
@@ -429,11 +463,36 @@ fs_quota_get_solaris(struct fs_quota_roo
#endif
static int
+fs_quota_get_one_resource(struct fs_quota_root *root, bool group, bool bytes,
+ uint64_t *value_r, uint64_t *limit_r)
+{
+ if (group) {
+ if (root->group_disabled)
+ return 0;
+ } else {
+ if (root->user_disabled)
+ return 0;
+ }
+#ifdef FS_QUOTA_LINUX
+ return fs_quota_get_linux(root, group, bytes, value_r, limit_r);
+#elif defined (FS_QUOTA_BSDAIX)
+ return fs_quota_get_bsdaix(root, group, bytes, value_r, limit_r);
+#else
+ if (group) {
+ /* not supported */
+ return 0;
+ }
+ return fs_quota_get_solaris(root, bytes, value_r, limit_r);
+#endif
+}
+
+static int
fs_quota_get_resource(struct quota_root *_root, const char *name,
uint64_t *value_r, uint64_t *limit_r)
{
struct fs_quota_root *root = (struct fs_quota_root *)_root;
bool bytes;
+ int ret;
*value_r = 0;
*limit_r = 0;
@@ -455,13 +514,13 @@ fs_quota_get_resource(struct quota_root
}
#endif
-#ifdef FS_QUOTA_LINUX
- return fs_quota_get_linux(root, bytes, value_r, limit_r);
-#elif defined (FS_QUOTA_BSDAIX)
- return fs_quota_get_bsdaix(root, bytes, value_r, limit_r);
-#else
- return fs_quota_get_solaris(root, bytes, value_r, limit_r);
-#endif
+ ret = fs_quota_get_one_resource(root, FALSE, bytes,
+ value_r, limit_r);
+ if (ret != 0)
+ return ret;
+
+ /* fallback to group quota */
+ return fs_quota_get_one_resource(root, TRUE, bytes, value_r, limit_r);
}
static int
More information about the dovecot-cvs
mailing list