summaryrefslogtreecommitdiffstats
path: root/source/smbd/quotas.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/quotas.c')
-rw-r--r--source/smbd/quotas.c111
1 files changed, 69 insertions, 42 deletions
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index 39cb8f2432f..4cfa05b1997 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
support for quotas
Copyright (C) Andrew Tridgell 1992-1998
@@ -41,28 +42,15 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B
#ifdef LINUX
#include <sys/types.h>
-#include <asm/types.h>
+#include <mntent.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.
+ * So we include all the files has *should* be in the system into a large,
+ * grungy samba_linux_quoatas.h 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>
-
-
-#define LINUX_QUOTAS_2
+#include "samba_linux_quota.h"
typedef struct _LINUX_SMB_DISK_QUOTA {
SMB_BIG_UINT bsize;
@@ -81,7 +69,6 @@ typedef struct _LINUX_SMB_DISK_QUOTA {
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);
@@ -95,7 +82,6 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
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;
}
@@ -103,23 +89,36 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
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;
+ dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
+
+ 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;
@@ -127,18 +126,38 @@ static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
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;
}
/****************************************************************************
-try to get the disk space from disk quotas (LINUX version)
+ Try to get the disk space from disk quotas (LINUX version).
****************************************************************************/
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
@@ -181,10 +200,18 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
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 */
@@ -415,7 +442,7 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B
host = strncat(cutstr,mnttype, sizeof(char) * len );
DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr));
DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype));
- testpath=strchr_m(mnttype, ':');
+ testpath=strchr(mnttype, ':');
args.gqa_pathp = testpath+1;
args.gqa_uid = uid;
@@ -498,7 +525,7 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B
DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize));
- SAFE_FREE(cutstr);
+ safe_free(cutstr);
DEBUG(10,("nfs_quotas: End of nfs_quotas\n" ));
return ret;
}