summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog5
-rw-r--r--Makefile.in4
-rw-r--r--mntopt.h4
-rw-r--r--quota.h3
-rw-r--r--quotacheck.c6
-rw-r--r--quotaio.c27
-rw-r--r--quotaio.h4
-rw-r--r--quotaon.c8
-rw-r--r--quotaops.c6
-rw-r--r--quotasys.c15
-rw-r--r--quotasys.h2
-rw-r--r--rquotad.84
-rw-r--r--setquota.c20
13 files changed, 83 insertions, 25 deletions
diff --git a/Changelog b/Changelog
index 195550b..fba3be0 100644
--- a/Changelog
+++ b/Changelog
@@ -1,4 +1,9 @@
Changes in quota-tools from 3.16 to 3.17
+* fix reference to rpc manpage (anonymous reporter)
+* add EXT4 (not only EXT4DEV) to the list of supported filesystems (Mingming Cao)
+* fix setting of more than 31-bit block and inode limits (Gui Xiaohua)
+* fixed bug in error reporting when quota reading fails (Jan Kara)
+* added support for quota formats with hidden quota files (Jan Kara)
* remove IMMUTABLE flag from quota file in quotacheck (Jan Kara)
* fix bug in warnquota which could result in bogus hostname and domainname (anonymous reporter)
* implemented writing of messages that user got below hard/soft limits to quota_nld (Jan Kara)
diff --git a/Makefile.in b/Makefile.in
index ef119dc..2e1f106 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,5 +1,5 @@
PROGS = quotacheck quotaon quota quot repquota warnquota quotastats xqmstats edquota setquota convertquota rpc.rquotad @QUOTA_NETLINK_PROG@
-SOURCES = bylabel.c common.c convertquota.c edquota.c pot.c quot.c quota.c quotacheck.c quotacheck_v1.c quotacheck_v2.c quotaio.c quotaio_rpc.c quotaio_v1.c quotaio_v2.c quotaio_xfs.c quotaio_generic.c quotaon.c quotaon_xfs.c quotaops.c quotastats.c quotasys.c repquota.c rquota_client.c rquota_server.c rquota_svc.c setquota.c warnquota.c xqmstats.c svc_socket.c
+SOURCES = bylabel.c common.c convertquota.c edquota.c pot.c quot.c quota.c quotacheck.c quotacheck_v1.c quotacheck_v2.c quotaio.c quotaio_rpc.c quotaio_v1.c quotaio_v2.c quotaio_xfs.c quotaio_meta.c quotaio_generic.c quotaon.c quotaon_xfs.c quotaops.c quotastats.c quotasys.c repquota.c rquota_client.c rquota_server.c rquota_svc.c setquota.c warnquota.c xqmstats.c svc_socket.c
VERSIONDEF = -DQUOTA_VERSION=\"3.16\"
CFLAGS = @CFLAGS@ @EXT2_DIRECT@ -D_GNU_SOURCE -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 $(VERSIONDEF) -DCOMPILE_OPTS="\"@COMPILE_OPTS@\""
CPPFLAGS = @CPPFLAGS@
@@ -39,7 +39,7 @@ locale_dir = $(prefix)/share/locale
sysconfdir = @sysconfdir@
RPCCLNTOBJS = rquota_xdr.o rquota_client.o rquota_clnt.o
-IOOBJS = quotaio.o quotaio_v1.o quotaio_v2.o quotaio_rpc.o quotaio_xfs.o quotaio_generic.o
+IOOBJS = quotaio.o quotaio_v1.o quotaio_v2.o quotaio_rpc.o quotaio_xfs.o quotaio_meta.o quotaio_generic.o
IOOBJS += $(RPCCLNTOBJS)
LIBOBJS = bylabel.o common.o quotasys.o pot.o $(IOOBJS)
LIBOBJS += @LIBMALLOC@
diff --git a/mntopt.h b/mntopt.h
index e714243..ee375c4 100644
--- a/mntopt.h
+++ b/mntopt.h
@@ -6,7 +6,8 @@
/* filesystem type */
#define MNTTYPE_EXT2 "ext2" /* 2nd Extended file system */
#define MNTTYPE_EXT3 "ext3" /* ext2 + journaling */
-#define MNTTYPE_EXT4 "ext4dev" /* ext4 filesystem */
+#define MNTTYPE_EXT4 "ext4" /* ext4 filesystem */
+#define MNTTYPE_EXT4DEV "ext4dev"/* ext4dev filesystem */
#define MNTTYPE_MINIX "minix" /* MINIX file system */
#define MNTTYPE_UFS "ufs" /* UNIX file system */
#define MNTTYPE_UDF "udf" /* OSTA UDF file system */
@@ -16,6 +17,7 @@
#define MNTTYPE_JFS "jfs" /* JFS file system */
#define MNTTYPE_NFS4 "nfs4" /* NFSv4 filesystem */
#define MNTTYPE_MPFS "mpfs" /* EMC Celerra MPFS filesystem */
+#define MNTTYPE_OCFS2 "ocfs2" /* Oracle Cluster filesystem */
/* mount options */
#define MNTOPT_NOQUOTA "noquota" /* don't enforce quota */
diff --git a/quota.h b/quota.h
index e512677..76b12b2 100644
--- a/quota.h
+++ b/quota.h
@@ -4,7 +4,7 @@
#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 */
+typedef int64_t qsize_t; /* Type in which we store size limitations */
#define MAXQUOTAS 2
#define USRQUOTA 0 /* element used for user quotas */
@@ -139,6 +139,7 @@ enum {
/* Quota format identifiers */
#define QFMT_VFS_OLD 1
#define QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
/* Flags supported by kernel */
#define V1_DQF_RSQUASH 1
diff --git a/quotacheck.c b/quotacheck.c
index 209fc97..b5f7e2e 100644
--- a/quotacheck.c
+++ b/quotacheck.c
@@ -8,7 +8,7 @@
* New quota format implementation - Jan Kara <jack@suse.cz> - Sponsored by SuSE CR
*/
-#ident "$Id: quotacheck.c,v 1.56 2008/08/21 11:19:09 jkar8572 Exp $"
+#ident "$Id: quotacheck.c,v 1.57 2008/12/17 12:40:07 jkar8572 Exp $"
#include <dirent.h>
#include <stdio.h>
@@ -1048,7 +1048,8 @@ static void check_all(void)
while ((mnt = get_next_mount())) {
if (flags & FL_ALL && flags & FL_NOROOT && !strcmp(mnt->mnt_dir, "/"))
continue;
- if (!strcmp(mnt->mnt_type, MNTTYPE_XFS) || nfs_fstype(mnt->mnt_type)) {
+ if (!strcmp(mnt->mnt_type, MNTTYPE_XFS) || nfs_fstype(mnt->mnt_type) ||
+ meta_qf_fstype(mnt->mnt_type)) {
debug(FL_DEBUG | FL_VERBOSE, _("Skipping %s [%s]\n"), mnt->mnt_fsname, mnt->mnt_dir);
continue;
}
@@ -1076,6 +1077,7 @@ static void check_all(void)
!hasmntopt(mnt, MNTOPT_GRPJQUOTA) && !warned &&
(!strcmp(mnt->mnt_type, MNTTYPE_EXT3) ||
!strcmp(mnt->mnt_type, MNTTYPE_EXT4) ||
+ !strcmp(mnt->mnt_type, MNTTYPE_EXT4DEV) ||
!strcmp(mnt->mnt_type, MNTTYPE_REISER))) {
struct utsname stats;
diff --git a/quotaio.c b/quotaio.c
index 5be8a25..d74a37d 100644
--- a/quotaio.c
+++ b/quotaio.c
@@ -97,8 +97,26 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags)
fmt = kernfmt; /* Default is kernel used format */
}
}
- if ((fmt = get_qf_name(mnt, type, (fmt == -1) ? ((1 << QF_VFSOLD) | (1 << QF_VFSV0)) : (1 << fmt),
- (!QIO_ENABLED(h) || flags & IOI_OPENFILE) ? NF_FORMAT : 0, &qfname)) < 0) {
+
+ if (meta_qf_fstype(mnt->mnt_type)) {
+ if (!QIO_ENABLED(h)) {
+ errstr(_("Quota not supported by the filesystem.\n"));
+ goto out_handle;
+ }
+ if (flags & IOI_OPENFILE) {
+ errstr(_("Operation not supported for filesystems with hidden quota files!\n"));
+ goto out_handle;
+ }
+ h->qh_fd = -1;
+ h->qh_fmt = fmt;
+ goto set_ops;
+ }
+
+ fmt = get_qf_name(mnt, type,
+ (fmt == -1) ? ((1 << QF_VFSOLD) | (1 << QF_VFSV0)) : (1 << fmt),
+ (!QIO_ENABLED(h) || flags & IOI_OPENFILE) ? NF_FORMAT : 0,
+ &qfname);
+ if (fmt < 0) {
errstr(_("Quota file not found or has wrong format.\n"));
goto out_handle;
}
@@ -121,10 +139,13 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags)
free(qfname); /* We don't need it anymore */
qfname = NULL;
+set_ops:
if (h->qh_fmt == QF_VFSOLD)
h->qh_ops = &quotafile_ops_1;
else if (h->qh_fmt == QF_VFSV0)
h->qh_ops = &quotafile_ops_2;
+ else if (h->qh_fmt == QF_META)
+ h->qh_ops = &quotafile_ops_meta;
memset(&h->qh_info, 0, sizeof(h->qh_info));
if (h->qh_ops->init_io && h->qh_ops->init_io(h) < 0) {
@@ -155,7 +176,7 @@ struct quota_handle *new_io(struct mntent *mnt, int type, int fmt)
if (fmt == -1)
fmt = QF_VFSV0; /* Use the newest format */
- else if (fmt == QF_RPC || fmt == QF_XFS) {
+ else if (fmt == QF_RPC || fmt == QF_XFS || meta_qf_fstype(mnt->mnt_type)) {
errstr(_("Creation of %s quota format is not supported.\n"),
fmt == QF_RPC ? "RPC" : "XFS");
return NULL;
diff --git a/quotaio.h b/quotaio.h
index c3f633d..f6eef50 100644
--- a/quotaio.h
+++ b/quotaio.h
@@ -50,6 +50,7 @@
#define QF_VFSV0 1 /* New quota format - version 0 */
#define QF_RPC 2 /* RPC should be used on given filesystem */
#define QF_XFS 3 /* XFS quota format */
+#define QF_META 4 /* Quota files are hidden, we don't care about the format */
/*
* Definitions for disk quotas imposed on the average user
@@ -153,6 +154,9 @@ struct quotafile_ops {
int (*report) (struct quota_handle * h, int verbose); /* Function called after 'repquota' to print format specific file information */
};
+/* This might go into a special header file but that sounds a bit silly... */
+extern struct quotafile_ops quotafile_ops_meta;
+
static inline void mark_quotafile_info_dirty(struct quota_handle *h)
{
h->qh_io_flags |= IOFL_INFODIRTY;
diff --git a/quotaon.c b/quotaon.c
index 3f5ac86..51b107e 100644
--- a/quotaon.c
+++ b/quotaon.c
@@ -34,7 +34,7 @@
#ident "$Copyright: (c) 1980, 1990 Regents of the University of California $"
#ident "$Copyright: All rights reserved. $"
-#ident "$Id: quotaon.c,v 1.25 2008/03/13 14:49:33 jkar8572 Exp $"
+#ident "$Id: quotaon.c,v 1.26 2008/12/17 12:40:07 jkar8572 Exp $"
/*
* Turn quota on/off for a filesystem.
@@ -173,6 +173,12 @@ static int newstate(struct mntent *mnt, int type, char *extra)
|| (!(flags & FL_OFF) && kern_quota_on(mnt->mnt_fsname, type, 1 << QF_XFS))))
ret = xfs_newstate(mnt, type, extra, sflags);
}
+ else if (meta_qf_fstype(mnt->mnt_type)) {
+ if (!hasquota(mnt, type, 0))
+ return 0;
+ /* Must be non-empty because empty path is always invalid. */
+ ret = v2_newstate(mnt, type, ".", sflags);
+ }
else {
if (!hasquota(mnt, type, 0))
return 0;
diff --git a/quotaops.c b/quotaops.c
index b6e1747..f63b043 100644
--- a/quotaops.c
+++ b/quotaops.c
@@ -34,7 +34,7 @@
#ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $"
#ident "$Copyright: All rights reserved. $"
-#ident "$Id: quotaops.c,v 1.21 2008/04/21 15:37:42 jkar8572 Exp $"
+#ident "$Id: quotaops.c,v 1.22 2008/12/17 12:40:07 jkar8572 Exp $"
#include <rpc/rpc.h>
#include <sys/types.h>
@@ -154,9 +154,11 @@ struct dquot *getprivs(qid_t id, struct quota_handle **handles, int quiet)
if (!(q = handles[i]->qh_ops->read_dquot(handles[i], id))) {
/* If rpc.rquotad is not running filesystem might be just without quotas... */
if (errno != ENOENT && (errno != ECONNREFUSED || !quiet)) {
+ int olderrno = errno;
+
id2name(id, handles[i]->qh_type, name);
errstr(_("error while getting quota from %s for %s (id %u): %s\n"),
- handles[i]->qh_quotadev, name, id, strerror(errno));
+ handles[i]->qh_quotadev, name, id, strerror(olderrno));
}
continue;
}
diff --git a/quotasys.c b/quotasys.c
index 8d25da9..9a7f440 100644
--- a/quotasys.c
+++ b/quotasys.c
@@ -48,6 +48,15 @@ int nfs_fstype(char *type)
}
/*
+ * Check whether filesystem has hidden quota files which is handles
+ * as metadata (and thus always tracks usage).
+ */
+int meta_qf_fstype(char *type)
+{
+ return !strcmp(type, MNTTYPE_OCFS2);
+}
+
+/*
* Check whether give filesystem type is supported
*/
@@ -63,6 +72,7 @@ static int correct_fstype(char *type)
if (!strcmp(type, MNTTYPE_EXT2) ||
!strcmp(type, MNTTYPE_EXT3) ||
!strcmp(type, MNTTYPE_EXT4) ||
+ !strcmp(type, MNTTYPE_EXT4DEV) ||
!strcmp(type, MNTTYPE_JFS) ||
!strcmp(type, MNTTYPE_MINIX) ||
!strcmp(type, MNTTYPE_UFS) ||
@@ -71,6 +81,7 @@ static int correct_fstype(char *type)
!strcmp(type, MNTTYPE_XFS) ||
!strcmp(type, MNTTYPE_NFS) ||
!strcmp(type, MNTTYPE_NFS4) ||
+ !strcmp(type, MNTTYPE_OCFS2) ||
!strcmp(type, MNTTYPE_MPFS)) {
free(mtype);
return 1;
@@ -267,6 +278,8 @@ int kern2utilfmt(int fmt)
return QF_VFSOLD;
case QFMT_VFS_V0:
return QF_VFSV0;
+ case QFMT_OCFS2:
+ return QF_META;
}
return -1;
}
@@ -700,7 +713,7 @@ void init_kernel_interface(void)
/* Detect new kernel interface; Assume generic interface unless we can prove there is not one... */
if (!stat("/proc/sys/fs/quota", &st) || errno != ENOENT) {
kernel_iface = IFACE_GENERIC;
- kernel_formats |= (1 << QF_VFSOLD) | (1 << QF_VFSV0);
+ kernel_formats |= (1 << QF_VFSOLD) | (1 << QF_VFSV0) | (1 << QF_META);
}
else {
struct v2_dqstats v2_stats;
diff --git a/quotasys.h b/quotasys.h
index 54bcb8d..17b0a05 100644
--- a/quotasys.h
+++ b/quotasys.h
@@ -41,6 +41,8 @@ extern int kernel_formats, kernel_iface;
*/
/* Check whether type is one of the NFS filesystems */
int nfs_fstype(char *);
+/* Quota file is treated as metadata? */
+int meta_qf_fstype(char *type);
/* Convert quota type to written form */
char *type2name(int);
diff --git a/rquotad.8 b/rquotad.8
index c6b250a..f18bdcc 100644
--- a/rquotad.8
+++ b/rquotad.8
@@ -19,7 +19,7 @@ rquotad, rpc.rquotad \- remote quota server
.IX "remote procedure call services" "rquotad" "" "\fLrquotad\fP \(em remote quota server"
.B rquotad
is an
-.BR rpc (3N)
+.BR rpc (3)
server which returns quotas for a user of a local filesystem
which is mounted by a remote machine over the
.SM NFS\s0.
@@ -89,7 +89,7 @@ default filesystems
.PD
.SH "SEE ALSO"
.BR quota (1),
-.BR rpc (3N),
+.BR rpc (3),
.BR nfs (5),
.BR services (5),
.BR inetd (8)
diff --git a/setquota.c b/setquota.c
index c104b31..325c553 100644
--- a/setquota.c
+++ b/setquota.c
@@ -78,10 +78,10 @@ static void usage(void)
}
/* Convert string to number - print errstr message in case of failure */
-static long parse_num(char *str, char *msg)
+static qsize_t parse_unum(char *str, char *msg)
{
char *errch;
- long ret = strtol(str, &errch, 0);
+ qsize_t ret = strtoull(str, &errch, 0);
if (*errch) {
errstr(_("Bad %s: %s\n"), msg, str);
@@ -219,17 +219,17 @@ static void parse_options(int argcnt, char **argstr)
if (!(flags & (FL_GRACE | FL_BATCH))) {
id = name2id(argstr[optind++], flag2type(flags), !!(flags & FL_NUMNAMES), NULL);
if (!(flags & (FL_GRACE | FL_INDIVIDUAL_GRACE | FL_PROTO))) {
- toset.dqb_bsoftlimit = parse_num(argstr[optind++], _("block softlimit"));
- toset.dqb_bhardlimit = parse_num(argstr[optind++], _("block hardlimit"));
- toset.dqb_isoftlimit = parse_num(argstr[optind++], _("inode softlimit"));
- toset.dqb_ihardlimit = parse_num(argstr[optind++], _("inode hardlimit"));
+ toset.dqb_bsoftlimit = parse_unum(argstr[optind++], _("block softlimit"));
+ toset.dqb_bhardlimit = parse_unum(argstr[optind++], _("block hardlimit"));
+ toset.dqb_isoftlimit = parse_unum(argstr[optind++], _("inode softlimit"));
+ toset.dqb_ihardlimit = parse_unum(argstr[optind++], _("inode hardlimit"));
}
else if (flags & FL_PROTO)
protoid = name2id(protoname, flag2type(flags), !!(flags & FL_NUMNAMES), NULL);
}
if (flags & FL_GRACE) {
- toset.dqb_btime = parse_num(argstr[optind++], _("block grace time"));
- toset.dqb_itime = parse_num(argstr[optind++], _("inode grace time"));
+ toset.dqb_btime = parse_unum(argstr[optind++], _("block grace time"));
+ toset.dqb_itime = parse_unum(argstr[optind++], _("inode grace time"));
}
else if (flags & FL_INDIVIDUAL_GRACE) {
time_t now;
@@ -240,13 +240,13 @@ static void parse_options(int argcnt, char **argstr)
optind++;
}
else
- toset.dqb_btime = now + parse_num(argstr[optind++], _("block grace time"));
+ toset.dqb_btime = now + parse_unum(argstr[optind++], _("block grace time"));
if (!strcmp(argstr[optind], _("unset"))) {
toset.dqb_itime = 0;
optind++;
}
else
- toset.dqb_itime = now + parse_num(argstr[optind++], _("inode grace time"));
+ toset.dqb_itime = now + parse_unum(argstr[optind++], _("inode grace time"));
}
if (!(flags & FL_ALL)) {
mntcnt = argcnt - optind;