svn commit: r205207 - in projects/quota64: lib/libc/sys lib/libutil sys/ufs/ufs usr.bin/quota usr.sbin/repquota

Kirk McKusick mckusick at FreeBSD.org
Tue Mar 16 06:12:31 UTC 2010


Author: mckusick
Date: Tue Mar 16 06:12:30 2010
New Revision: 205207
URL: http://svn.freebsd.org/changeset/base/205207

Log:
  Debugging nits found while testing the new 64-bit quota code.

Modified:
  projects/quota64/lib/libc/sys/quotactl.2
  projects/quota64/lib/libutil/quotafile.c
  projects/quota64/sys/ufs/ufs/quota.h
  projects/quota64/sys/ufs/ufs/ufs_quota.c
  projects/quota64/sys/ufs/ufs/ufs_vfsops.c
  projects/quota64/usr.bin/quota/Makefile
  projects/quota64/usr.sbin/repquota/repquota.c

Modified: projects/quota64/lib/libc/sys/quotactl.2
==============================================================================
--- projects/quota64/lib/libc/sys/quotactl.2	Tue Mar 16 05:13:20 2010	(r205206)
+++ projects/quota64/lib/libc/sys/quotactl.2	Tue Mar 16 06:12:30 2010	(r205207)
@@ -84,7 +84,7 @@ and group identifiers (GRPQUOTA).
 The
 .Dq ufs
 specific commands are:
-.Bl -tag -width Q_QUOTAOFFxx
+.Bl -tag -width Q_GETQUOTASIZEx
 .It Dv Q_QUOTAON
 Enable disk quotas for the file system specified by
 .Fa path .
@@ -110,6 +110,17 @@ and
 .Fa id
 arguments are unused.
 Only the super-user may turn quotas off.
+.It Dv Q_GETQUOTASIZE
+Get the wordsize used to represent the quotas for the user or group
+(as determined by the command type).
+Possible values are 32 for the old-style quota file 
+and 64 for the new-style quota file.
+The
+.Fa addr
+argument is a pointer to an integer into which the size is stored.
+The identifier
+.Fa id
+is not used.
 .It Dv Q_GETQUOTA
 Get disk quota limits and current usage for the user or group
 (as determined by the command type) with identifier
@@ -177,9 +188,11 @@ The
 argument
 or the command type is invalid.
 In
-.Dv Q_GETQUOTA
-and
+.Dv Q_GETQUOTASIZE ,
+.Dv Q_GETQUOTA ,
 .Dv Q_SETQUOTA ,
+and
+.Dv Q_SETUSE ,
 quotas are not currently enabled for this file system.
 .Pp
 The
@@ -208,7 +221,8 @@ Too many symbolic links were encountered
 .It Bq Er EROFS
 In
 .Dv Q_QUOTAON ,
-the quota file resides on a read-only file system.
+either the file system on which quotas are to be enabled is mounted read-only
+or the quota file resides on a read-only file system.
 .It Bq Er EIO
 An
 .Tn I/O

