[Samba] Re: Problems compiling Samba 2.2.4 with quota under Debian stable

Christoph Hellwig hch at infradead.org
Wed May 29 12:49:02 GMT 2002


On Wed, May 29, 2002 at 12:17:17PM -0700, Jeremy Allison wrote:
> If this is the "magic" include file that is guarenteed to 
> work across all Linux distributions and kernels why isn't
> in in /usr/include/quota.h ?

Glibc politics :P

> You must understand I don't care about the glibc or Linux 
> politics, I just see a UNIX with a broken feature that isn't
> broken on other UNIXes.
> 
> I'm happy to add a header file for a particular system especially
> as it is a major platform like Linux, but it's a pain to do so
> and we've been trying to move away from platform specific files
> for *years*. Your attitude of "go looking for something to fix
> *my* platform", frankly sucks.

I complety agree with the pain this causes and I agree with you
that it would be much better if we could avoid it.  From a kernel
hackers side on the other hand I also have to tell you that including
kernel headers directly will cause you much more pain in the long-term.

> Popular supported commerical Linux platforms like RedHat and
> SuSE already ship with working quota support, and when we binary
> package on them Samba works fine. Debian (of course) has to be
> different.

The problem is that the stock Linux 2.4 quota support is a) not
32bit UID save and is (or at least was for a long time) very broken.

Debian has some strange policy to not include major patches in their
kernel packages which is usually a rather bad idea, especially in this
case.  (and when you see how they patch their gcc or XFree packages it
also is inconsistant with themselves).

The real problem is of course that the mainline quota is out of date,
and because the new quota code was neither ondisk nor user-interface
compatible with the old code it couldn't be updated in the 2.4 series.
Jan's new code fixes this problem and I really, really hope it will
show up in one of the next 2.4 kernels after it got testing in the
unstable series.

> If you want it to work on your particular platform a little more
> cooperation would be appreciated.

Is this constructive enough?


diff -uNr samba-2.2.4/source/configure.in samba-2.2.4-hch/source/configure.in
--- samba-2.2.4/source/configure.in	Fri May  3 03:02:46 2002
+++ samba-2.2.4-hch/source/configure.in	Wed May 29 22:03:53 2002
@@ -2221,26 +2221,6 @@
   yes)
     AC_MSG_RESULT(yes)
     QUOTAOBJS=smbd/quotas.o
-    case "$host_os" in
-      *linux*)
-        # Check for kernel 2.4.x quota braindamage...
-	AC_CACHE_CHECK([for linux 2.4.x quota braindamage..],samba_cv_linux_2_4_quota_braindamage, [
-        AC_TRY_COMPILE([#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <linux/quota.h>
-#include <mntent.h>
-#include <linux/unistd.h>],[struct mem_dqblk D;],
-	samba_cv_linux_2_4_quota_braindamage=yes,samba_cv_linux_2_4_quota_braindamage=no)])
-if test x"$samba_cv_linux_2_4_quota_braindamage" = x"yes"; then
-        AC_DEFINE(LINUX_QUOTAS_2)
-else
-        AC_DEFINE(LINUX_QUOTAS_1)
-fi
-        ;;
-      *)
-        ;;
-    esac
     ;;
   *)
     AC_MSG_RESULT(no)
