changeset 4387:670dd15edbf3 HEAD

Added support for XFS disk quotas. Patch by Pawel Jarosz
author Timo Sirainen <tss@iki.fi>
date Fri, 16 Jun 2006 16:28:17 +0300
parents e23469650c85
children af61031c746f
files configure.in src/plugins/quota/quota-fs.c
diffstat 2 files changed, 41 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/configure.in	Fri Jun 16 14:47:22 2006 +0300
+++ b/configure.in	Fri Jun 16 16:28:17 2006 +0300
@@ -17,7 +17,7 @@
 AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h \
   sys/uio.h sys/sysmacros.h sys/resource.h sys/select.h libgen.h \
   sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h \
-  mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h)
+  mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h linux/dqblk_xfs.h)
 
 AC_ARG_ENABLE(ipv6,
 [  --enable-ipv6           Enable IPv6 support (default)],
--- a/src/plugins/quota/quota-fs.c	Fri Jun 16 14:47:22 2006 +0300
+++ b/src/plugins/quota/quota-fs.c	Fri Jun 16 16:28:17 2006 +0300
@@ -16,6 +16,9 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#ifdef HAVE_LINUX_DQBLK_XFS_H
+#  include <linux/dqblk_xfs.h>
+#endif
 
 #ifdef HAVE_STRUCT_DQBLK_CURSPACE
 #  define dqb_curblocks dqb_curspace
@@ -24,6 +27,7 @@
 struct fs_quota_mountpoint {
 	char *mount_path;
 	char *device_path;
+	char *type;
 
 	unsigned int blk_size;
 
@@ -73,6 +77,7 @@
 
 	i_free(mount->device_path);
 	i_free(mount->mount_path);
+	i_free(mount->type);
 	i_free(mount);
 }
 
@@ -100,7 +105,7 @@
 	mount->blk_size = point.block_size;
 	mount->device_path = point.device_path;
 	mount->mount_path = point.mount_path;
-	i_free(point.type);
+	mount->type = point.type;
 	return mount;
 }
 
@@ -182,15 +187,41 @@
 	if (strcasecmp(name, QUOTA_NAME_STORAGE) != 0 || root->mount == NULL)
 		return 0;
 
-#ifdef HAVE_QUOTACTL
-	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),
+#if defined (HAVE_QUOTACTL) && defined(HAVE_SYS_QUOTA_H)
+	/* Linux */
+#ifdef HAVE_LINUX_DQBLK_XFS_H
+	if (strcmp(root->mount->type, "xfs") == 0) {
+		/* XFS */
+		struct fs_disk_quota xdqblk;
+
+		if (quotactl(QCMD(Q_XGETQUOTA, USRQUOTA),
+			     root->mount->device_path,
+			     root->uid, (void *)&xdqblk) < 0) {
+			i_error("quotactl(Q_XGETQUOTA, %s) failed: %m",
+				root->mount->device_path);
+			quota_set_error(_root->setup->quota,
+					"Internal quota error");
+			return -1;
+		}
+		dqblk.dqb_curblocks = xdqblk.d_bcount << 9;
+		dqblk.dqb_bsoftlimit = xdqblk.d_blk_softlimit >> 1;
+	} else
 #endif
+	{
+		/* ext2, ext3 */
+		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;
+		}
+	}
+#elif defined(HAVE_QUOTACTL)
+	/* BSD, AIX */
+	if (quotactl(root->mount->device_path, QCMD(Q_GETQUOTA, USRQUOTA),
 		     root->uid, (void *)&dqblk) < 0) {
 		i_error("quotactl(Q_GETQUOTA, %s) failed: %m",
 			root->mount->device_path);