[patchset] quota fixes, cleanups and sysquotas for AIX

Björn JACKE bjacke at samba.org
Tue Feb 12 21:33:45 UTC 2019


Hi,

review appreciated ...

Björn
-------------- next part --------------
From a6ed3378bc543bfa6f415c6c248b5049925a1eb0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj at sernet.de>
Date: Wed, 6 Feb 2019 22:53:00 +0100
Subject: [PATCH 01/13] replace: remove needless vxfs header file check

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 lib/replace/system/filesys.h | 8 --------
 lib/replace/wscript          | 2 +-
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/lib/replace/system/filesys.h b/lib/replace/system/filesys.h
index b9ce41a4b38b..1a8cb68103d2 100644
--- a/lib/replace/system/filesys.h
+++ b/lib/replace/system/filesys.h
@@ -107,14 +107,6 @@
 #include <sys/uio.h>
 #endif
 
-/*
- * Veritas File System.  Often in addition to native.
- * Quotas different.
- */
-#if defined(HAVE_SYS_FS_VX_QUOTA_H)
-#define VXFS_QUOTA
-#endif
-
 #if defined(HAVE_SYS_ATTRIBUTES_H)
 #include <sys/attributes.h>
 #elif defined(HAVE_ATTR_ATTRIBUTES_H)
diff --git a/lib/replace/wscript b/lib/replace/wscript
index a7fd25d15bc1..1d01e1e2b555 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -41,7 +41,7 @@ def configure(conf):
     conf.CHECK_HEADERS('shadow.h sys/acl.h')
     conf.CHECK_HEADERS('sys/attributes.h attr/attributes.h sys/capability.h sys/dir.h sys/epoll.h')
     conf.CHECK_HEADERS('port.h')
-    conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h sys/fs/vx/quota.h')
+    conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h')
     conf.CHECK_HEADERS('sys/id.h sys/ioctl.h sys/ipc.h sys/mman.h sys/mode.h sys/ndir.h sys/priv.h')
     conf.CHECK_HEADERS('sys/resource.h sys/security.h sys/shm.h sys/statfs.h sys/statvfs.h sys/termio.h')
     conf.CHECK_HEADERS('sys/vfs.h sys/xattr.h termio.h termios.h sys/file.h')
-- 
2.17.1


