Quota GPFS

Juan Carlos Sanchez-DelBarrio carlos.sanchez at bsc.es
Mon Oct 27 22:58:47 GMT 2008


Hi everybody,

I suggest the following patch for quota support over GPFS. I have 
compiled and linked the binaries using the following procedure:

1) tar zxf samba-latest.tar.gz
2) export LIBS="-lgpfs"
3) cd samba-XXXX
4) patch -p0 < gpfs-quota.patch
5) cd source
6) sh ./autogen.sh
7) ./configure --with-quotas ...
8) make && make install


Best regards,
Juan C. Sanchez-DelBarrio
Security Officer
BSC-CNS
http://www.bsc.es

-------------- next part --------------
diff -Nur ../samba-3.2.4/source/Makefile.in ./source/Makefile.in
--- ../samba-3.2.4/source/Makefile.in	2008-09-18 08:49:02.000000000 +0200
+++ ./source/Makefile.in	2008-10-27 21:27:34.472514000 +0100
@@ -639,7 +639,7 @@
                smbd/posix_acls.o lib/sysacls.o $(SERVER_MUTEX_OBJ) \
 	       smbd/process.o smbd/service.o smbd/error.o \
 	       printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
-	       lib/sysquotas_xfs.o lib/sysquotas_4A.o \
+	       lib/sysquotas_xfs.o lib/sysquotas_gpfs.o lib/sysquotas_4A.o \
 	       smbd/change_trust_pw.o smbd/fake_file.o \
 	       smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
 	       $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
diff -Nur ../samba-3.2.4/source/configure.in ./source/configure.in
--- ../samba-3.2.4/source/configure.in	2008-09-18 08:49:02.000000000 +0200
+++ ./source/configure.in	2008-10-27 22:33:47.799523000 +0100
@@ -4454,6 +4454,11 @@
 	    samba_cv_found_xfs_header=yes
 	    AC_MSG_CHECKING(whether to use the lib/sysquotas_xfs.c builtin support)
 	    AC_MSG_RESULT(yes)
+
+	    AC_DEFINE(HAVE_LINUX_GPFS_QUOTAS,1,[Whether Linux gpfs quota support is available])
+	    samba_cv_found_gpfs_header=yes
+	    AC_MSG_CHECKING(whether to use the lib/sysquotas_gpfs.c builtin support)
+	    AC_MSG_RESULT(yes)
 	    ;;
 	*solaris*)
 	    # need to set this define when using static linking (BUG 1473)
@@ -4478,6 +4483,9 @@
 # For sys/quota.h and linux/quota.h
 AC_CHECK_HEADERS(sys/quota.h)
 
