aboutsummaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2012-01-08 23:06:53 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2012-01-08 23:06:53 +0000
commit3ab0160340cfc7704bb2b3fb1d5daf12eec75267 (patch)
tree628b27022e4f620628af64c85c5a17f7aaee3d3d /sys/ufs
parenta194b02d8860dc2c494f8bc8ebb782d6e19bf30d (diff)
Notes
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/ufs_quota.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index 59e89f965031..ce89efaccb6b 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -512,17 +512,29 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname)
NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_USERSPACE, fname, td);
flags = FREAD | FWRITE;
+ vfs_ref(mp);
+ vfs_unbusy(mp);
error = vn_open(&nd, &flags, 0, NULL);
- if (error)
+ if (error != 0) {
+ vfs_rel(mp);
return (error);
+ }
vfslocked = NDHASGIANT(&nd);
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
- if (vp->v_type != VREG) {
+ error = vfs_busy(mp, MBF_NOWAIT);
+ vfs_rel(mp);
+ if (error == 0) {
+ if (vp->v_type != VREG) {
+ error = EACCES;
+ vfs_unbusy(mp);
+ }
+ }
+ if (error != 0) {
VOP_UNLOCK(vp, 0);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
VFS_UNLOCK_GIANT(vfslocked);
- return (EACCES);
+ return (error);
}
UFS_LOCK(ump);
@@ -531,6 +543,7 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname)
VOP_UNLOCK(vp, 0);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
VFS_UNLOCK_GIANT(vfslocked);
+ vfs_unbusy(mp);
return (EALREADY);
}
ump->um_qflags[type] |= QTF_OPENING|QTF_CLOSING;
@@ -542,6 +555,7 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname)
UFS_UNLOCK(ump);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
VFS_UNLOCK_GIANT(vfslocked);
+ vfs_unbusy(mp);
return (error);
}
VOP_UNLOCK(vp, 0);
@@ -619,6 +633,7 @@ again:
("quotaon: leaking flags"));
UFS_UNLOCK(ump);
+ vfs_unbusy(mp);
return (error);
}