aboutsummaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/quota.h2
-rw-r--r--sys/ufs/ufs/ufs_quota.c21
-rw-r--r--sys/ufs/ufs/ufs_vfsops.c19
3 files changed, 26 insertions, 16 deletions
diff --git a/sys/ufs/ufs/quota.h b/sys/ufs/ufs/quota.h
index eb3db9c300d0..e154f8234705 100644
--- a/sys/ufs/ufs/quota.h
+++ b/sys/ufs/ufs/quota.h
@@ -232,7 +232,7 @@ int getinoquota(struct inode *);
int qsync(struct mount *);
int qsyncvp(struct vnode *);
int quotaoff(struct thread *, struct mount *, int);
-int quotaon(struct thread *, struct mount *, int, void *, bool *);
+int quotaon(struct thread *, struct mount *, int, void *);
int getquota32(struct thread *, struct mount *, u_long, int, void *);
int setquota32(struct thread *, struct mount *, u_long, int, void *);
int setuse32(struct thread *, struct mount *, u_long, int, void *);
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index 143e0afbf1e3..4dff74f75945 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -492,8 +492,7 @@ chkdquot(struct inode *ip)
* Q_QUOTAON - set up a quota file for a particular filesystem.
*/
int
-quotaon(struct thread *td, struct mount *mp, int type, void *fname,
- bool *mp_busy)
+quotaon(struct thread *td, struct mount *mp, int type, void *fname)
{
struct ufsmount *ump;
struct vnode *vp, **vpp;
@@ -503,11 +502,15 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname,
struct nameidata nd;
error = priv_check(td, PRIV_UFS_QUOTAON);
- if (error != 0)
+ if (error != 0) {
+ vfs_unbusy(mp);
return (error);
+ }
- if ((mp->mnt_flag & MNT_RDONLY) != 0)
+ if ((mp->mnt_flag & MNT_RDONLY) != 0) {
+ vfs_unbusy(mp);
return (EROFS);
+ }
ump = VFSTOUFS(mp);
dq = NODQUOT;
@@ -515,9 +518,7 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname,
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fname, td);
flags = FREAD | FWRITE;
vfs_ref(mp);
- KASSERT(*mp_busy, ("%s called without busied mount", __func__));
vfs_unbusy(mp);
- *mp_busy = false;
error = vn_open(&nd, &flags, 0, NULL);
if (error != 0) {
vfs_rel(mp);
@@ -528,9 +529,10 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname,
error = vfs_busy(mp, MBF_NOWAIT);
vfs_rel(mp);
if (error == 0) {
- *mp_busy = true;
- if (vp->v_type != VREG)
+ if (vp->v_type != VREG) {
error = EACCES;
+ vfs_unbusy(mp);
+ }
}
if (error != 0) {
VOP_UNLOCK(vp);
@@ -543,6 +545,7 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname,
UFS_UNLOCK(ump);
VOP_UNLOCK(vp);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
+ vfs_unbusy(mp);
return (EALREADY);
}
ump->um_qflags[type] |= QTF_OPENING|QTF_CLOSING;
@@ -553,6 +556,7 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname,
ump->um_qflags[type] &= ~(QTF_OPENING|QTF_CLOSING);
UFS_UNLOCK(ump);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
+ vfs_unbusy(mp);
return (error);
}
VOP_UNLOCK(vp);
@@ -636,6 +640,7 @@ again:
("quotaon: leaking flags"));
UFS_UNLOCK(ump);
+ vfs_unbusy(mp);
return (error);
}
diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c
index 33ef7bc2c3d1..0f45baed634f 100644
--- a/sys/ufs/ufs/ufs_vfsops.c
+++ b/sys/ufs/ufs/ufs_vfsops.c
@@ -87,14 +87,17 @@ ufs_root(mp, flags, vpp)
* Do operations associated with quotas
*/
int
-ufs_quotactl(mp, cmds, id, arg, mp_busy)
+ufs_quotactl(mp, cmds, id, arg)
struct mount *mp;
int cmds;
uid_t id;
void *arg;
- bool *mp_busy;
{
#ifndef QUOTA
+ if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON ||
+ (cmds >> SUBCMDSHIFT) == Q_QUOTAOFF)
+ vfs_unbusy(mp);
+
return (EOPNOTSUPP);
#else
struct thread *td;
@@ -114,23 +117,25 @@ ufs_quotactl(mp, cmds, id, arg, mp_busy)
break;
default:
+ if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF)
+ vfs_unbusy(mp);
return (EINVAL);
}
}
- if ((u_int)type >= MAXQUOTAS)
+ if ((u_int)type >= MAXQUOTAS) {
+ if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF)
+ vfs_unbusy(mp);
return (EINVAL);
+ }
switch (cmd) {
case Q_QUOTAON:
- error = quotaon(td, mp, type, arg, mp_busy);
+ error = quotaon(td, mp, type, arg);
break;
case Q_QUOTAOFF:
vfs_ref(mp);
- KASSERT(*mp_busy,
- ("%s called without busied mount", __func__));
vfs_unbusy(mp);
- *mp_busy = false;
vn_start_write(NULL, &mp, V_WAIT | V_MNTREF);
error = quotaoff(td, mp, type);
vn_finished_write(mp);