From ff63686635358d6daf20d4e02ac96057d25843a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj at sernet.de>
Date: Thu, 7 Feb 2019 03:35:01 +0100
Subject: [PATCH 02/13] sysquotas_linux: fix inode limit setting, which is not
 depeding on blocksize

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/lib/sysquotas_linux.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/source3/lib/sysquotas_linux.c b/source3/lib/sysquotas_linux.c
index eebb1ad1f8c4..4415f519ce06 100644
--- a/source3/lib/sysquotas_linux.c
+++ b/source3/lib/sysquotas_linux.c
@@ -140,14 +140,12 @@ int sys_set_vfs_quota(const char *path, const char *bdev,
 	if (bsize == dp->bsize) {
 		D.dqb_bsoftlimit = dp->softlimit;
 		D.dqb_bhardlimit = dp->hardlimit;
-		D.dqb_ihardlimit = dp->ihardlimit;
-		D.dqb_isoftlimit = dp->isoftlimit;
 	} else {
 		D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
 		D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
-		D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
-		D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
 	}
+	D.dqb_ihardlimit = dp->ihardlimit;
+	D.dqb_isoftlimit = dp->isoftlimit;
 	D.dqb_valid = QIF_LIMITS;
 
 	switch (qtype) {
-- 
2.17.1


From 94b9692c937d39441a2cef2b68e8c2b1ddc56240 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj at sernet.de>
Date: Thu, 7 Feb 2019 04:23:13 +0100
Subject: [PATCH 03/13] sysquotas_xfs: fix inode limit setting, which is not
 depeding on blocksize

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/lib/sysquotas_xfs.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/source3/lib/sysquotas_xfs.c b/source3/lib/sysquotas_xfs.c
index 8db52bd84593..6b184874435b 100644
--- a/source3/lib/sysquotas_xfs.c
+++ b/source3/lib/sysquotas_xfs.c
@@ -188,14 +188,12 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt
 	if (bsize == dp->bsize) {
 		D.d_blk_softlimit = dp->softlimit;
 		D.d_blk_hardlimit = dp->hardlimit;
-		D.d_ino_hardlimit = dp->ihardlimit;
-		D.d_ino_softlimit = dp->isoftlimit;
 	} else {
 		D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
 		D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
-		D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
-		D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;		
 	}
+	D.d_ino_hardlimit = dp->ihardlimit;
+	D.d_ino_softlimit = dp->isoftlimit;
 
 	qflags = dp->qflags;
 
-- 
2.17.1


From da7df0eb80d4b67583b9064d4d9934a8a87f3b82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj at sernet.de>
Date: Sun, 10 Feb 2019 00:51:23 +0100
Subject: [PATCH 04/13] sysquotas_nfs: also honor reported inode/file limits

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/lib/sysquotas_nfs.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/source3/lib/sysquotas_nfs.c b/source3/lib/sysquotas_nfs.c
index dd2b12d0ffda..14dcb028d0a3 100644
--- a/source3/lib/sysquotas_nfs.c
+++ b/source3/lib/sysquotas_nfs.c
@@ -244,6 +244,9 @@ int sys_get_nfs_quota(const char *path, const char *bdev,
 		dp->softlimit = gq_rslt.GQR_RQUOTA.rq_bsoftlimit;
 		dp->hardlimit = gq_rslt.GQR_RQUOTA.rq_bhardlimit;
 		dp->curblocks = gq_rslt.GQR_RQUOTA.rq_curblocks;
+		dp->isoftlimit = gq_rslt.GQR_RQUOTA.rq_fsoftlimit;
+		dp->ihardlimit = gq_rslt.GQR_RQUOTA.rq_fhardlimit;
+		dp->curinodes = gq_rslt.GQR_RQUOTA.rq_curfiles;
 		break;
 
 	case 2:
-- 
2.17.1


From 9227a6ce2bb1e9b8aa79b80c86715495563168d4 Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Wed, 30 Jan 2019 17:55:06 -0600
Subject: [PATCH 05/13] tests/quota: tidy up includes of sysquotas 4B

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 tests/sysquotas.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/tests/sysquotas.c b/tests/sysquotas.c
index afec3f162446..a90049988295 100644
--- a/tests/sysquotas.c
+++ b/tests/sysquotas.c
@@ -55,12 +55,10 @@ extern int quotactl(int cmd, const char *special, uid_t uid, void *addr);
 
 #ifdef HAVE_SYS_QUOTA_H
 #include <sys/quota.h>
-#else /* *BSD */
-#include <sys/types.h>
+#endif
+
 #ifdef HAVE_UFS_UFS_QUOTA_H
 #include <ufs/ufs/quota.h>
-#endif
-#include <machine/param.h>
 #endif
 
  int autoconf_quota(void)
-- 
2.17.1


From 99f2e23a9b58dffa9f4e54ec97ab29a9aa272541 Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Thu, 31 Jan 2019 12:01:36 -0600
Subject: [PATCH 06/13] sysquotas.h: collect more platform quotablock sizes

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/include/sysquotas.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/source3/include/sysquotas.h b/source3/include/sysquotas.h
index 71d5e9b26401..7ba631e4e76f 100644
--- a/source3/include/sysquotas.h
+++ b/source3/include/sysquotas.h
@@ -69,7 +69,17 @@ typedef struct _SMB_DISK_QUOTA {
 } SMB_DISK_QUOTA;
 
 #ifndef QUOTABLOCK_SIZE
+#if defined(DQBSIZE)                          /* AIX */
+#define QUOTABLOCK_SIZE    DQBSIZE
+#elif defined(QIF_DQBLKSIZE)                  /* Linux */
+#define QUOTABLOCK_SIZE    QIF_DQBLKSIZE
+#elif defined(HAVE_STRUCT_DQBLK_DQB_CURBYTES) /*Darwin */
+#define QUOTABLOCK_SIZE 1
+#elif defined(HAVE_UFS_UFS_QUOTA_H)           /* BSDs */
+#define QUOTABLOCK_SIZE 512
+#else
 #define QUOTABLOCK_SIZE 1024
 #endif
+#endif /* QUOTABLOCK_SIZE */
 
 #endif /*_SYSQUOTAS_H */
-- 
2.17.1


From 9a9a87daab25ee25b079716a0453eab40855cad2 Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Wed, 30 Jan 2019 18:27:12 -0600
Subject: [PATCH 07/13] waf: check for jfs/quota.h

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/wscript | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source3/wscript b/source3/wscript
index 0cd7f40317ac..c6fedf8534eb 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -1403,6 +1403,8 @@ main() {
         conf.CHECK_HEADERS('sys/quota.h')
         # For quotas on BSD systems
         conf.CHECK_HEADERS('ufs/ufs/quota.h')
+        # For quotas on AIX systems
+        conf.CHECK_HEADERS('jfs/quota.h')
         # For quotas on Linux XFS filesystems
         if conf.CHECK_HEADERS('xfs/xqm.h'):
             conf.DEFINE('HAVE_XFS_QUOTAS', '1')
-- 
2.17.1


From e2dcddcc5329cbddb80aea24f8474568a6a57b0f Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Tue, 5 Feb 2019 17:23:35 -0600
Subject: [PATCH 08/13] sysquotas_4B: make quota block calculation adopt to
 platform quota block size

the correct QUOTABLOCK_SIZE for platform is taken from sysquotas.h

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/lib/sysquotas_4B.c | 43 ++++++++++++++++----------------------
 1 file changed, 18 insertions(+), 25 deletions(-)

diff --git a/source3/lib/sysquotas_4B.c b/source3/lib/sysquotas_4B.c
index ee56432211e9..690e765231a3 100644
--- a/source3/lib/sysquotas_4B.c
+++ b/source3/lib/sysquotas_4B.c
@@ -52,6 +52,11 @@
 #define HFS_QUOTACTL_WAR 1
 #endif
 
+#ifdef HAVE_STRUCT_DQBLK_DQB_CURBYTES
+/* we handle the byte vs. block count dynamically via QUOTABLOCK_SIZE 1 */
+#define dqb_curbytes dqb_curblocks
+#endif
+
 static void xlate_qblk_to_smb(const struct dqblk * const qblk,
 			SMB_DISK_QUOTA *dp)
 {
@@ -59,34 +64,22 @@ static void xlate_qblk_to_smb(const struct dqblk * const qblk,
 
 	DEBUG(10, ("unix softlimit=%u hardlimit=%u curblock=%u\n",
 	    (unsigned)qblk->dqb_bsoftlimit, (unsigned)qblk->dqb_bhardlimit,
-#ifdef HAVE_STRUCT_DQBLK_DQB_CURBYTES
-	    (unsigned)qblk->dqb_curbytes));
-#else
 	    (unsigned)qblk->dqb_curblocks));
-#endif
 
 	DEBUGADD(10, ("unix softinodes=%u hardinodes=%u curinodes=%u\n",
 	    (unsigned)qblk->dqb_isoftlimit, (unsigned)qblk->dqb_ihardlimit,
 	    (unsigned)qblk->dqb_curinodes));
 
-#ifdef HAVE_STRUCT_DQBLK_DQB_CURBYTES
-	/* On Darwin, quotas are counted in bytes. We report them
-	 * in 512b blocks because various callers have assumptions
-	 * about the block size.
-	 */
-#define XLATE_TO_BLOCKS(bytes) (((bytes) + 1) / 512)
-	dp->bsize = 512;
-
-	dp->softlimit = XLATE_TO_BLOCKS(qblk->dqb_bsoftlimit);
-	dp->hardlimit = XLATE_TO_BLOCKS(qblk->dqb_bhardlimit);
-	dp->curblocks = XLATE_TO_BLOCKS(qblk->dqb_curbytes);
-#undef XLATE_TO_BLOCKS
-#else
-	dp->bsize = DEV_BSIZE;
+	dp->bsize = QUOTABLOCK_SIZE;
 
 	dp->softlimit = qblk->dqb_bsoftlimit;
 	dp->hardlimit = qblk->dqb_bhardlimit;
 	dp->curblocks = qblk->dqb_curblocks;
+#ifdef HAVE_STRUCT_DQBLK_DQB_CURBYTES
+	/* we want Darwin 0 byte files not to take 0 space, set a minimum of 1 here */
+	if (dp->curblocks == 0) {
+		dp->curblocks = 1;
+	}
 #endif
 
 	dp->ihardlimit = qblk->dqb_ihardlimit;
@@ -110,13 +103,13 @@ static void xlate_smb_to_qblk(const SMB_DISK_QUOTA * const dp,
 {
 	ZERO_STRUCTP(qblk);
 
-	qblk->dqb_bsoftlimit = dp->softlimit;
-	qblk->dqb_bhardlimit = dp->hardlimit;
-#ifdef HAVE_STRUCT_DQBLK_DQB_CURBYTES
-	/* On Darwin, quotas are counted in bytes. */
-	qblk->dqb_bsoftlimit *= dp->bsize;
-	qblk->dqb_bhardlimit *= dp->bsize;
-#endif
+	if (dp->bsize == QUOTABLOCK_SIZE) {
+		qblk->dqb_bsoftlimit = dp->softlimit;
+		qblk->dqb_bhardlimit = dp->hardlimit;
+	} else {
+		qblk->dqb_bsoftlimit = dp->softlimit * dp->bsize / QUOTABLOCK_SIZE;
+		qblk->dqb_bhardlimit = dp->hardlimit * dp->bsize / QUOTABLOCK_SIZE;
+	}
 	qblk->dqb_ihardlimit = dp->ihardlimit;
 	qblk->dqb_isoftlimit = dp->isoftlimit;
 }
-- 
2.17.1


From 60695e97c5daaa4b78e477670913aa598238854e Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Wed, 30 Jan 2019 18:33:55 -0600
Subject: [PATCH 09/13] sysquotas_4B: enable for jfs/quota.h on AIX

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/lib/sysquotas_4B.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source3/lib/sysquotas_4B.c b/source3/lib/sysquotas_4B.c
index 690e765231a3..935560ec62b1 100644
--- a/source3/lib/sysquotas_4B.c
+++ b/source3/lib/sysquotas_4B.c
@@ -47,6 +47,10 @@
 #include <ufs/ufs/quota.h>
 #endif
 
+#ifdef HAVE_JFS_QUOTA_H
+#include <jfs/quota.h>
+#endif
+
 #if defined(DARWINOS)
 /* WorkARound broken HFS access checks in hfs_quotactl. Darwin only(?) */
 #define HFS_QUOTACTL_WAR 1
-- 
2.17.1


From 47b4bf8cb9c427422572f96b76fc65310547fc57 Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Tue, 5 Feb 2019 16:52:33 -0600
Subject: [PATCH 10/13] add sysquotas_jfs2.c

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/include/proto.h      |   3 +
 source3/lib/sysquotas.c      |   3 +
 source3/lib/sysquotas_jfs2.c | 150 +++++++++++++++++++++++++++++++++++
 source3/wscript_build        |   1 +
 4 files changed, 157 insertions(+)
 create mode 100644 source3/lib/sysquotas_jfs2.c

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 9d6192967ba9..93d01a06be0e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -203,6 +203,9 @@ int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt
 int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
 int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
 
+int sys_get_jfs2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
+int sys_set_jfs2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
+
 int sys_get_nfs_quota(const char *path, const char *bdev,
 		      enum SMB_QUOTA_TYPE qtype,
 		      unid_t id, SMB_DISK_QUOTA *dp);
diff --git a/source3/lib/sysquotas.c b/source3/lib/sysquotas.c
index 9b2d37b83759..40b421c056f8 100644
--- a/source3/lib/sysquotas.c
+++ b/source3/lib/sysquotas.c
@@ -227,6 +227,9 @@ static struct {
 	int (*get_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
 	int (*set_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
 } sys_quota_backends[] = {
+#ifdef HAVE_JFS_QUOTA_H
+	{"jfs2", sys_get_jfs2_quota, 	sys_set_jfs2_quota},
+#endif
 #if defined HAVE_XFS_QUOTAS
 	{"xfs", sys_get_xfs_quota, 	sys_set_xfs_quota},
 	{"gfs", sys_get_xfs_quota, 	sys_set_xfs_quota},
diff --git a/source3/lib/sysquotas_jfs2.c b/source3/lib/sysquotas_jfs2.c
new file mode 100644
index 000000000000..999b7e089417
--- /dev/null
+++ b/source3/lib/sysquotas_jfs2.c
@@ -0,0 +1,150 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * System QUOTA function wrappers for JFS2 on AIX
+
+ * Copyright (C) 2019 Bjoern Jacke
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_QUOTA
+
+#if defined(HAVE_JFS_QUOTA_H)
+#include <jfs/quota.h>
+
+#if defined(Q_J2GETQUOTA) /* when have JFS2 */
+
+/* int quotactl(const char *path, int cmd, int id, char *addr)
+ *
+ * This is very similar to sysquotas_4B but JFS2 has different quota cmds
+ * (why?) and for some reason wants root even for querying your own quota,
+ * which seems to be an AIX bug because the docs say root is only
+ * required for querying other users' quota
+ */
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_JFS_QUOTA_H
+#include <jfs/quota.h>
+#endif
+
+
+static int sys_quotactl_JFS2(const char * path, int cmd,
+		int id, quota64_t *quota)
+{
+	int ret;
+
+	/* NB: We must test GRPQUOTA here, because USRQUOTA is 0. */
+	DEBUG(10, ("%s quota for %s ID %u on %s\n",
+		    (cmd & QCMD(Q_J2GETQUOTA, 0)) ? "getting" : "setting",
+		    (cmd & QCMD(0, GRPQUOTA)) ? "group" : "user",
+		    (unsigned)id, path));
+
+	become_root();
+
+	ret = quotactl((char *) path, cmd, id, (char *) quota);
+	if (ret == -1) {
+		/* ENOTSUP means quota support is not compiled in. EINVAL
+		 * means that quotas are not configured (commonly).
+		 */
+		if (errno != ENOTSUP && errno != EINVAL) {
+			DEBUG(0, ("failed to %s quota for %s ID %u on %s: %s\n",
+				    (cmd & QCMD(Q_J2GETQUOTA, 0)) ? "get" : "set",
+				    (cmd & QCMD(0, GRPQUOTA)) ? "group" : "user",
+				    (unsigned)id, path, strerror(errno)));
+		}
+	}
+
+	unbecome_root();
+
+	return ret;
+}
+
+
+int sys_get_jfs2_quota(const char *path, const char *bdev,
+	enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
+{
+	int ret;
+	quota64_t quota;
+
+	ZERO_STRUCT(quota);
+
+	switch (qtype) {
+	case SMB_USER_QUOTA_TYPE:
+		/* Get quota for provided UID. */
+		ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, USRQUOTA),
+					id.uid, &quota);
+		break;
+	case SMB_USER_FS_QUOTA_TYPE:
+		/* Get quota for current UID. */
+		ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, USRQUOTA),
+					geteuid(), &quota);
+		break;
+	case SMB_GROUP_QUOTA_TYPE:
+		/* Get quota for provided GID. */
+		ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, GRPQUOTA),
+					id.gid, &quota);
+		break;
+	case SMB_GROUP_FS_QUOTA_TYPE:
+		/* Get quota for current GID. */
+		ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, GRPQUOTA),
+					getegid(), &quota);
+		break;
+	default:
+		DEBUG(0, ("cannot get unsupported quota type: %u\n",
+			    (unsigned)qtype));
+		errno = ENOSYS;
+		return -1;
+	}
+
+	if (ret == -1) {
+		return -1;
+	}
+
+	dp->softlimit = quota.bsoft;
+	dp->hardlimit = quota.bhard;
+	dp->ihardlimit = quota.ihard;
+	dp->isoftlimit = quota.isoft;
+	dp->curinodes = quota.iused;
+	dp->curblocks = quota.bused;
+
+	dp->qflags = QUOTAS_ENABLED | QUOTAS_DENY_DISK;
+	dp->qtype = qtype;
+	dp->bsize = QUOTABLOCK_SIZE;
+
+	return ret;
+}
+
+int sys_set_jfs2_quota(const char *path, const char *bdev,
+	enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
+{
+	/* JFS2 supports fancy quota limit classes for setting user quota.
+	 * Unfortunately, this makes them quite unmanagable for Samba.
+	 */
+	DEBUG(1, ("cannot set quota on JFS2!\n"));
+	errno = ENOSYS;
+	return -1;
+}
+
+
+#endif /* JFS2 */
+#endif /* AIX quotas */
diff --git a/source3/wscript_build b/source3/wscript_build
index 11c877818c2f..8ddda887138c 100644
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -610,6 +610,7 @@ bld.SAMBA3_SUBSYSTEM('sysquotas',
                         lib/sysquotas_xfs.c
                         lib/sysquotas_4A.c
                         lib/sysquotas_4B.c
+                        lib/sysquotas_jfs2.c
                         lib/sysquotas_nfs.c
                      ''',
                      allow_warnings=True,
-- 
2.17.1


From aa74da54fb1990a22e6f57773ffc19de29dfcc84 Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Wed, 30 Jan 2019 18:35:55 -0600
Subject: [PATCH 11/13] tests/sysquotas.c: include jfs/quota.h for 4B test on
 AIX

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 tests/sysquotas.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tests/sysquotas.c b/tests/sysquotas.c
index a90049988295..973b9f4f76a3 100644
--- a/tests/sysquotas.c
+++ b/tests/sysquotas.c
@@ -59,6 +59,10 @@ extern int quotactl(int cmd, const char *special, uid_t uid, void *addr);
 
 #ifdef HAVE_UFS_UFS_QUOTA_H
 #include <ufs/ufs/quota.h>
+#endif
+
+#if defined(HAVE_JFS_QUOTA_H)
+#include <jfs/quota.h>
 #endif
 
  int autoconf_quota(void)
-- 
2.17.1


From d5ca365b06de35b2289560da72a45199535461ad Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Wed, 30 Jan 2019 21:57:38 -0600
Subject: [PATCH 12/13] quotas: remove legacy AIX quota code that is covered by
 sysquotas now

Signed-off-by: Bjoern Jacke <bjacke at samba.org>
---
 source3/smbd/quotas.c | 122 ------------------------------------------
 1 file changed, 122 deletions(-)

diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c
index 2f18e368b175..c9472682f8fe 100644
--- a/source3/smbd/quotas.c
+++ b/source3/smbd/quotas.c
@@ -335,128 +335,6 @@ bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
 	return true;
 }
 
-
-#else /* not Solaris */
-
-#if           AIX
-/* AIX quota patch from Ole Holm Nielsen <ohnielse at fysik.dtu.dk> */
-#include <jfs/quota.h>
-/* AIX 4.X: Rename members of the dqblk structure (ohnielse at fysik.dtu.dk) */
-#define dqb_curfiles dqb_curinodes
-#define dqb_fhardlimit dqb_ihardlimit
-#define dqb_fsoftlimit dqb_isoftlimit
-#ifdef _AIXVERSION_530 
-#include <sys/statfs.h>
-#include <sys/vmount.h>
-#endif /* AIX 5.3 */
-#else /* !AIX */
-#include <sys/quota.h>
-#include <devnm.h>
-#endif
-
-
-/****************************************************************************
-try to get the disk space from disk quotas - default version
-****************************************************************************/
-
-bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
-		 uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
-{
-  int r;
-  struct dqblk D;
-  uid_t euser_id;
-  const char *path = fname->base_name;
-#if !defined(AIX)
-  char dev_disk[256];
-  SMB_STRUCT_STAT S = fname->st;
-
-  /* find the block device file */
-
-  if ((sys_stat(path, &S, false)<0)
-      || (devnm(S_IFBLK, S.st_ex_dev, dev_disk, 256, 0)<0))
-	return (False);
-
-#endif /* !defined(AIX) */
-
-  euser_id = geteuid();
-
-#if   defined(AIX)
-  /* AIX has both USER and GROUP quotas: 
-     Get the USER quota (ohnielse at fysik.dtu.dk) */
-#ifdef _AIXVERSION_530
-  {
-    struct statfs statbuf;
-    quota64_t user_quota;
-    if (statfs(path,&statbuf) != 0)
-      return False;
-    if(statbuf.f_vfstype == MNT_J2)
-    {
-    /* For some reason we need to be root for jfs2 */
-      become_root();
-      r = quotactl(path,QCMD(Q_J2GETQUOTA,USRQUOTA),euser_id,(char *) &user_quota);
-      unbecome_root();
-    /* Copy results to old struct to let the following code work as before */
-      D.dqb_curblocks  = user_quota.bused;
-      D.dqb_bsoftlimit = user_quota.bsoft;
-      D.dqb_bhardlimit = user_quota.bhard;
-      D.dqb_curfiles   = user_quota.iused;
-      D.dqb_fsoftlimit = user_quota.isoft;
-      D.dqb_fhardlimit = user_quota.ihard;
-    }
-    else if(statbuf.f_vfstype == MNT_JFS)
-    {
-#endif /* AIX 5.3 */
-  save_re_uid();
-  if (set_re_uid() != 0) 
-    return False;
-  r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
-  restore_re_uid();
-#ifdef _AIXVERSION_530
-    }
-    else
-      r = 1; /* Fail for other FS-types */
-  }
-#endif /* AIX 5.3 */
-#else /* !AIX */
-  r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
-#endif /* !AIX */
-
-  /* Use softlimit to determine disk space, except when it has been exceeded */
-  *bsize = 1024;
-
-  if (r)
-    {
-      if (errno == EDQUOT) 
-	{
- 	  *dfree =0;
- 	  *dsize =D.dqb_curblocks;
- 	  return (True);
-	}
-      else return(False);
-    }
-
-  /* If softlimit is zero, set it equal to hardlimit.
-   */
-
-  if (D.dqb_bsoftlimit==0)
-    D.dqb_bsoftlimit = D.dqb_bhardlimit;
-
-  if (D.dqb_bsoftlimit==0)
-    return(False);
-  /* Use softlimit to determine disk space, except when it has been exceeded */
-  if ((D.dqb_curblocks>D.dqb_bsoftlimit)
-||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0))
-    ) {
-      *dfree = 0;
-      *dsize = D.dqb_curblocks;
-    }
-  else {
-    *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
-    *dsize = D.dqb_bsoftlimit;
-  }
-  return (True);
-}
-
 #endif /* Solaris */
 
 #else /* WITH_QUOTAS */
-- 
2.17.1


From 4d85553b23b862642d948acaa48ee98201fbb4d0 Mon Sep 17 00:00:00 2001
From: Bjoern Jacke <bj at sernet.de>
Date: Thu, 31 Jan 2019 15:30:31 -0600
Subject: [PATCH 13/13] quotas: honor group quota if this is lower than
 existing user quota

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13769
---
 source3/smbd/quotas.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c
index c9472682f8fe..d3b1cf7d8a91 100644
--- a/source3/smbd/quotas.c
+++ b/source3/smbd/quotas.c
@@ -364,6 +364,7 @@ bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
 	int r;
 	SMB_DISK_QUOTA D;
 	unid_t id;
+	bool ret_user_quota = false;
 
 	/*
 	 * First of all, check whether user quota is
@@ -428,7 +429,7 @@ bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
 		*dsize = D.softlimit;
 	}
 
-	return True;
+	ret_user_quota = true;
 	
 try_group_quota:
 	/*
@@ -441,10 +442,10 @@ try_group_quota:
 	r = SMB_VFS_GET_QUOTA(conn, fname, SMB_GROUP_FS_QUOTA_TYPE,
 			      id, &D);
 	if (r == -1 && errno != ENOSYS) {
-		return false;
+		return ret_user_quota;
 	}
 	if (r == 0 && (D.qflags & QUOTAS_DENY_DISK) == 0) {
-		return false;
+		return ret_user_quota;
 	}
 
 	id.gid = getegid();
@@ -454,7 +455,7 @@ try_group_quota:
 			      &D);
 
 	if (r == -1) {
-		return False;
+		return ret_user_quota;
 	}
 
 	*bsize = D.bsize;
@@ -468,15 +469,18 @@ try_group_quota:
 		*dfree = 0;
 		*dsize = D.curblocks;
 	} else if (D.softlimit==0 && D.hardlimit==0) {
-		return False;
+		return ret_user_quota;
 	} else {
 		if (D.softlimit == 0) {
 			D.softlimit = D.hardlimit;
 		}
-		*dfree = D.softlimit - D.curblocks;
-		*dsize = D.softlimit;
+		/* let's see if user quota or group quota is more limiting: */
+		if (*dsize > D.softlimit) {
+			*dfree = D.softlimit - D.curblocks;
+			*dsize = D.softlimit;
+		}
 	}
 
-	return (True);
+	return (true);
 }
 #endif /* HAVE_SYS_QUOTAS */
-- 
2.17.1



More information about the samba-technical mailing list