Debugging nits found while testing the new 64-bit quota code.
This commit is contained in:
parent
1a0fda2b54
commit
516ad57b74
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/quota64/; revision=205207
@ -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 in translating a pathname.
|
||||
.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
|
||||
|
@ -129,11 +129,9 @@ quota_open(struct fstab *fs, int quotatype, int openflags)
|
||||
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 *dqb, int id)
|
||||
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, struct dqblk *dqb, int id)
|
||||
/*
|
||||
* 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 *dqb, int id)
|
||||
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, struct dqblk *dqb, int id)
|
||||
/*
|
||||
* 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);
|
||||
/*
|
||||
|
@ -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 mount *, u_long, int, void *);
|
||||
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 */
|
||||
|
@ -508,6 +508,9 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname)
|
||||
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 *mp, int type, void *fname)
|
||||
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 *mp, int type, void *fname)
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_QUOTA;
|
||||
MNT_IUNLOCK(mp);
|
||||
UFS_UNLOCK(ump);
|
||||
|
||||
vpp = &ump->um_quotas[type];
|
||||
if (*vpp != vp)
|
||||
@ -988,6 +992,30 @@ setuse(struct thread *td, struct mount *mp, u_long id, int type, void *addr)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@ -1163,12 +1191,17 @@ dqopen(struct vnode *vp, struct ufsmount *ump, int type)
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
PROG= quota
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
|
||||
DPADD= ${LIBRPCSVC} ${LIBUTIL}
|
||||
LDADD= -lrpcsvc -lutil
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user