Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6186:9a3a7ad297cf HEAD
Added support for group quotas.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 06 Aug 2007 22:48:48 +0300 |
parents | 685a6f165193 |
children | 7c81e6d848f6 |
files | src/plugins/quota/quota-fs.c |
diffstat | 1 files changed, 78 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- 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 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 @@ root = i_new(struct fs_quota_root, 1); root->uid = geteuid(); + root->gid = getegid(); return &root->root; } @@ -313,23 +318,40 @@ } #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 @@ #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 @@ #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; + int type, id; - if (quotactl(root->mount->mount_path, QCMD(Q_GETQUOTA, USRQUOTA), - root->uid, (void *)&dqblk) < 0) { + 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 @@ #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 @@ } #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