diff -uNr samba-2.2.4/source/smbd/dqblk_rpc.h samba-2.2.4-hch/source/smbd/dqblk_rpc.h
--- samba-2.2.4/source/smbd/dqblk_rpc.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/dqblk_rpc.h	Wed May 29 22:01:05 2002
@@ -0,0 +1,20 @@
+/*
+ *	Headerfile for rpc quotafile format
+ */
+
+#ifndef _DQBLK_RPC_H
+#define _DQBLK_RPC_H
+
+/* Values used for communication through network */
+#define Q_RPC_GETQUOTA	0x0300	/* get limits and usage */
+#define Q_RPC_SETQUOTA	0x0400	/* set limits and usage */
+#define Q_RPC_SETUSE	0x0500	/* set usage */
+#define Q_RPC_SETQLIM	0x0700	/* set limits */
+
+#define RPC_DQBLK_SIZE_BITS 10
+#define RPC_DQBLK_SIZE (1 << RPC_DQBLK_SIZE_BITS)
+
+/* Operations above this format */
+extern struct quotafile_ops quotafile_ops_rpc;
+
+#endif
diff -uNr samba-2.2.4/source/smbd/dqblk_v1.h samba-2.2.4-hch/source/smbd/dqblk_v1.h
--- samba-2.2.4/source/smbd/dqblk_v1.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/dqblk_v1.h	Wed May 29 22:01:05 2002
@@ -0,0 +1,21 @@
+/*
+ *	Headerfile for old quotafile format
+ */
+
+#ifndef _DQBLK_V1_H
+#define _DQBLK_V1_H
+
+/* Values of quota calls */
+#define Q_V1_RSQUASH	0x1000
+#define Q_V1_GETQUOTA	0x300
+#define Q_V1_SETQUOTA	0x400
+#define Q_V1_SETUSE	0x500
+#define Q_V1_SETQLIM	0x700
+#define Q_V1_GETSTATS	0x800
+
+struct quotafile_ops;		/* Will be defined later in quotaio.h */
+
+/* Operations above this format */
+extern struct quotafile_ops quotafile_ops_1;
+
+#endif
diff -uNr samba-2.2.4/source/smbd/dqblk_v2.h samba-2.2.4-hch/source/smbd/dqblk_v2.h
--- samba-2.2.4/source/smbd/dqblk_v2.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/dqblk_v2.h	Wed May 29 22:01:05 2002
@@ -0,0 +1,41 @@
+/*
+ *
+ *	Header file for disk format of new quotafile format
+ *
+ */
+
+#ifndef _DQBLK_V2_H
+#define _DQBLK_V2_H
+
+#include <sys/types.h>
+
+#define Q_V2_GETQUOTA	0x0D00	/* Get limits and usage */
+#define Q_V2_SETQUOTA	0x0E00	/* Set limits and usage */
+#define Q_V2_SETUSE	0x0F00	/* Set only usage */
+#define Q_V2_SETQLIM	0x0700	/* Set only limits */
+#define Q_V2_GETINFO	0x0900	/* Get information about quota */
+#define Q_V2_SETINFO	0x0A00	/* Set information about quota */
+#define Q_V2_SETGRACE	0x0B00	/* Set just grace times in quotafile information */
+#define Q_V2_SETFLAGS	0x0C00	/* Set just flags in quotafile information */
+#define Q_V2_GETSTATS	0x1100	/* get collected stats (before proc was used) */
+
+/* Structure for format specific information */
+struct v2_mem_dqinfo {
+	uint dqi_flags;		/* Flags set in quotafile */
+	uint dqi_blocks;	/* Number of blocks in file */
+	uint dqi_free_blk;	/* Number of first free block in the list */
+	uint dqi_free_entry;	/* Number of first block with free entry in the list */
+	uint dqi_used_entries;	/* Number of entries in file - updated by scan_dquots */
+	uint dqi_data_blocks;	/* Number of data blocks in file - updated by scan_dquots */
+};
+
+struct v2_mem_dqblk {
+	loff_t dqb_off;		/* Offset of dquot in file */
+};
+
+struct quotafile_ops;		/* Will be defined later in quotaio.h */
+
+/* Operations above this format */
+extern struct quotafile_ops quotafile_ops_2;
+
+#endif
diff -uNr samba-2.2.4/source/smbd/dqblk_xfs.h samba-2.2.4-hch/source/smbd/dqblk_xfs.h
--- samba-2.2.4/source/smbd/dqblk_xfs.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/dqblk_xfs.h	Wed May 29 22:01:05 2002
@@ -0,0 +1,25 @@
+/*
+ *	Headerfile for XFS quota format
+ */
+
+#ifndef _DQBLK_XFS_H
+#define _DQBLK_XFS_H
+
+#include "quotaio_xfs.h"
+
+#define Q_XFS_QUOTAON	Q_XQUOTAON
+#define Q_XFS_QUOTAOFF	Q_XQUOTAOFF
+#define Q_XFS_GETQUOTA	Q_XGETQUOTA
+#define Q_XFS_SETQLIM	Q_XSETQLIM
+#define Q_XFS_GETQSTAT	Q_XGETQSTAT
+#define Q_XFS_QUOTARM	Q_XQUOTARM
+
+#define xfs_mem_dqinfo	fs_quota_stat
+#define xfs_kern_dqblk	fs_disk_quota
+
+struct quotafile_ops;		/* Will be defined later in quotaio.h */
+
+/* Operations above this format */
+extern struct quotafile_ops quotafile_ops_xfs;
+
+#endif
diff -uNr samba-2.2.4/source/smbd/quota.h samba-2.2.4-hch/source/smbd/quota.h
--- samba-2.2.4/source/smbd/quota.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/quota.h	Wed May 29 21:59:26 2002
@@ -0,0 +1,128 @@
+#ifndef _QUOTA_H
+#define _QUOTA_H
+
+#include <sys/types.h>
+
+typedef u_int32_t qid_t;	/* Type in which we store ids in memory */
+typedef u_int64_t qsize_t;	/* Type in which we store size limitations */
+
+#define MAXQUOTAS 2
+#define USRQUOTA  0		/* element used for user quotas */
+#define GRPQUOTA  1		/* element used for group quotas */
+
+/*
+ * Definitions for the default names of the quotas files.
+ */
+#define INITQFNAMES { \
+	"user",    /* USRQUOTA */ \
+	"group",   /* GRPQUOTA */ \
+	"undefined", \
+}
+
+/*
+ * Definitions of magics and versions of current quota files
+ */
+#define INITQMAGICS {\
+	0xd9c01f11,	/* USRQUOTA */\
+	0xd9c01927	/* GRPQUOTA */\
+}
+
+/* Size of blocks in which are counted size limits in generic utility parts */
+#define QUOTABLOCK_BITS 10
+#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
+
+/* Conversion routines from and to quota blocks */
+#define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10))
+#define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
+#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
+
+/*
+ * Command definitions for the 'quotactl' system call.
+ * The commands are broken into a main command defined below
+ * and a subcommand that is used to convey the type of
+ * quota that is being manipulated (see above).
+ */
+#define SUBCMDMASK  0x00ff
+#define SUBCMDSHIFT 8
+#define QCMD(cmd, type)  (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#define Q_6_5_QUOTAON  0x0100	/* enable quotas */
+#define Q_6_5_QUOTAOFF 0x0200	/* disable quotas */
+#define Q_6_5_SYNC     0x0600	/* sync disk copy of a filesystems quotas */
+
+#define Q_SYNC     0x800001	/* sync disk copy of a filesystems quotas */
+#define Q_QUOTAON  0x800002	/* turn quotas on */
+#define Q_QUOTAOFF 0x800003	/* turn quotas off */
+#define Q_GETFMT   0x800004	/* get quota format used on given filesystem */
+#define Q_GETINFO  0x800005	/* get information about quota files */
+#define Q_SETINFO  0x800006	/* set information about quota files */
+#define Q_GETQUOTA 0x800007	/* get user quota structure */
+#define Q_SETQUOTA 0x800008	/* set user quota structure */
+
+/*
+ * Quota structure used for communication with userspace via quotactl
+ * Following flags are used to specify which fields are valid
+ */
+#define QIF_BLIMITS	1
+#define QIF_SPACE	2
+#define QIF_ILIMITS	4
+#define QIF_INODES	8
+#define QIF_BTIME	16
+#define QIF_ITIME	32
+#define QIF_LIMITS	(QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE	(QIF_SPACE | QIF_INODES)
+#define QIF_TIMES	(QIF_BTIME | QIF_ITIME)
+#define QIF_ALL		(QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct if_dqblk {
+	u_int64_t dqb_bhardlimit;
+	u_int64_t dqb_bsoftlimit;
+	u_int64_t dqb_curspace;
+	u_int64_t dqb_ihardlimit;
+	u_int64_t dqb_isoftlimit;
+	u_int64_t dqb_curinodes;
+	u_int64_t dqb_btime;
+	u_int64_t dqb_itime;
+	u_int32_t dqb_valid;
+};
+
+/*
+ * Structure used for setting quota information about file via quotactl
+ * Following flags are used to specify which fields are valid
+ */
+#define IIF_BGRACE	1
+#define IIF_IGRACE	2
+#define IIF_FLAGS	4
+#define IIF_ALL		(IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct if_dqinfo {
+	u_int64_t dqi_bgrace;
+	u_int64_t dqi_igrace;
+	u_int32_t dqi_flags;
+	u_int32_t dqi_valid;
+};
+
+/* Quota format identifiers */
+#define QFMT_VFS_OLD 1
+#define QFMT_VFS_V0  2
+
+/* Flags supported by kernel */
+#define V1_DQF_RSQUASH 1
+
+/* Ioctl for getting quota size */
+#include <sys/ioctl.h>
+#ifndef FIOQSIZE
+	#if defined(__alpha__) || defined(__powerpc__) || defined(__sh__) || defined(__sparc__) || defined(__sparc64__)
+		#define FIOQSIZE _IOR('f', 128, loff_t)
+	#elif defined(__arm__) || defined(__mc68000__) || defined(__s390__)
+		#define FIOQSIZE 0x545E
+        #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__ia64__) || defined(__parisc__) || defined(__cris__) || defined(__hppa__)
+		#define FIOQSIZE 0x5460
+	#elif defined(__mips__) || defined(__mips64__)
+		#define FIOQSIZE 0x6667
+	#endif
+#endif
+
+long quotactl __P((int, const char *, qid_t, caddr_t));
+
+#endif /* _QUOTA_ */
diff -uNr samba-2.2.4/source/smbd/quotaio_v1.h samba-2.2.4-hch/source/smbd/quotaio_v1.h
--- samba-2.2.4/source/smbd/quotaio_v1.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/quotaio_v1.h	Wed May 29 21:59:32 2002
@@ -0,0 +1,49 @@
+/*
+ *	Headerfile for old quotafile format
+ */
+
+#ifndef _QUOTAIO_V1_H
+#define _QUOTAIO_V1_H
+
+#include <sys/types.h>
+
+#define V1_DQBLK_SIZE_BITS 10
+#define V1_DQBLK_SIZE (1 << V1_DQBLK_SIZE_BITS)	/* Size of one quota block in bytes in old format */
+
+#define V1_DQOFF(__id) ((loff_t) ((__id) * sizeof(struct v1_disk_dqblk)))
+
+/* Structure of quota on disk */
+struct v1_disk_dqblk {
+	u_int32_t dqb_bhardlimit;	/* absolute limit on disk blks alloc */
+	u_int32_t dqb_bsoftlimit;	/* preferred limit on disk blks */
+	u_int32_t dqb_curblocks;	/* current block count */
+	u_int32_t dqb_ihardlimit;	/* maximum # allocated inodes */
+	u_int32_t dqb_isoftlimit;	/* preferred limit on inodes */
+	u_int32_t dqb_curinodes;	/* current # allocated inodes */
+	time_t dqb_btime;	/* time limit for excessive disk use */
+	time_t dqb_itime;	/* time limit for excessive files */
+} __attribute__ ((packed));
+
+/* Structure used for communication with kernel */
+struct v1_kern_dqblk {
+	u_int32_t dqb_bhardlimit;	/* absolute limit on disk blks alloc */
+	u_int32_t dqb_bsoftlimit;	/* preferred limit on disk blks */
+	u_int32_t dqb_curblocks;	/* current block count */
+	u_int32_t dqb_ihardlimit;	/* maximum # allocated inodes */
+	u_int32_t dqb_isoftlimit;	/* preferred inode limit */
+	u_int32_t dqb_curinodes;	/* current # allocated inodes */
+	time_t dqb_btime;	/* time limit for excessive disk use */
+	time_t dqb_itime;	/* time limit for excessive files */
+};
+
+struct v1_dqstats {
+	u_int32_t lookups;
+	u_int32_t drops;
+	u_int32_t reads;
+	u_int32_t writes;
+	u_int32_t cache_hits;
+	u_int32_t allocated_dquots;
+	u_int32_t free_dquots;
+	u_int32_t syncs;
+};                                                                               
+#endif
diff -uNr samba-2.2.4/source/smbd/quotaio_v2.h samba-2.2.4-hch/source/smbd/quotaio_v2.h
--- samba-2.2.4/source/smbd/quotaio_v2.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/quotaio_v2.h	Wed May 29 21:59:32 2002
@@ -0,0 +1,101 @@
+/*
+ *
+ *	Header file for disk format of new quotafile format
+ *
+ */
+
+#ifndef _QUOTAIO_V2_H
+#define _QUOTAIO_V2_H
+
+#include <sys/types.h>
+#include "quota.h"
+
+#define V2_DQINFOOFF	sizeof(struct v2_disk_dqheader)	/* Offset of info header in file */
+#define V2_DQBLKSIZE_BITS	10
+#define V2_DQBLKSIZE	(1 << V2_DQBLKSIZE_BITS)	/* Size of block with quota structures */
+#define V2_DQTREEOFF	1	/* Offset of tree in file in blocks */
+#define V2_DQTREEDEPTH	4	/* Depth of quota tree */
+#define V2_DQSTRINBLK	((V2_DQBLKSIZE - sizeof(struct v2_disk_dqdbheader)) / sizeof(struct v2_disk_dqblk))	/* Number of entries in one blocks */
+#define V2_GETIDINDEX(id, depth) (((id) >> ((V2_DQTREEDEPTH-(depth)-1)*8)) & 0xff)
+#define V2_GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)(buf)) + sizeof(struct v2_disk_dqdbheader)))
+#define INIT_V2_VERSIONS { 0, 0}
+
+struct v2_disk_dqheader {
+	u_int32_t dqh_magic;	/* Magic number identifying file */
+	u_int32_t dqh_version;	/* File version */
+} __attribute__ ((packed));
+
+/* Flags for version specific files */
+#define V2_DQF_MASK  0x0000	/* Mask for all valid ondisk flags */
+
+/* Header with type and version specific information */
+struct v2_disk_dqinfo {
+	u_int32_t dqi_bgrace;	/* Time before block soft limit becomes hard limit */
+	u_int32_t dqi_igrace;	/* Time before inode soft limit becomes hard limit */
+	u_int32_t dqi_flags;	/* Flags for quotafile (DQF_*) */
+	u_int32_t dqi_blocks;	/* Number of blocks in file */
+	u_int32_t dqi_free_blk;	/* Number of first free block in the list */
+	u_int32_t dqi_free_entry;	/* Number of block with at least one free entry */
+} __attribute__ ((packed));
+
+/*
+ *  Structure of header of block with quota structures. It is padded to 16 bytes so
+ *  there will be space for exactly 18 quota-entries in a block
+ */
+struct v2_disk_dqdbheader {
+	u_int32_t dqdh_next_free;	/* Number of next block with free entry */
+	u_int32_t dqdh_prev_free;	/* Number of previous block with free entry */
+	u_int16_t dqdh_entries;	/* Number of valid entries in block */
+	u_int16_t dqdh_pad1;
+	u_int32_t dqdh_pad2;
+} __attribute__ ((packed));
+
+/* Structure of quota for one user on disk */
+struct v2_disk_dqblk {
+	u_int32_t dqb_id;	/* id this quota applies to */
+	u_int32_t dqb_ihardlimit;	/* absolute limit on allocated inodes */
+	u_int32_t dqb_isoftlimit;	/* preferred inode limit */
+	u_int32_t dqb_curinodes;	/* current # allocated inodes */
+	u_int32_t dqb_bhardlimit;	/* absolute limit on disk space (in QUOTABLOCK_SIZE) */
+	u_int32_t dqb_bsoftlimit;	/* preferred limit on disk space (in QUOTABLOCK_SIZE) */
+	u_int64_t dqb_curspace;	/* current space occupied (in bytes) */
+	u_int64_t dqb_btime;	/* time limit for excessive disk use */
+	u_int64_t dqb_itime;	/* time limit for excessive inode use */
+} __attribute__ ((packed));
+
+/* Structure of quota for communication with kernel */
+struct v2_kern_dqblk {
+	unsigned int dqb_ihardlimit;
+	unsigned int dqb_isoftlimit;
+	unsigned int dqb_curinodes;
+	unsigned int dqb_bhardlimit;
+	unsigned int dqb_bsoftlimit;
+	qsize_t dqb_curspace;
+	time_t dqb_btime;
+	time_t dqb_itime;
+};
+
+/* Structure of quotafile info for communication with kernel */
+struct v2_kern_dqinfo {
+	unsigned int dqi_bgrace;
+	unsigned int dqi_igrace;
+	unsigned int dqi_flags;
+	unsigned int dqi_blocks;
+	unsigned int dqi_free_blk;
+	unsigned int dqi_free_entry;
+};
+
+/* Structure with gathered statistics from kernel */
+struct v2_dqstats {
+	u_int32_t lookups;
+	u_int32_t drops;
+	u_int32_t reads;
+	u_int32_t writes;
+	u_int32_t cache_hits;
+	u_int32_t allocated_dquots;
+	u_int32_t free_dquots;
+	u_int32_t syncs;
+	u_int32_t version;
+};
+
+#endif
diff -uNr samba-2.2.4/source/smbd/quotaio_xfs.h samba-2.2.4-hch/source/smbd/quotaio_xfs.h
--- samba-2.2.4/source/smbd/quotaio_xfs.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/smbd/quotaio_xfs.h	Wed May 29 21:59:32 2002
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+#ifndef _QUOTAIO_XFS_H
+#define _QUOTAIO_XFS_H
+
+#include <linux/types.h>
+
+#define XQM_CMD(cmd)	( ('X'<<8)+(cmd) )
+#define IS_XQM_CMD(cmd)	( ((int)(cmd)>>8) == 'X' )
+
+/*
+ * Disk quota - quotactl(2) commands for XFS Quota Manager (XQM).
+ */
+#define Q_XQUOTAON   XQM_CMD(0x1)	/* enable quota accounting/enforcement */
+#define Q_XQUOTAOFF  XQM_CMD(0x2)	/* disable quota accounting/enforcement */
+#define Q_XGETQUOTA  XQM_CMD(0x3)	/* get disk limits & usage */
+#define Q_XSETQLIM   XQM_CMD(0x4)	/* set disk limits only */
+#define Q_XGETQSTAT  XQM_CMD(0x5)	/* returns fs_quota_stat_t struct */
+#define Q_XQUOTARM   XQM_CMD(0x6)	/* free quota files' space */
+
+/*
+ * fs_disk_quota structure:
+ *
+ * This contains the current quota information regarding a user/proj/group.
+ * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of
+ * 512 bytes.
+ */
+#define FS_DQUOT_VERSION	1	/* fs_disk_quota.d_version */
+typedef struct fs_disk_quota {
+	__s8 d_version;		/* version of this structure */
+	__s8 d_flags;		/* XFS_{USER,PROJ,GROUP}_QUOTA */
+	__u16 d_fieldmask;	/* field specifier */
+	__u32 d_id;		/* user, project, or group ID */
+	__u64 d_blk_hardlimit;	/* absolute limit on disk blks */
+	__u64 d_blk_softlimit;	/* preferred limit on disk blks */
+	__u64 d_ino_hardlimit;	/* maximum # allocated inodes */
+	__u64 d_ino_softlimit;	/* preferred inode limit */
+	__u64 d_bcount;		/* # disk blocks owned by the user */
+	__u64 d_icount;		/* # inodes owned by the user */
+	__s32 d_itimer;		/* zero if within inode limits */
+	/* if not, we refuse service */
+	__s32 d_btimer;		/* similar to above; for disk blocks */
+	__u16 d_iwarns;		/* # warnings issued wrt num inodes */
+	__u16 d_bwarns;		/* # warnings issued wrt disk blocks */
+	__s32 d_padding2;	/* padding2 - for future use */
+	__u64 d_rtb_hardlimit;	/* absolute limit on realtime blks */
+	__u64 d_rtb_softlimit;	/* preferred limit on RT disk blks */
+	__u64 d_rtbcount;	/* # realtime blocks owned */
+	__s32 d_rtbtimer;	/* similar to above; for RT disk blks */
+	__u16 d_rtbwarns;	/* # warnings issued wrt RT disk blks */
+	__s16 d_padding3;	/* padding3 - for future use */
+	char d_padding4[8];	/* yet more padding */
+} fs_disk_quota_t;
+
+/*
+ * These fields are sent to Q_XSETQLIM to specify fields that need to change.
+ */
+#define FS_DQ_ISOFT	(1<<0)
+#define FS_DQ_IHARD	(1<<1)
+#define FS_DQ_BSOFT	(1<<2)
+#define FS_DQ_BHARD 	(1<<3)
+#define FS_DQ_RTBSOFT	(1<<4)
+#define FS_DQ_RTBHARD	(1<<5)
+#define FS_DQ_LIMIT_MASK	(FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \
+				 FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD)
+/*
+ * These timers can only be set in super user's dquot. For others, timers are
+ * automatically started and stopped. Superusers timer values set the limits
+ * for the rest.  In case these values are zero, the DQ_{F,B}TIMELIMIT values
+ * defined below are used. 
+ * These values also apply only to the d_fieldmask field for Q_XSETQLIM.
+ */
+#define FS_DQ_BTIMER	(1<<6)
+#define FS_DQ_ITIMER	(1<<7)
+#define FS_DQ_RTBTIMER 	(1<<8)
+#define FS_DQ_TIMER_MASK	(FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER)
+
+/*
+ * The following constants define the default amount of time given a user
+ * before the soft limits are treated as hard limits (usually resulting
+ * in an allocation failure).  These may be modified by the quotactl(2)
+ * system call with the Q_XSETQLIM command.
+ */
+#define	DQ_FTIMELIMIT	(7 * 24*60*60)	/* 1 week */
+#define	DQ_BTIMELIMIT	(7 * 24*60*60)	/* 1 week */
+
+/*
+ * Various flags related to quotactl(2).  Only relevant to XFS filesystems.
+ */
+#define XFS_QUOTA_UDQ_ACCT	(1<<0)	/* user quota accounting */
+#define XFS_QUOTA_UDQ_ENFD	(1<<1)	/* user quota limits enforcement */
+#define XFS_QUOTA_GDQ_ACCT	(1<<2)	/* group quota accounting */
+#define XFS_QUOTA_GDQ_ENFD	(1<<3)	/* group quota limits enforcement */
+
+#define XFS_USER_QUOTA		(1<<0)	/* user quota type */
+#define XFS_PROJ_QUOTA		(1<<1)	/* (IRIX) project quota type */
+#define XFS_GROUP_QUOTA		(1<<2)	/* group quota type */
+
+/*
+ * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system.
+ * Provides a centralized way to get meta infomation about the quota subsystem.
+ * eg. space taken up for user and group quotas, number of dquots currently
+ * incore.
+ */
+#define FS_QSTAT_VERSION	1	/* fs_quota_stat.qs_version */
+
+/*
+ * Some basic infomation about 'quota files'.
+ */
+typedef struct fs_qfilestat {
+	__u64 qfs_ino;		/* inode number */
+	__u64 qfs_nblks;	/* number of BBs 512-byte-blks */
+	__u32 qfs_nextents;	/* number of extents */
+} fs_qfilestat_t;
+
+typedef struct fs_quota_stat {
+	__s8 qs_version;	/* version number for future changes */
+	__u16 qs_flags;		/* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
+	__s8 qs_pad;		/* unused */
+	fs_qfilestat_t qs_uquota;	/* user quota storage information */
+	fs_qfilestat_t qs_gquota;	/* group quota storage information */
+	__u32 qs_incoredqs;	/* number of dquots incore */
+	__s32 qs_btimelimit;	/* limit for blks timer */
+	__s32 qs_itimelimit;	/* limit for inodes timer */
+	__s32 qs_rtbtimelimit;	/* limit for rt blks timer */
+	__u16 qs_bwarnlimit;	/* limit for num warnings */
+	__u16 qs_iwarnlimit;	/* limit for num warnings */
+} fs_quota_stat_t;
+
+#endif /* _QUOTAIO_XFS_H */
diff -uNr samba-2.2.4/source/smbd/quotas.c samba-2.2.4-hch/source/smbd/quotas.c
--- samba-2.2.4/source/smbd/quotas.c	Sun Feb  3 01:46:56 2002
+++ samba-2.2.4-hch/source/smbd/quotas.c	Wed May 29 22:39:58 2002
@@ -42,26 +42,17 @@
 #ifdef LINUX
 
 #include <sys/types.h>