+# For gpfs 
+AC_CHECK_HEADERS(gpfs.h)
+
 if test x"$samba_cv_found_xfs_header" != x"yes"; then
 # if we have xfs quota support <sys/quota.h> (IRIX) we should use it
 AC_CACHE_CHECK([for XFS QUOTA in <sys/quota.h>],samba_cv_HAVE_SYS_QUOTA_XFS, [
@@ -4497,6 +4505,25 @@
 fi
 fi
 
+if test x"$samba_cv_found_gpfs_header" != x"yes"; then
+# if we have gpfs quota support <gpfs.h> (IRIX) we should use it
+AC_CACHE_CHECK([for GPFS QUOTA in <gpfs.h>],samba_cv_HAVE_SYS_QUOTA_GPFS, [
+AC_TRY_COMPILE([
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#include <gpfs.h>
+],[int i =  Q_GETQUOTA;],
+samba_cv_HAVE_SYS_QUOTA_GPFS=yes,samba_cv_HAVE_SYS_QUOTA_GPFS=no)])
+if test "$samba_cv_HAVE_SYS_QUOTA_GPFS"x = "yes"x; then
+        samba_cv_found_gpfs_header=yes
+fi
+fi
+
 # if we have struct dqblk .dqb_fsoftlimit instead of .dqb_isoftlimit on IRIX
 AC_CACHE_CHECK([if struct dqblk has .dqb_fsoftlimit],samba_cv_HAVE_DQB_FSOFTLIMIT, [
 AC_TRY_COMPILE([
@@ -4639,6 +4666,27 @@
 fi
 fi
 
+if test x"$samba_cv_SYSQUOTA_FOUND" != x"no" -a x"$samba_cv_found_gpfs_header" = x"yes"; then
+AC_CACHE_CHECK([whether the sys_quota interface works with GPFS],samba_cv_SYSQUOTA_WORKS_GPFS,[
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}"
+AC_TRY_COMPILE([
+#include "confdefs.h"
+#define NO_PROTO_H 1
+#define NO_CONFIG_H 1
+#define HAVE_SYS_QUOTAS 1
+#define HAVE_GPFS_QUOTAS 1
+#include "${srcdir-.}/lib/sysquotas_gpfs.c"
+],[],samba_cv_SYSQUOTA_WORKS_GPFS=yes,samba_cv_SYSQUOTA_WORKS_GPFS=no)
+CPPFLAGS="$SAVE_CPPFLAGS"
+])
+if test x"$samba_cv_SYSQUOTA_WORKS_GPFS" = x"yes"; then
+    if test x"$samba_cv_WE_USE_SYS_QUOTAS" = x"yes"; then
+        AC_DEFINE(HAVE_GPFS_QUOTAS,1,[Whether gpfs quota support is available])
+    fi
+fi
+fi
+
 AC_CACHE_CHECK([whether the old quota support works],samba_cv_QUOTA_WORKS,[
 SAVE_CPPFLAGS="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}"
diff -Nur ../samba-3.2.4/source/include/config.h.in ./source/include/config.h.in
--- ../samba-3.2.4/source/include/config.h.in	2008-09-18 13:58:36.000000000 +0200
+++ ./source/include/config.h.in	2008-10-27 22:39:40.000000000 +0100
@@ -694,6 +694,12 @@
 /* Whether GPFS GPL libs are available */
 #undef HAVE_GPFS
 
+/* Define to 1 if you have the <gpfs.h> header file. */
+#undef HAVE_GPFS_H
+
+/* Whether gpfs quota support is available */
+#undef HAVE_GPFS_QUOTAS
+
 /* Define to 1 if you have the `grantpt' function. */
 #undef HAVE_GRANTPT
 
@@ -1146,6 +1152,9 @@
 /* Define to 1 if you have the <linux/dqblk_xfs.h> header file. */
 #undef HAVE_LINUX_DQBLK_XFS_H
 
+/* Whether Linux gpfs quota support is available */
+#undef HAVE_LINUX_GPFS_QUOTAS
+
 /* Define to 1 if you have the <linux/inotify.h> header file. */
 #undef HAVE_LINUX_INOTIFY_H
 
@@ -2553,7 +2562,7 @@
 /* Shared library extension */
 #undef SHLIBEXT
 
-/* The size of `char', as computed by sizeof. */
+/* The size of a `char', as computed by sizeof. */
 #undef SIZEOF_CHAR
 
 /* The size of the 'dev_t' type */
@@ -2562,31 +2571,31 @@
 /* The size of the 'ino_t' type */
 #undef SIZEOF_INO_T
 
-/* The size of `int', as computed by sizeof. */
+/* The size of a `int', as computed by sizeof. */
 #undef SIZEOF_INT
 
-/* The size of `long', as computed by sizeof. */
+/* The size of a `long', as computed by sizeof. */
 #undef SIZEOF_LONG
 
-/* The size of `long long', as computed by sizeof. */
+/* The size of a `long long', as computed by sizeof. */
 #undef SIZEOF_LONG_LONG
 
 /* The size of the 'off_t' type */
 #undef SIZEOF_OFF_T
 
-/* The size of `short', as computed by sizeof. */
+/* The size of a `short', as computed by sizeof. */
 #undef SIZEOF_SHORT
 
-/* The size of `size_t', as computed by sizeof. */
+/* The size of a `size_t', as computed by sizeof. */
 #undef SIZEOF_SIZE_T
 
-/* The size of `ssize_t', as computed by sizeof. */
+/* The size of a `ssize_t', as computed by sizeof. */
 #undef SIZEOF_SSIZE_T
 
 /* The size of the 'time_t' type */
 #undef SIZEOF_TIME_T
 
-/* The size of `void *', as computed by sizeof. */
+/* The size of a `void *', as computed by sizeof. */
 #undef SIZEOF_VOID_P
 
 /* Use socket wrapper library */
@@ -2809,9 +2818,6 @@
 #ifndef _POSIX_PTHREAD_SEMANTICS
 # undef _POSIX_PTHREAD_SEMANTICS
 #endif
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
 
 /* Whether to build auth_builtin as shared module */
 #undef auth_builtin_init
@@ -2906,7 +2912,7 @@
 /* Whether to build nss_info_template as shared module */
 #undef nss_info_template_init
 
-/* Define to `long int' if <sys/types.h> does not define. */
+/* Define to `long' if <sys/types.h> does not define. */
 #undef off_t
 
 /* Define to `loff_t' if <sys/types.h> does not define. */
@@ -2969,7 +2975,7 @@
 /* Whether to build rpc_wkssvc as shared module */
 #undef rpc_wkssvc_init
 
-/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* Define to `unsigned' if <sys/types.h> does not define. */
 #undef size_t
 
 /* Define to `int' if <sys/types.h> does not define. */
diff -Nur ../samba-3.2.4/source/lib/sysquotas.c ./source/lib/sysquotas.c
--- ../samba-3.2.4/source/lib/sysquotas.c	2008-09-18 08:49:02.000000000 +0200
+++ ./source/lib/sysquotas.c	2008-10-27 22:01:34.863978000 +0100
@@ -177,6 +177,9 @@
 #ifdef HAVE_XFS_QUOTAS
 	{"xfs", sys_get_xfs_quota, 	sys_set_xfs_quota},
 #endif /* HAVE_XFS_QUOTAS */
+#ifdef HAVE_GPFS_QUOTAS
+	{"gpfs", sys_get_gpfs_quota, 	sys_set_gpfs_quota},
+#endif /* HAVE_GPFS */
 	{NULL, 	NULL, 			NULL}
 };
 
diff -Nur ../samba-3.2.4/source/lib/sysquotas_gpfs.c ./source/lib/sysquotas_gpfs.c
--- ../samba-3.2.4/source/lib/sysquotas_gpfs.c	1970-01-01 01:00:00.000000000 +0100
+++ ./source/lib/sysquotas_gpfs.c	2008-10-27 22:15:48.323768000 +0100
@@ -0,0 +1,214 @@
+/* 
+   Unix SMB/CIFS implementation.
+   System QUOTA function wrappers for QUOTACTL_GPFS
+   Copyright (C) Juan Carlos Sanchez	2008
+   
+   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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_QUOTA
+
+#ifdef HAVE_GPFS_QUOTAS
+
+#include <gpfs.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+
+#ifndef QUOTABLOCK_SIZE
+#define QUOTABLOCK_SIZE DEV_BSIZE
+#endif
+
+/****************************************************************************
+ Abstract out the quotactl_gpfs get calls.
+****************************************************************************/
+int sys_get_gpfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
+{
+	int ret = -1;
+	uint32 qflags = 0;
+	struct gpfs_quotaInfo D;
+	SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
+
+	ZERO_STRUCT(D);
+	ZERO_STRUCT(*dp);
+	dp->qtype = qtype;
+
+	switch (qtype) {
+		case SMB_USER_QUOTA_TYPE:
+			DEBUG(10,("sys_get_gpfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
+				path, bdev, (unsigned)id.uid));
+
+			if ((ret = gpfs_quotactl((char *)path, QCMD(Q_GETQUOTA,GPFS_USRQUOTA), id.uid, (void *)&D))&&errno != EDQUOT) {
+				return ret;
+			}
+
+			if ((D.blockUsage==0)&&
+				(D.blockSoftLimit==0)&&
+				(D.blockHardLimit==0)) {
+				/* the upper layer functions don't want empty quota records...*/
+				return -1;
+			}
+
+			break;
+		case SMB_GROUP_QUOTA_TYPE:
+			DEBUG(10,("sys_get_gpfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
+				path, bdev, (unsigned)id.gid));
+
+			if ((ret = gpfs_quotactl((char *)path, QCMD(Q_GETQUOTA,GPFS_GRPQUOTA), id.gid, (void *)&D))&&errno != EDQUOT) {
+				return ret;
+			}
+
+			if ((D.blockUsage==0)&&
+				(D.blockSoftLimit==0)&&
+				(D.blockHardLimit==0)) {
+				/* the upper layer functions don't want empty quota records...*/
+				return -1;
+			}
+
+			break;
+		case SMB_USER_FS_QUOTA_TYPE:
+			id.uid = getuid();
+
+			DEBUG(10,("sys_get_gpfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
+				path, (caddr_t)bdev, (unsigned)id.uid));
+
+			if ((ret = gpfs_quotactl((char *)path, QCMD(Q_GETQUOTA,GPFS_USRQUOTA), id.uid, (void *)&D))==0) {
+				qflags |= QUOTAS_DENY_DISK;
+			}
+
+			ret = 0;
+			break;
+		case SMB_GROUP_FS_QUOTA_TYPE:
+			id.gid = getgid();
+
+			DEBUG(10,("sys_get_gpfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
+				path, bdev, (unsigned)id.gid));
+
+			if ((ret = gpfs_quotactl((char *)path, QCMD(Q_GETQUOTA,GPFS_GRPQUOTA), id.gid, (void *)&D))==0) {
+				qflags |= QUOTAS_DENY_DISK;
+			}
+
+			ret = 0;
+			break;
+		default:
+			errno = ENOSYS;
+			return -1;
+	}
+
+	dp->bsize = bsize;
+	dp->softlimit = (SMB_BIG_UINT)D.blockSoftLimit;
+	dp->hardlimit = (SMB_BIG_UINT)D.blockHardLimit;
+	dp->ihardlimit = (SMB_BIG_UINT)D.inodeHardLimit;
+	dp->isoftlimit = (SMB_BIG_UINT)D.inodeSoftLimit;
+	dp->curinodes = (SMB_BIG_UINT)D.inodeUsage;
+	dp->curblocks = (SMB_BIG_UINT)D.blockUsage;
+
+
+	dp->qflags = qflags;
+
+	return ret;
+}
+
+/****************************************************************************
+ Abstract out the quotactl_gpfs set calls.
+****************************************************************************/
+int sys_set_gpfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
+{
+	int ret = -1;
+	uint32 qflags = 0;
+	uint32 oldqflags = 0;
+	struct gpfs_quotaInfo D;
+	SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
+
+	ZERO_STRUCT(D);
+
+	if (bsize == dp->bsize) {
+		D.blockSoftLimit = dp->softlimit;
+		D.blockHardLimit = dp->hardlimit;
+		D.inodeHardLimit = dp->ihardlimit;
+		D.inodeSoftLimit = dp->isoftlimit;
+	} else {
+		D.blockSoftLimit = (dp->softlimit*dp->bsize)/bsize;
+		D.blockHardLimit = (dp->hardlimit*dp->bsize)/bsize;
+		D.inodeHardLimit = (dp->ihardlimit*dp->bsize)/bsize;
+		D.inodeSoftLimit = (dp->isoftlimit*dp->bsize)/bsize;
+	}
+
+	qflags = dp->qflags;
+
+	switch (qtype) {
+		case SMB_USER_QUOTA_TYPE:
+			DEBUG(10,("sys_set_gpfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
+				path, bdev, (unsigned)id.uid));
+
+			ret = gpfs_quotactl((char *)path, QCMD(Q_SETQLIM,GPFS_USRQUOTA), id.uid, (void *)&D);
+			break;
+		case SMB_GROUP_QUOTA_TYPE:
+			DEBUG(10,("sys_set_gpfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
+				path, bdev, (unsigned)id.gid));
+
+			ret = gpfs_quotactl((char *)path, QCMD(Q_SETQLIM,GPFS_GRPQUOTA), id.gid, (void *)&D);
+			break;
+		case SMB_USER_FS_QUOTA_TYPE:
+			id.uid = getuid();
+			DEBUG(10,("sys_set_gpfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
+				path, bdev, (unsigned)id.uid));
+
+			if ((ret = gpfs_quotactl((char *)path, QCMD(Q_GETQUOTA,GPFS_USRQUOTA), id.uid, (void *)&D))==0) {
+				oldqflags |= QUOTAS_DENY_DISK;
+			}
+
+			if (oldqflags == qflags) {
+				ret = 0;
+			} else {
+				ret = -1;
+			}
+			break;
+		case SMB_GROUP_FS_QUOTA_TYPE:
+			id.gid = getgid();
+			DEBUG(10,("sys_set_gpfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
+				path, bdev, (unsigned)id.gid));
+
+			if ((ret = gpfs_quotactl((char *)path, QCMD(Q_GETQUOTA,GPFS_GRPQUOTA), id.gid, (void *)&D))==0) {
+				oldqflags |= QUOTAS_DENY_DISK;
+			}
+
+			if (oldqflags == qflags) {
+				ret = 0;
+			} else {
+				ret = -1;
+			}
+			break;
+		default:
+			errno = ENOSYS;
+			return -1;
+	}
+
+	return ret;
+}
+
+#else /* HAVE_QUOTACTL_GPFS */
+ void dummy_sysquotas_gpfs(void);
+
+ void dummy_sysquotas_gpfs(void){}
+#endif /* HAVE_QUOTACTL_GPFS */


More information about the samba-cvs mailing list