Package: dovecot-common 1.0.beta8-2
Severity: normal
Tags: patch
FS-Qupta plugin assumes standard quota format.
This is ok, but not enough.
This plugin does not handle XFS, (not tested) NFS and maybe maybe other FS.
This patch add suport for quotas on XFS.
-- System Information:
Debian Release: testing/unstable
APT prefers testing
APT policy: (500, 'testing')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.16.11
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)
Regards,
Pawel.--- quota-fs.c.orig 2006-04-15 04:00:07.000000000 +0200
+++ quota-fs.c 2006-06-16 14:13:40.000000000 +0200
@@ -16,6 +16,10 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <linux/dqblk_xfs.h>
+
+#define xfs_kern_dqblk fs_disk_quota
+typedef u_int64_t qsize_t;
#ifdef HAVE_STRUCT_DQBLK_CURSPACE
# define dqb_curblocks dqb_curspace
@@ -166,6 +170,22 @@
return resources;
}
+/*
+ * Convert XFS kernel quota format to utility format (from quota utility)
+ */
+static inline void xfs_kern2utildqblk(struct dqblk *u, struct xfs_kern_dqblk *
k)
+{
+ u->dqb_ihardlimit = k->d_ino_hardlimit;
+ u->dqb_isoftlimit = k->d_ino_softlimit;
+ u->dqb_bhardlimit = k->d_blk_hardlimit >> 1;
+ u->dqb_bsoftlimit = k->d_blk_softlimit >> 1;
+ u->dqb_curinodes = k->d_icount;
+ u->dqb_curspace = ((qsize_t)k->d_bcount) << 9;
+ u->dqb_itime = k->d_itimer;
+ u->dqb_btime = k->d_btimer;
+}
+
+
static int
fs_quota_get_resource(struct quota_root *_root, const char *name,
uint64_t *value_r, uint64_t *limit_r)
@@ -183,22 +203,41 @@
return 0;
#ifdef HAVE_QUOTACTL
+ #ifdef HAVE_SYS_QUOTA_H
+ // Linux - XFS
+ struct xfs_kern_dqblk xdqblk;
+ if (quotactl(
+ QCMD(Q_XGETQUOTA,USRQUOTA), root->mount->device_path,
+ root->uid, (void *)&xdqblk) < 0) {
+ // Linux - ext2, ext3
+ i_error("quotactl(Q_XGETQUOTA, %s) failed: %m",
+ root->mount->device_path);
+ quota_set_error(_root->setup->quota,
"Internal quota error");
+ if (quotactl(
+ QCMD(Q_GETQUOTA, USRQUOTA),
root->mount->device_path,
+ root->uid, (void *)&dqblk) < 0) {
+ i_error("quotactl(Q_GETQUOTA,
%s) failed: %m",
+ root->mount->device_path);
+
quota_set_error(_root->setup->quota, "Internal quota error");
+ return -1;
+ }
+ } else {
+ //ALL OK, let's convert XFS quota format to standard one
+ xfs_kern2utildqblk(&dqblk, &xdqblk);
+ }
+ #else
+ // BSD, AIX
if (quotactl(
-#ifdef HAVE_SYS_QUOTA_H
- /* Linux */
- QCMD(Q_GETQUOTA, USRQUOTA), root->mount->device_path,
-#else
- /* BSD, AIX */
root->mount->device_path, QCMD(Q_GETQUOTA, USRQUOTA),
-#endif
root->uid, (void *)&dqblk) < 0) {
i_error("quotactl(Q_GETQUOTA, %s) failed: %m",
root->mount->device_path);
quota_set_error(_root->setup->quota, "Internal quota error");
return -1;
}
+ #endif
#else
- /* Solaris */
+ // Solaris
if (root->mount->fd == -1)
return 0;