-#include <asm/types.h>
-
-/*
- * This shouldn't be neccessary - it should be /usr/include/sys/quota.h
- * Unfortunately, RH7.1 ships with a different quota system using struct mem_dqblk
- * rather than the struct dqblk defined in /usr/include/sys/quota.h.
- * This means we must include linux/quota.h to have a hope of working on
- * RH7.1 systems. And it also means this breaks if the kernel is upgraded
- * to a Linus 2.4.x (where x > the minor number shipped with RH7.1) until
- * Linus synchronises with the AC patches. Sometimes I *hate* Linux :-). JRA.
- */
-
-#include <linux/quota.h>
-#ifdef HAVE_LINUX_XQM_H
-#include <linux/xqm.h>
-#endif
-
 #include <mntent.h>
-#include <linux/unistd.h>
+#include <unistd.h>
 
+#include "quota.h"
+#include "quotaio_v1.h"
+#include "quotaio_v2.h"
+#include "quotaio_xfs.h"
+
+#ifndef QUOTABLOCK_SIZE
+#define QUOTABLOCK_SIZE 1024
+#endif
 
 #define LINUX_QUOTAS_2
 
@@ -82,7 +73,6 @@
 static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
 {
        int ret = -1;
-#ifdef HAVE_LINUX_XQM_H
        struct fs_disk_quota D;
        ZERO_STRUCT(D);
 
@@ -96,7 +86,7 @@
        dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
        dp->curinodes = (SMB_BIG_UINT)D.d_icount;
        dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
-#endif
+
        return ret;
 }
 