Modified: projects/quota64/lib/libutil/quotafile.c
==============================================================================
--- projects/quota64/lib/libutil/quotafile.c	Tue Mar 16 05:13:20 2010	(r205206)
+++ projects/quota64/lib/libutil/quotafile.c	Tue Mar 16 06:12:30 2010	(r205207)
@@ -129,11 +129,9 @@ quota_open(struct fstab *fs, int quotaty
 		goto error;
 	qf->dev = st.st_dev;
 	serrno = hasquota(fs, quotatype, qf->qfname, sizeof(qf->qfname));
-	qcmd = QCMD(Q_GETQUOTA, quotatype);
-	if (quotactl(fs->fs_file, qcmd, 0, &dqh) == 0) {
-		qf->wordsize = 64;
+	qcmd = QCMD(Q_GETQUOTASIZE, quotatype);
+	if (quotactl(qf->fsname, qcmd, 0, &qf->wordsize) == 0)
 		return (qf);
-	}
 	if (serrno == 0) {
 		errno = EOPNOTSUPP;
 		goto error;
@@ -250,18 +248,22 @@ int
 quota_maxid(struct quotafile *qf)
 {
 	struct stat st;
+	int maxid;
 
 	if (stat(qf->qfname, &st) < 0)
 		return (0);
 	switch (qf->wordsize) {
 	case 32:
-		return (st.st_size / sizeof(struct dqblk32) - 1);
+		maxid = st.st_size / sizeof(struct dqblk32) - 1;
+		break;
 	case 64:
-		return (st.st_size / sizeof(struct dqblk64) - 2);
+		maxid = st.st_size / sizeof(struct dqblk64) - 2;
+		break;
 	default:
-		return (0);
+		maxid = 0;
+		break;
 	}
-	/* not reached */
+	return (maxid > 0 ? maxid : 0);
 }
 
 static int
@@ -395,10 +397,6 @@ quota_write_usage(struct quotafile *qf, 
 	struct dqblk dqbuf;
 	int qcmd;
 
-	if ((qf->accmode & O_RDWR) != O_RDWR) {
-		errno = EBADF;
-		return (-1);
-	}
 	if (qf->fd == -1) {
 		qcmd = QCMD(Q_SETUSE, qf->quotatype);
 		return (quotactl(qf->fsname, qcmd, id, dqb));
@@ -406,6 +404,10 @@ quota_write_usage(struct quotafile *qf, 
 	/*
 	 * Have to do read-modify-write of quota in file.
 	 */
+	if ((qf->accmode & O_RDWR) != O_RDWR) {
+		errno = EBADF;
+		return (-1);
+	}
 	if (quota_read(qf, &dqbuf, id) != 0)
 		return (-1);
 	/*
@@ -443,10 +445,6 @@ quota_write_limits(struct quotafile *qf,
 	struct dqblk dqbuf;
 	int qcmd;
 
-	if ((qf->accmode & O_RDWR) != O_RDWR) {
-		errno = EBADF;
-		return (-1);
-	}
 	if (qf->fd == -1) {
 		qcmd = QCMD(Q_SETQUOTA, qf->quotatype);
 		return (quotactl(qf->fsname, qcmd, id, dqb));
@@ -454,6 +452,10 @@ quota_write_limits(struct quotafile *qf,
 	/*
 	 * Have to do read-modify-write of quota in file.
 	 */
+	if ((qf->accmode & O_RDWR) != O_RDWR) {
+		errno = EBADF;
+		return (-1);
+	}
 	if (quota_read(qf, &dqbuf, id) != 0)
 		return (-1);
 	/*

Modified: projects/quota64/sys/ufs/ufs/quota.h
==============================================================================
--- projects/quota64/sys/ufs/ufs/quota.h	Tue Mar 16 05:13:20 2010	(r205206)
+++ projects/quota64/sys/ufs/ufs/quota.h	Tue Mar 16 06:12:30 2010	(r205207)
@@ -88,6 +88,7 @@
 #define	Q_GETQUOTA	0x0700	/* get limits and usage (64-bit version) */
 #define	Q_SETQUOTA	0x0800	/* set limits and usage (64-bit version) */
 #define	Q_SETUSE	0x0900	/* set usage (64-bit version) */
+#define	Q_GETQUOTASIZE	0x0A00	/* get bit-size of quota file fields */
 
 /*
  * The following structure defines the format of the disk quota file
@@ -235,6 +236,7 @@ int	setuse32(struct thread *, struct mou
 int	getquota(struct thread *, struct mount *, u_long, int, void *);
 int	setquota(struct thread *, struct mount *, u_long, int, void *);
 int	setuse(struct thread *, struct mount *, u_long, int, void *);
+int	getquotasize(struct thread *, struct mount *, u_long, int, void *);
 vfs_quotactl_t ufs_quotactl;
 
 #else /* !_KERNEL */

Modified: projects/quota64/sys/ufs/ufs/ufs_quota.c
==============================================================================
--- projects/quota64/sys/ufs/ufs/ufs_quota.c	Tue Mar 16 05:13:20 2010	(r205206)
+++ projects/quota64/sys/ufs/ufs/ufs_quota.c	Tue Mar 16 06:12:30 2010	(r205207)
@@ -508,6 +508,9 @@ quotaon(struct thread *td, struct mount 
 	if (error)
 		return (error);
 
+	if (mp->mnt_flag & MNT_RDONLY)
+		return (EROFS);
+
 	ump = VFSTOUFS(mp);
 	dq = NODQUOT;
 
@@ -534,7 +537,9 @@ quotaon(struct thread *td, struct mount 
 		return (EALREADY);
 	}
 	ump->um_qflags[type] |= QTF_OPENING|QTF_CLOSING;
+	UFS_UNLOCK(ump);
 	if ((error = dqopen(vp, ump, type)) != 0) {
+		UFS_LOCK(ump);
 		ump->um_qflags[type] &= ~(QTF_OPENING|QTF_CLOSING);
 		UFS_UNLOCK(ump);
 		(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
@@ -544,7 +549,6 @@ quotaon(struct thread *td, struct mount 
 	MNT_ILOCK(mp);
 	mp->mnt_flag |= MNT_QUOTA;
 	MNT_IUNLOCK(mp);
-	UFS_UNLOCK(ump);
 
 	vpp = &ump->um_quotas[type];
 	if (*vpp != vp)
@@ -989,6 +993,30 @@ setuse(struct thread *td, struct mount *
 }
 
 /*
+ * Q_GETQUOTASIZE - get bit-size of quota file fields
+ */
+int
+getquotasize(struct thread *td, struct mount *mp, u_long id, int type,
+    void *sizep)
+{
+	struct ufsmount *ump = VFSTOUFS(mp);
+	int bitsize;
+
+	UFS_LOCK(ump);
+	if (ump->um_quotas[type] == NULLVP ||
+	    (ump->um_qflags[type] & QTF_CLOSING)) {
+		UFS_UNLOCK(ump);
+		return (EINVAL);
+	}
+	if ((ump->um_qflags[type] & QTF_64BIT) != 0)
+		bitsize = 64;
+	else
+		bitsize = 32;
+	UFS_UNLOCK(ump);
+	return (copyout(&bitsize, sizep, sizeof(int)));
+}
+
+/*
  * Q_SYNC - sync quota files to disk.
  */
 int
@@ -1163,12 +1191,17 @@ dqopen(struct vnode *vp, struct ufsmount
 		return (0);
 	}
 
+	UFS_LOCK(ump);
 	if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) == 0 &&
 	    be32toh(dqh.dqh_version) == Q_DQHDR64_VERSION &&
 	    be32toh(dqh.dqh_hdrlen) == (uint32_t)sizeof(struct dqhdr64) &&
-	    be32toh(dqh.dqh_reclen) == (uint32_t)sizeof(struct dqblk64))
+	    be32toh(dqh.dqh_reclen) == (uint32_t)sizeof(struct dqblk64)) {
+		/* XXX: what if the magic matches, but the sizes are wrong? */
 		ump->um_qflags[type] |= QTF_64BIT;
-	/* XXX: what if the magic matches, but the sizes are wrong? */
+	} else {
+		ump->um_qflags[type] &= ~QTF_64BIT;
+	}
+	UFS_UNLOCK(ump);
 
 	return (0);
 }

Modified: projects/quota64/sys/ufs/ufs/ufs_vfsops.c
==============================================================================
--- projects/quota64/sys/ufs/ufs/ufs_vfsops.c	Tue Mar 16 05:13:20 2010	(r205206)
+++ projects/quota64/sys/ufs/ufs/ufs_vfsops.c	Tue Mar 16 06:12:30 2010	(r205207)
@@ -151,6 +151,10 @@ ufs_quotactl(mp, cmds, id, arg)
 		error = getquota(td, mp, id, type, arg);
 		break;
 
+	case Q_GETQUOTASIZE:
+		error = getquotasize(td, mp, id, type, arg);
+		break;
+
 	case Q_SYNC:
 		error = qsync(mp);
 		break;

Modified: projects/quota64/usr.bin/quota/Makefile
==============================================================================
--- projects/quota64/usr.bin/quota/Makefile	Tue Mar 16 05:13:20 2010	(r205206)
+++ projects/quota64/usr.bin/quota/Makefile	Tue Mar 16 06:12:30 2010	(r205207)
@@ -3,6 +3,7 @@
 
 PROG=	quota
 BINOWN=	root
+BINMODE=4555
 
 DPADD=	${LIBRPCSVC} ${LIBUTIL}
 LDADD=	-lrpcsvc -lutil

Modified: projects/quota64/usr.sbin/repquota/repquota.c
==============================================================================
--- projects/quota64/usr.sbin/repquota/repquota.c	Tue Mar 16 05:13:20 2010	(r205206)
+++ projects/quota64/usr.sbin/repquota/repquota.c	Tue Mar 16 06:12:30 2010	(r205207)
@@ -224,7 +224,7 @@ repquota(struct fstab *fs, int type)
 	printf("User%*s  used   soft   hard  grace     used    soft    hard  grace\n",
 		max(MAXLOGNAME - 1, 10), " ");
 	maxid = quota_maxid(qf);
-	for (id = 0; id < maxid; id++) {
+	for (id = 0; id <= maxid; id++) {
 		if (quota_read(qf, &dqbuf, id) != 0)
 			break;
 		if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0)


More information about the svn-src-projects mailing list