File quota-tools-meta.diff of Package quota

--- 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 = &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 @@
 
 	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);
openSUSE Build Service is sponsored by