@@ -104,21 +94,34 @@
  Abstract out the old and new Linux quota get calls.
 ****************************************************************************/
 
-static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_v1_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
 {
+	struct v1_disk_dqblk D;
 	int ret;
-#ifdef LINUX_QUOTAS_1
-	struct dqblk D;
+
 	ZERO_STRUCT(D);
 	dp->bsize = (SMB_BIG_UINT)1024;
-#else /* LINUX_QUOTAS_2 */
-	struct mem_dqblk D;
+
+	if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+		return -1;
+
+	dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
+	dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
+	dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
+	dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
+	dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
+	dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
+
+	return 0;
+}
+
+static int get_smb_linux_v2_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+{
+	struct v2_disk_dqblk D;
+	int ret;
+
 	ZERO_STRUCT(D);
-#ifndef QUOTABLOCK_SIZE
-#define QUOTABLOCK_SIZE 1024
-#endif
 	dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-#endif
 
 	if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
 		return -1;
@@ -128,12 +131,7 @@
 	dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
 	dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
 	dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
-
-#ifdef LINUX_QUOTAS_1
-	dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
-#else /* LINUX_QUOTAS_2 */
 	dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace)/ dp->bsize;
-#endif
 
 	return 0;
 }
@@ -182,10 +180,12 @@
 
 	save_re_uid();
 	set_effective_uid(0);  
-	if (strcmp(mnt->mnt_type, "xfs") == 0)
+	if (strcmp(mnt->mnt_type, "xfs")) {
+		r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D);
+		if (r == -1)
+			r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D);
+	} else
 		r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D);
-	else
-		r=get_smb_linux_vfs_quota(mnt->mnt_fsname, euser_id, &D);
 	restore_re_uid();
 
 	/* Use softlimit to determine disk space, except when it has been exceeded */




More information about the samba mailing list