projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ufs_vinit prototype changed for new vn_if
[unix-history]
/
usr
/
src
/
sys
/
ufs
/
ffs
/
ufs_quota.c
diff --git
a/usr/src/sys/ufs/ffs/ufs_quota.c
b/usr/src/sys/ufs/ffs/ufs_quota.c
index
ad715e4
..
455f1e9
100644
(file)
--- a/
usr/src/sys/ufs/ffs/ufs_quota.c
+++ b/
usr/src/sys/ufs/ffs/ufs_quota.c
@@
-7,23
+7,22
@@
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)ufs_quota.c 7.
4
(Berkeley) %G%
+ * @(#)ufs_quota.c 7.
15
(Berkeley) %G%
*/
*/
-#include "param.h"
-#include "time.h"
-#include "kernel.h"
-#include "systm.h"
-#include "ucred.h"
-#include "namei.h"
-#include "errno.h"
-#include "malloc.h"
-#include "file.h"
-#include "vnode.h"
-#include "mount.h"
-#include "../ufs/fs.h"
-#include "../ufs/quota.h"
-#include "../ufs/inode.h"
-#include "../ufs/ufsmount.h"
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/malloc.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/inode.h>
+#include <ufs/ufs/ufsmount.h>
+#include <ufs/ufs/ufs_extern.h>
/*
* Quota name to error message mapping.
/*
* Quota name to error message mapping.
@@
-38,6
+37,7
@@
static char *quotatypes[] = INITQFNAMES;
* MAXQUOTAS value in quotas.h should be increased, and the
* additional dquots set up here.
*/
* MAXQUOTAS value in quotas.h should be increased, and the
* additional dquots set up here.
*/
+int
getinoquota(ip)
register struct inode *ip;
{
getinoquota(ip)
register struct inode *ip;
{
@@
-70,6
+70,7
@@
getinoquota(ip)
/*
* Update disk usage, and take corrective action.
*/
/*
* Update disk usage, and take corrective action.
*/
+int
chkdq(ip, change, cred, flags)
register struct inode *ip;
long change;
chkdq(ip, change, cred, flags)
register struct inode *ip;
long change;
@@
-129,6
+130,7
@@
chkdq(ip, change, cred, flags)
* Check for a valid change to a users allocation.
* Issue an error message if appropriate.
*/
* Check for a valid change to a users allocation.
* Issue an error message if appropriate.
*/
+int
chkdqchg(ip, change, cred, type)
struct inode *ip;
long change;
chkdqchg(ip, change, cred, type)
struct inode *ip;
long change;
@@
-145,7
+147,8
@@
chkdqchg(ip, change, cred, type)
if ((dq->dq_flags & DQ_BLKS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s disk limit reached\n",
if ((dq->dq_flags & DQ_BLKS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s disk limit reached\n",
- ip->i_fs->fs_fsmnt, quotatypes[type]);
+ ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ quotatypes[type]);
dq->dq_flags |= DQ_BLKS;
}
return (EDQUOT);
dq->dq_flags |= DQ_BLKS;
}
return (EDQUOT);
@@
-160,16
+163,17
@@
chkdqchg(ip, change, cred, type)
VFSTOUFS(ITOV(ip)->v_mount)->um_btime[type];
if (ip->i_uid == cred->cr_uid)
uprintf("\n%s: warning, %s %s\n",
VFSTOUFS(ITOV(ip)->v_mount)->um_btime[type];
if (ip->i_uid == cred->cr_uid)
uprintf("\n%s: warning, %s %s\n",
-
ip->i_fs->fs_fsmnt, quotatypes[type]
,
- "disk quota exceeded");
+
ITOV(ip)->v_mount->mnt_stat.f_mntonname
,
+
quotatypes[type],
"disk quota exceeded");
return (0);
}
if (time.tv_sec > dq->dq_btime) {
if ((dq->dq_flags & DQ_BLKS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s %s\n",
return (0);
}
if (time.tv_sec > dq->dq_btime) {
if ((dq->dq_flags & DQ_BLKS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s %s\n",
- ip->i_fs->fs_fsmnt, quotatypes[type],
- "disk quota exceeded too long");
+ ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ quotatypes[type],
+ "disk quota exceeded for too long");
dq->dq_flags |= DQ_BLKS;
}
return (EDQUOT);
dq->dq_flags |= DQ_BLKS;
}
return (EDQUOT);
@@
-181,6
+185,7
@@
chkdqchg(ip, change, cred, type)
/*
* Check the inode limit, applying corrective action.
*/
/*
* Check the inode limit, applying corrective action.
*/
+int
chkiq(ip, change, cred, flags)
register struct inode *ip;
long change;
chkiq(ip, change, cred, flags)
register struct inode *ip;
long change;
@@
-240,6
+245,7
@@
chkiq(ip, change, cred, flags)
* Check for a valid change to a users allocation.
* Issue an error message if appropriate.
*/
* Check for a valid change to a users allocation.
* Issue an error message if appropriate.
*/
+int
chkiqchg(ip, change, cred, type)
struct inode *ip;
long change;
chkiqchg(ip, change, cred, type)
struct inode *ip;
long change;
@@
-256,7
+262,8
@@
chkiqchg(ip, change, cred, type)
if ((dq->dq_flags & DQ_INODS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s inode limit reached\n",
if ((dq->dq_flags & DQ_INODS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s inode limit reached\n",
- ip->i_fs->fs_fsmnt, quotatypes[type]);
+ ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ quotatypes[type]);
dq->dq_flags |= DQ_INODS;
}
return (EDQUOT);
dq->dq_flags |= DQ_INODS;
}
return (EDQUOT);
@@
-271,16
+278,17
@@
chkiqchg(ip, change, cred, type)
VFSTOUFS(ITOV(ip)->v_mount)->um_itime[type];
if (ip->i_uid == cred->cr_uid)
uprintf("\n%s: warning, %s %s\n",
VFSTOUFS(ITOV(ip)->v_mount)->um_itime[type];
if (ip->i_uid == cred->cr_uid)
uprintf("\n%s: warning, %s %s\n",
-
ip->i_fs->fs_fsmnt, quotatypes[type]
,
- "inode quota exceeded");
+
ITOV(ip)->v_mount->mnt_stat.f_mntonname
,
+
quotatypes[type],
"inode quota exceeded");
return (0);
}
if (time.tv_sec > dq->dq_itime) {
if ((dq->dq_flags & DQ_INODS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s %s\n",
return (0);
}
if (time.tv_sec > dq->dq_itime) {
if ((dq->dq_flags & DQ_INODS) == 0 &&
ip->i_uid == cred->cr_uid) {
uprintf("\n%s: write failed, %s %s\n",
- ip->i_fs->fs_fsmnt, quotatypes[type],
- "inode quota exceeded too long");
+ ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ quotatypes[type],
+ "inode quota exceeded for too long");
dq->dq_flags |= DQ_INODS;
}
return (EDQUOT);
dq->dq_flags |= DQ_INODS;
}
return (EDQUOT);
@@
-291,10
+299,10
@@
chkiqchg(ip, change, cred, type)
#ifdef DIAGNOSTIC
/*
#ifdef DIAGNOSTIC
/*
- * On filesystems with quotas enabled,
- * it is an error for a file to change size and not
- * to have a dquot structure associated with it.
+ * On filesystems with quotas enabled, it is an error for a file to change
+ * size and not to have a dquot structure associated with it.
*/
*/
+void
chkdquot(ip)
register struct inode *ip;
{
chkdquot(ip)
register struct inode *ip;
{
@@
-311,7
+319,7
@@
chkdquot(ip)
}
}
}
}
}
}
-#endif
/* DIAGNOSTIC */
+#endif
/*
* Code to process quotactl commands.
/*
* Code to process quotactl commands.
@@
-320,8
+328,9
@@
chkdquot(ip)
/*
* Q_QUOTAON - set up a quota file for a particular file system.
*/
/*
* Q_QUOTAON - set up a quota file for a particular file system.
*/
-quotaon(ndp, mp, type, fname)
- register struct nameidata *ndp;
+int
+quotaon(p, mp, type, fname)
+ struct proc *p;
struct mount *mp;
register int type;
caddr_t fname;
struct mount *mp;
register int type;
caddr_t fname;
@@
-331,23
+340,24
@@
quotaon(ndp, mp, type, fname)
struct vnode *nextvp;
struct dquot *dq;
int error;
struct vnode *nextvp;
struct dquot *dq;
int error;
-
+ struct nameidata nd;
+
vpp = &ump->um_quotas[type];
vpp = &ump->um_quotas[type];
- ndp->ni_segflg = UIO_USERSPACE;
- ndp->ni_dirp = fname;
- if (error = vn_open(ndp, FREAD|FWRITE, 0))
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fname, p);
+ if (error = vn_open(&nd, FREAD|FWRITE, 0))
return (error);
return (error);
- vp = ndp->ni_vp;
+ vp = nd.ni_vp;
+ VOP_UNLOCK(vp);
if (vp->v_type != VREG) {
if (vp->v_type != VREG) {
-
vrele(v
p);
+
(void) vn_close(vp, FREAD|FWRITE, p->p_ucred,
p);
return (EACCES);
}
if (vfs_busy(mp)) {
return (EACCES);
}
if (vfs_busy(mp)) {
-
vrele(v
p);
+
(void) vn_close(vp, FREAD|FWRITE, p->p_ucred,
p);
return (EBUSY);
}
if (*vpp != vp)
return (EBUSY);
}
if (*vpp != vp)
- quotaoff(mp, type);
+ quotaoff(
p,
mp, type);
ump->um_qflags[type] |= QTF_OPENING;
mp->mnt_flag |= MNT_QUOTA;
vp->v_flag |= VSYSTEM;
ump->um_qflags[type] |= QTF_OPENING;
mp->mnt_flag |= MNT_QUOTA;
vp->v_flag |= VSYSTEM;
@@
-356,8
+366,8
@@
quotaon(ndp, mp, type, fname)
* Save the credential of the process that turned on quotas.
* Set up the time limits for this quota.
*/
* Save the credential of the process that turned on quotas.
* Set up the time limits for this quota.
*/
- crhold(
ndp->ni_
cred);
- ump->um_cred[type] =
ndp->ni_
cred;
+ crhold(
p->p_u
cred);
+ ump->um_cred[type] =
p->p_u
cred;
ump->um_btime[type] = MAX_DQ_TIME;
ump->um_itime[type] = MAX_IQ_TIME;
if (dqget(NULLVP, 0, ump, type, &dq) == 0) {
ump->um_btime[type] = MAX_DQ_TIME;
ump->um_itime[type] = MAX_IQ_TIME;
if (dqget(NULLVP, 0, ump, type, &dq) == 0) {
@@
-370,25
+380,26
@@
quotaon(ndp, mp, type, fname)
/*
* Search vnodes associated with this mount point,
* adding references to quota file being opened.
/*
* Search vnodes associated with this mount point,
* adding references to quota file being opened.
- * NB: only need to add dquot's for inodes being modified;
- * vp->v_usecount == 0 below should use vp->v_writecnt == 0.
+ * NB: only need to add dquot's for inodes being modified.
*/
again:
for (vp = mp->mnt_mounth; vp; vp = nextvp) {
nextvp = vp->v_mountf;
*/
again:
for (vp = mp->mnt_mounth; vp; vp = nextvp) {
nextvp = vp->v_mountf;
- if (vp->v_
us
ecount == 0)
+ if (vp->v_
writ
ecount == 0)
continue;
if (vget(vp))
goto again;
continue;
if (vget(vp))
goto again;
- if (error = getinoquota(VTOI(vp)))
+ if (error = getinoquota(VTOI(vp))) {
+ vput(vp);
break;
break;
+ }
vput(vp);
if (vp->v_mountf != nextvp || vp->v_mount != mp)
goto again;
}
ump->um_qflags[type] &= ~QTF_OPENING;
if (error)
vput(vp);
if (vp->v_mountf != nextvp || vp->v_mount != mp)
goto again;
}
ump->um_qflags[type] &= ~QTF_OPENING;
if (error)
- quotaoff(mp, type);
+ quotaoff(
p,
mp, type);
vfs_unbusy(mp);
return (error);
}
vfs_unbusy(mp);
return (error);
}
@@
-396,7
+407,9
@@
again:
/*
* Q_QUOTAOFF - turn off disk quotas for a filesystem.
*/
/*
* Q_QUOTAOFF - turn off disk quotas for a filesystem.
*/
-quotaoff(mp, type)
+int
+quotaoff(p, mp, type)
+ struct proc *p;
struct mount *mp;
register int type;
{
struct mount *mp;
register int type;
{
@@
-405,6
+418,7
@@
quotaoff(mp, type)
struct ufsmount *ump = VFSTOUFS(mp);
register struct dquot *dq;
register struct inode *ip;
struct ufsmount *ump = VFSTOUFS(mp);
register struct dquot *dq;
register struct inode *ip;
+ int error;
if ((mp->mnt_flag & MNT_MPBUSY) == 0)
panic("quotaoff: not busy");
if ((mp->mnt_flag & MNT_MPBUSY) == 0)
panic("quotaoff: not busy");
@@
-430,7
+444,7
@@
again:
}
dqflush(qvp);
qvp->v_flag &= ~VSYSTEM;
}
dqflush(qvp);
qvp->v_flag &= ~VSYSTEM;
-
vrele(qv
p);
+
error = vn_close(qvp, FREAD|FWRITE, p->p_ucred,
p);
ump->um_quotas[type] = NULLVP;
crfree(ump->um_cred[type]);
ump->um_cred[type] = NOCRED;
ump->um_quotas[type] = NULLVP;
crfree(ump->um_cred[type]);
ump->um_cred[type] = NOCRED;
@@
-440,12
+454,13
@@
again:
break;
if (type == MAXQUOTAS)
mp->mnt_flag &= ~MNT_QUOTA;
break;
if (type == MAXQUOTAS)
mp->mnt_flag &= ~MNT_QUOTA;
- return (
0
);
+ return (
error
);
}
/*
* Q_GETQUOTA - return current values in a dqblk structure.
*/
}
/*
* Q_GETQUOTA - return current values in a dqblk structure.
*/
+int
getquota(mp, id, type, addr)
struct mount *mp;
u_long id;
getquota(mp, id, type, addr)
struct mount *mp;
u_long id;
@@
-465,6
+480,7
@@
getquota(mp, id, type, addr)
/*
* Q_SETQUOTA - assign an entire dqblk structure.
*/
/*
* Q_SETQUOTA - assign an entire dqblk structure.
*/
+int
setquota(mp, id, type, addr)
struct mount *mp;
u_long id;
setquota(mp, id, type, addr)
struct mount *mp;
u_long id;
@@
-523,6
+539,7
@@
setquota(mp, id, type, addr)
/*
* Q_SETUSE - set current inode and block usage.
*/
/*
* Q_SETUSE - set current inode and block usage.
*/
+int
setuse(mp, id, type, addr)
struct mount *mp;
u_long id;
setuse(mp, id, type, addr)
struct mount *mp;
u_long id;
@@
-568,6
+585,7
@@
setuse(mp, id, type, addr)
/*
* Q_SYNC - sync quota files to disk.
*/
/*
* Q_SYNC - sync quota files to disk.
*/
+int
qsync(mp)
struct mount *mp;
{
qsync(mp)
struct mount *mp;
{
@@
-577,14
+595,25
@@
qsync(mp)
register int i;
/*
register int i;
/*
- *
Search vnodes associated with this mount point,
- *
synchronizing any modified dquot structures
.
+ *
Check if the mount point has any quotas.
+ *
If not, simply return
.
*/
if ((mp->mnt_flag & MNT_MPBUSY) == 0)
panic("qsync: not busy");
*/
if ((mp->mnt_flag & MNT_MPBUSY) == 0)
panic("qsync: not busy");
+ for (i = 0; i < MAXQUOTAS; i++)
+ if (ump->um_quotas[i] != NULLVP)
+ break;
+ if (i == MAXQUOTAS)
+ return (0);
+ /*
+ * Search vnodes associated with this mount point,
+ * synchronizing any modified dquot structures.
+ */
again:
for (vp = mp->mnt_mounth; vp; vp = nextvp) {
nextvp = vp->v_mountf;
again:
for (vp = mp->mnt_mounth; vp; vp = nextvp) {
nextvp = vp->v_mountf;
+ if (VOP_ISLOCKED(vp))
+ continue;
if (vget(vp))
goto again;
for (i = 0; i < MAXQUOTAS; i++) {
if (vget(vp))
goto again;
for (i = 0; i < MAXQUOTAS; i++) {
@@
-626,6
+655,7
@@
long numdquot, desireddquot = DQUOTINC;
/*
* Initialize the quota system.
*/
/*
* Initialize the quota system.
*/
+void
dqinit()
{
register union dqhead *dhp;
dqinit()
{
register union dqhead *dhp;
@@
-635,7
+665,7
@@
dqinit()
NBPG * CLSIZE);
dqhashtbl = (union dqhead *)malloc(dqhashsize, M_DQUOT, M_WAITOK);
for (dqhash = 1; dqhash <= dqhashsize / sizeof *dhp; dqhash <<= 1)
NBPG * CLSIZE);
dqhashtbl = (union dqhead *)malloc(dqhashsize, M_DQUOT, M_WAITOK);
for (dqhash = 1; dqhash <= dqhashsize / sizeof *dhp; dqhash <<= 1)
-
/* void */
;
+
continue
;
dqhash = (dqhash >> 1) - 1;
for (dhp = &dqhashtbl[dqhash]; dhp >= dqhashtbl; dhp--) {
dhp->dqh_head[0] = dhp;
dqhash = (dqhash >> 1) - 1;
for (dhp = &dqhashtbl[dqhash]; dhp >= dqhashtbl; dhp--) {
dhp->dqh_head[0] = dhp;
@@
-647,6
+677,7
@@
dqinit()
* Obtain a dquot structure for the specified identifier and quota file
* reading the information from the file if necessary.
*/
* Obtain a dquot structure for the specified identifier and quota file
* reading the information from the file if necessary.
*/
+int
dqget(vp, id, ump, type, dqp)
struct vnode *vp;
u_long id;
dqget(vp, id, ump, type, dqp)
struct vnode *vp;
u_long id;
@@
-736,6
+767,7
@@
dqget(vp, id, ump, type, dqp)
auio.uio_offset = (off_t)(id * sizeof (struct dqblk));
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_READ;
auio.uio_offset = (off_t)(id * sizeof (struct dqblk));
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_READ;
+ auio.uio_procp = (struct proc *)0;
error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]);
if (auio.uio_resid == sizeof(struct dqblk) && error == 0)
bzero((caddr_t)&dq->dq_dqb, sizeof(struct dqblk));
error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]);
if (auio.uio_resid == sizeof(struct dqblk) && error == 0)
bzero((caddr_t)&dq->dq_dqb, sizeof(struct dqblk));
@@
-776,6
+808,7
@@
dqget(vp, id, ump, type, dqp)
/*
* Obtain a reference to a dquot.
*/
/*
* Obtain a reference to a dquot.
*/
+void
dqref(dq)
struct dquot *dq;
{
dqref(dq)
struct dquot *dq;
{
@@
-786,6
+819,7
@@
dqref(dq)
/*
* Release a reference to a dquot.
*/
/*
* Release a reference to a dquot.
*/
+void
dqrele(vp, dq)
struct vnode *vp;
register struct dquot *dq;
dqrele(vp, dq)
struct vnode *vp;
register struct dquot *dq;
@@
-815,6
+849,7
@@
dqrele(vp, dq)
/*
* Update the disk quota in the quota file.
*/
/*
* Update the disk quota in the quota file.
*/
+int
dqsync(vp, dq)
struct vnode *vp;
register struct dquot *dq;
dqsync(vp, dq)
struct vnode *vp;
register struct dquot *dq;
@@
-835,8
+870,11
@@
dqsync(vp, dq)
while (dq->dq_flags & DQ_LOCK) {
dq->dq_flags |= DQ_WANT;
sleep((caddr_t)dq, PINOD+2);
while (dq->dq_flags & DQ_LOCK) {
dq->dq_flags |= DQ_WANT;
sleep((caddr_t)dq, PINOD+2);
- if ((dq->dq_flags & DQ_MOD) == 0)
+ if ((dq->dq_flags & DQ_MOD) == 0) {
+ if (vp != dqvp)
+ VOP_UNLOCK(dqvp);
return (0);
return (0);
+ }
}
dq->dq_flags |= DQ_LOCK;
auio.uio_iov = &aiov;
}
dq->dq_flags |= DQ_LOCK;
auio.uio_iov = &aiov;
@@
-847,6
+885,7
@@
dqsync(vp, dq)
auio.uio_offset = (off_t)(dq->dq_id * sizeof (struct dqblk));
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_WRITE;
auio.uio_offset = (off_t)(dq->dq_id * sizeof (struct dqblk));
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_WRITE;
+ auio.uio_procp = (struct proc *)0;
error = VOP_WRITE(dqvp, &auio, 0, dq->dq_ump->um_cred[dq->dq_type]);
if (auio.uio_resid && error == 0)
error = EIO;
error = VOP_WRITE(dqvp, &auio, 0, dq->dq_ump->um_cred[dq->dq_type]);
if (auio.uio_resid && error == 0)
error = EIO;
@@
-861,6
+900,7
@@
dqsync(vp, dq)
/*
* Flush all entries from the cache for a particular vnode.
*/
/*
* Flush all entries from the cache for a particular vnode.
*/
+void
dqflush(vp)
register struct vnode *vp;
{
dqflush(vp)
register struct vnode *vp;
{