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

Christoph Hellwig hch at infradead.org
Wed May 29 13:31:02 GMT 2002


> Here's a better patch - it also handles another linux quota interface
> that samba didn't yet handle at all..

Yikes, that was still borked.


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/include/quota_linux.h samba-2.2.4-hch/source/include/quota_linux.h
--- samba-2.2.4/source/include/quota_linux.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/include/quota_linux.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/include/quotaio_linux_v1.h samba-2.2.4-hch/source/include/quotaio_linux_v1.h
--- samba-2.2.4/source/include/quotaio_linux_v1.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/include/quotaio_linux_v1.h	Wed May 29 23:10:51 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/include/quotaio_linux_v2.h samba-2.2.4-hch/source/include/quotaio_linux_v2.h
--- samba-2.2.4/source/include/quotaio_linux_v2.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/include/quotaio_linux_v2.h	Wed May 29 23:10:46 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_linux.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/include/quotaio_linux_xfs.h samba-2.2.4-hch/source/include/quotaio_linux_xfs.h
--- samba-2.2.4/source/include/quotaio_linux_xfs.h	Thu Jan  1 01:00:00 1970
+++ samba-2.2.4-hch/source/include/quotaio_linux_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 23:18:08 2002
@@ -42,28 +42,25 @@
 #ifdef LINUX
 
 #include <sys/types.h>
-#include <asm/types.h>
+#include <mntent.h>
+#include <unistd.h>
+
+#include "quotaio_linux_v1.h"
+#include "quotaio_linux_v2.h"
+#include "quotaio_linux_xfs.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>
+#ifndef Q_V1_GETQUOTA
+#define Q_V1_GETQUOTA	0x300
 #endif
 
-#include <mntent.h>
-#include <linux/unistd.h>
+#ifndef Q_V2_GETQUOTA
+#define Q_V2_GETQUOTA	0x0D00
+#endif
 
+#ifndef QUOTABLOCK_SIZE
+#define QUOTABLOCK_SIZE	1024
+#endif
 
-#define LINUX_QUOTAS_2
 
 typedef struct _LINUX_SMB_DISK_QUOTA {
 	SMB_BIG_UINT bsize;
@@ -82,7 +79,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 +92,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,23 +100,36 @@
  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_kern_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_V1_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_kern_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)))
+	if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
 		return -1;
 
 	dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
@@ -128,12 +137,32 @@
 	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_curspace) / dp->bsize;
 
-#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;
+}
+
+/****************************************************************************
+brand-new generic quota interface
+****************************************************************************/
+
+static int get_smb_linux_gen_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+{
+	struct if_dqblk D;
+	int ret;
+
+	ZERO_STRUCT(D);
+	dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
+
+	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_curspace) / dp->bsize;
 
 	return 0;
 }
@@ -182,10 +211,16 @@
 
 	save_re_uid();
 	set_effective_uid(0);  
-	if (strcmp(mnt->mnt_type, "xfs") == 0)
+	if (strcmp(mnt->mnt_type, "xfs")) {
+		r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D);
+		if (r == -1) {
+			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