summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneilbrown <neilbrown>2005-12-21 04:01:08 +0000
committerneilbrown <neilbrown>2005-12-21 04:01:08 +0000
commita021f1f459d8fd471123848c8f83a73a5fc1629e (patch)
tree9ddbc02b693a4e80aa39e8a56111297c724c753b
parentb7b2ed5c9ee5eea6193e6893a374bf8c8c3258d3 (diff)
downloadnfs-utils-a021f1f459d8fd471123848c8f83a73a5fc1629e.tar.gz
Handle new-style quotactl.
-rw-r--r--ChangeLog4
-rw-r--r--utils/rquotad/rquota_server.c140
2 files changed, 108 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 6440b4d..916ba0e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2005-12-21 NeilBrown <neilb@suse.de>
+ utils/rquotad/rquota_server.c: Detect and handle both old-style
+ (2.4) and new-style(2.6) quotactl.
+
2005-12-20 Kevin Coffman <kwc@citi.umich.edu> NeilBrown <neilb@suse.de>
Substantial Makefile/configure rewrite.
Run 'autogen.sh' to create "Makefile.in" etc.
diff --git a/utils/rquotad/rquota_server.c b/utils/rquotad/rquota_server.c
index 32e5cba..109c94e 100644
--- a/utils/rquotad/rquota_server.c
+++ b/utils/rquotad/rquota_server.c
@@ -22,14 +22,20 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#define _LINUX_QUOTA_VERSION 1
#include <rpc/rpc.h>
#include "rquota.h"
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/param.h>
+/* Unfortunately we cannot trust sys/quota.h to have
+ * what we need, either the old interface could be missing
+ * (SLES9) or the new (SLES8 and others).
+ * So we will just put it explicitly below
+ */
+#if 0
#include <sys/quota.h>
+#endif
#include <sys/mount.h>
#include <dirent.h>
#include <paths.h>
@@ -50,6 +56,47 @@
#define BLOCK_SIZE 1024
#endif
+#define MAXQUOTAS 2
+#define USRQUOTA 0 /* element used for user quotas */
+#define GRPQUOTA 1 /* element used for group quotas */
+
+struct 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 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;
+};
+
+#define SUBCMDMASK 0x00ff
+#define SUBCMDSHIFT 8
+#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#define Q_GETQUOTA 0x0300 /* get limits and usage */
+#define Q_SETQUOTA 0x0400 /* set limits and usage */
+
+#define Q_GETFMT 0x800004 /* get quota format used on given filesystem */
+#define Q_GETQUOTA_NEW 0x800007 /* get user quota structure */
+#define Q_SETQUOTA_NEW 0x800008 /* set user quota structure */
+#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk)))
+
+extern int quotactl (int __cmd, const char *__special, int __id,
+ caddr_t __addr) __THROW;
/*
* Global unix authentication credentials.
*/
@@ -75,12 +122,12 @@ getquota_rslt *getquotainfo(int flags, caddr_t *argp, struct svc_req *rqstp)
ext_getquota_args *ext_args;
} arguments;
FILE *fp;
- struct dqblk dq_dqb;
struct mntent *mnt;
char *pathname, *qfpathname;
int fd, err, id, type;
struct stat stm, stn;
struct rquota *rquota;
+ struct if_dqblk dqb;
/*
* First check authentication.
@@ -134,32 +181,53 @@ getquota_rslt *getquotainfo(int flags, caddr_t *argp, struct svc_req *rqstp)
result.getquota_rslt_u.gqr_rquota.rq_bsize = BLOCK_SIZE;
if (hasquota(mnt, type, &qfpathname)) {
- if ((err = quotactl(QCMD(Q_GETQUOTA, type), mnt->mnt_fsname,
- id, (caddr_t)&dq_dqb)) == -1
- && !(flags & ACTIVE)) {
- if ((fd = open(qfpathname, O_RDONLY)) < 0)
- {
- free(qfpathname);
- continue;
- }
- free(qfpathname);
- lseek(fd, (long) dqoff(id), L_SET);
- switch (read(fd, &dq_dqb, sizeof(struct dqblk))) {
- case 0:/* EOF */
- /*
- * Convert implicit 0 quota (EOF) into an
- * explicit one (zero'ed dqblk)
- */
- memset((caddr_t)&dq_dqb, 0, sizeof(struct dqblk));
- break;
- case sizeof(struct dqblk): /* OK */
- break;
- default: /* ERROR */
- close(fd);
- continue;
- }
- close(fd);
- }
+ int fmt;
+ if (quotactl(QCMD(Q_GETFMT, type), mnt->mnt_fsname, 0, (caddr_t)&fmt)==0) {
+ /* new style interface
+ * Don't bother trying to read from the file
+ */
+ err = quotactl(QCMD(Q_GETQUOTA_NEW, type),
+ mnt->mnt_fsname, id, (caddr_t)&dqb);
+ if (err) memset(&dqb, 0, sizeof(dqb));
+ } else {
+ /* old style */
+ struct dqblk dq_dqb;
+
+ if ((err = quotactl(QCMD(Q_GETQUOTA, type), mnt->mnt_fsname,
+ id, (caddr_t)&dq_dqb)) == -1
+ && !(flags & ACTIVE)) {
+ if ((fd = open(qfpathname, O_RDONLY)) < 0)
+ {
+ free(qfpathname);
+ continue;
+ }
+ free(qfpathname);
+ lseek(fd, (long) dqoff(id), L_SET);
+ switch (read(fd, &dq_dqb, sizeof(struct dqblk))) {
+ case 0:/* EOF */
+ /*
+ * Convert implicit 0 quota (EOF) into an
+ * explicit one (zero'ed dqblk)
+ */
+ memset((caddr_t)&dq_dqb, 0, sizeof(struct dqblk));
+ break;
+ case sizeof(struct dqblk): /* OK */
+ break;
+ default: /* ERROR */
+ close(fd);
+ continue;
+ }
+ close(fd);
+ }
+ dqb.dqb_bhardlimit = dq_dqb.dqb_bhardlimit;
+ dqb.dqb_bsoftlimit = dq_dqb.dqb_bsoftlimit;
+ dqb.dqb_curspace = dq_dqb.dqb_curblocks * 1024;
+ dqb.dqb_ihardlimit = dq_dqb.dqb_ihardlimit;
+ dqb.dqb_isoftlimit = dq_dqb.dqb_isoftlimit;
+ dqb.dqb_curinodes = dq_dqb.dqb_curinodes;
+ dqb.dqb_btime = dq_dqb.dqb_btime;
+ dqb.dqb_itime = dq_dqb.dqb_itime;
+ }
endmntent(fp);
if (err && (flags & ACTIVE)) {
@@ -175,14 +243,14 @@ getquota_rslt *getquotainfo(int flags, caddr_t *argp, struct svc_req *rqstp)
*/
rquota = &result.getquota_rslt_u.gqr_rquota;
- rquota->rq_bhardlimit = dq_dqb.dqb_bhardlimit;
- rquota->rq_bsoftlimit = dq_dqb.dqb_bsoftlimit;;
- rquota->rq_curblocks = dq_dqb.dqb_curblocks;
- rquota->rq_fhardlimit = dq_dqb.dqb_ihardlimit;
- rquota->rq_fsoftlimit = dq_dqb.dqb_isoftlimit;
- rquota->rq_curfiles = dq_dqb.dqb_curinodes;
- rquota->rq_btimeleft = dq_dqb.dqb_btime;
- rquota->rq_ftimeleft = dq_dqb.dqb_itime;
+ rquota->rq_bhardlimit = dqb.dqb_bhardlimit;
+ rquota->rq_bsoftlimit = dqb.dqb_bsoftlimit;;
+ rquota->rq_curblocks = dqb.dqb_curspace/1024;
+ rquota->rq_fhardlimit = dqb.dqb_ihardlimit;
+ rquota->rq_fsoftlimit = dqb.dqb_isoftlimit;
+ rquota->rq_curfiles = dqb.dqb_curinodes;
+ rquota->rq_btimeleft = dqb.dqb_btime;
+ rquota->rq_ftimeleft = dqb.dqb_itime;
return(&result);
}