diff options
-rw-r--r-- | Changelog | 5 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | mntopt.h | 4 | ||||
-rw-r--r-- | quota.h | 3 | ||||
-rw-r--r-- | quotacheck.c | 6 | ||||
-rw-r--r-- | quotaio.c | 27 | ||||
-rw-r--r-- | quotaio.h | 4 | ||||
-rw-r--r-- | quotaon.c | 8 | ||||
-rw-r--r-- | quotaops.c | 6 | ||||
-rw-r--r-- | quotasys.c | 15 | ||||
-rw-r--r-- | quotasys.h | 2 | ||||
-rw-r--r-- | rquotad.8 | 4 | ||||
-rw-r--r-- | setquota.c | 20 |
13 files changed, 83 insertions, 25 deletions
@@ -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@ @@ -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 */ @@ -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; @@ -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 = "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 @@ 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; @@ -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; @@ -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; @@ -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; } @@ -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; @@ -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); @@ -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) @@ -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; |