forked from pool/quota
289 lines
9.6 KiB
Diff
289 lines
9.6 KiB
Diff
--- quota-tools/Changelog
|
|
+++ quota-tools/Changelog
|
|
@@ -1,3 +1,6 @@
|
|
+* fixed bug in error reporting when quota reading fails (Jan Kara)
|
|
+* added support for quota formats with hidden quota files (Jan Kara)
|
|
+
|
|
Changes in quota-tools from 3.15 to 3.16
|
|
* added information message about journaled quota to quotacheck (Jan Kara, Alex Tomas)
|
|
* added pointers to quota_nld and warnquota to some manpages (Jan Kara)
|
|
--- quota-tools/Makefile.in
|
|
+++ quota-tools/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 @@
|
|
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@
|
|
--- quota-tools/mntopt.h
|
|
+++ quota-tools/mntopt.h
|
|
@@ -16,6 +16,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 */
|
|
--- quota-tools/quota.h
|
|
+++ quota-tools/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 */
|
|
@@ -135,6 +135,7 @@
|
|
/* 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
|
|
--- quota-tools/quotacheck.c
|
|
+++ quota-tools/quotacheck.c
|
|
@@ -1036,7 +1036,8 @@
|
|
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;
|
|
}
|
|
--- quota-tools/quotaio.c
|
|
+++ quota-tools/quotaio.c
|
|
@@ -97,8 +97,26 @@
|
|
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 @@
|
|
free(qfname); /* We don't need it anymore */
|
|
qfname = NULL;
|
|
|
|
+set_ops:
|
|
if (h->qh_fmt == QF_VFSOLD)
|
|
h->qh_ops = "afile_ops_1;
|
|
else if (h->qh_fmt == QF_VFSV0)
|
|
h->qh_ops = "afile_ops_2;
|
|
+ else if (h->qh_fmt == QF_META)
|
|
+ h->qh_ops = "afile_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 @@
|
|
|
|
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;
|
|
--- quota-tools/quotaio.h
|
|
+++ quota-tools/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 @@
|
|
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;
|
|
--- quota-tools/quotaio_meta.c
|
|
+++ quota-tools/quotaio_meta.c
|
|
@@ -0,0 +1,58 @@
|
|
+/*
|
|
+ * Implementation of handling of quotafiles which are hidden
|
|
+ *
|
|
+ * Jan Kara <jack@suse.cz>
|
|
+ */
|
|
+#include <string.h>
|
|
+#include <stdlib.h>
|
|
+
|
|
+#include <sys/types.h>
|
|
+
|
|
+#include "pot.h"
|
|
+#include "common.h"
|
|
+#include "quotasys.h"
|
|
+#include "quotaio_generic.h"
|
|
+
|
|
+static int meta_init_io(struct quota_handle *h)
|
|
+{
|
|
+ if (!QIO_ENABLED(h)) {
|
|
+ errstr(_("Metadata init_io called when kernel support is not enabled.\n"));
|
|
+ return -1;
|
|
+ }
|
|
+ if (kernel_iface != IFACE_GENERIC) {
|
|
+ errstr(_("Metadata init_io called when kernel does not support generic quota interface!\n"));
|
|
+ return -1;
|
|
+ }
|
|
+ return vfs_get_info(h);
|
|
+}
|
|
+
|
|
+static int meta_write_info(struct quota_handle *h)
|
|
+{
|
|
+ return vfs_set_info(h, IIF_BGRACE | IIF_IGRACE);
|
|
+}
|
|
+
|
|
+static struct dquot *meta_read_dquot(struct quota_handle *h, qid_t id)
|
|
+{
|
|
+ struct dquot *dquot = get_empty_dquot();
|
|
+
|
|
+ dquot->dq_id = id;
|
|
+ dquot->dq_h = h;
|
|
+ memset(&dquot->dq_dqb, 0, sizeof(struct util_dqblk));
|
|
+ if (vfs_get_dquot(dquot) < 0) {
|
|
+ free(dquot);
|
|
+ return NULL;
|
|
+ }
|
|
+ return dquot;
|
|
+}
|
|
+
|
|
+static int meta_commit_dquot(struct dquot *dquot, int flags)
|
|
+{
|
|
+ return vfs_set_dquot(dquot, flags);
|
|
+}
|
|
+
|
|
+struct quotafile_ops quotafile_ops_meta = {
|
|
+init_io: meta_init_io,
|
|
+write_info: meta_write_info,
|
|
+read_dquot: meta_read_dquot,
|
|
+commit_dquot: meta_commit_dquot,
|
|
+};
|
|
--- quota-tools/quotaon.c
|
|
+++ quota-tools/quotaon.c
|
|
@@ -173,6 +173,12 @@
|
|
|| (!(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;
|
|
--- quota-tools/quotaops.c
|
|
+++ quota-tools/quotaops.c
|
|
@@ -154,9 +154,11 @@
|
|
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;
|
|
}
|
|
--- quota-tools/quotasys.c
|
|
+++ quota-tools/quotasys.c
|
|
@@ -48,6 +48,15 @@
|
|
}
|
|
|
|
/*
|
|
+ * 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
|
|
*/
|
|
|
|
@@ -71,6 +80,7 @@
|
|
!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 +277,8 @@
|
|
return QF_VFSOLD;
|
|
case QFMT_VFS_V0:
|
|
return QF_VFSV0;
|
|
+ case QFMT_OCFS2:
|
|
+ return QF_META;
|
|
}
|
|
return -1;
|
|
}
|
|
@@ -700,7 +712,7 @@
|
|
/* 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;
|
|
--- quota-tools/quotasys.h
|
|
+++ quota-tools/quotasys.h
|
|
@@ -41,6 +41,8 @@
|
|
*/
|
|
/* 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);
|