diff options
author | jeff <jeff@FreeBSD.org> | 2006-03-31 03:53:25 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2006-03-31 03:53:25 +0000 |
commit | b9e82e7feff34d930f11589e465848e6fe444742 (patch) | |
tree | 17e0691710ce344ab5075eb186e66cf710795c4f | |
parent | d018a9a82031a9c4b99602056e747592e74b6b80 (diff) | |
download | FreeBSD-src-b9e82e7feff34d930f11589e465848e6fe444742.zip FreeBSD-src-b9e82e7feff34d930f11589e465848e6fe444742.tar.gz |
- Hold a reference from the time vfs_busy starts until vfs_unbusy is
called.
- vfs_getvfs has to return a reference to prevent the returned mountpoint
from changing identities.
- Release references acquired via vfs_getvfs.
Discussed with: tegge
Tested by: kris
Sponsored by: Isilon Systems, Inc.
-rw-r--r-- | sys/kern/vfs_subr.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 8dbee34..385808d 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -362,7 +362,6 @@ vfs_busy(struct mount *mp, int flags, struct mtx *interlkp, lkflags = LK_SHARED | LK_INTERLOCK; if (lockmgr(&mp->mnt_lock, lkflags, MNT_MTX(mp), td)) panic("vfs_busy: unexpected lock failure"); - vfs_rel(mp); return (0); } @@ -374,6 +373,7 @@ vfs_unbusy(struct mount *mp, struct thread *td) { lockmgr(&mp->mnt_lock, LK_RELEASE, NULL, td); + vfs_rel(mp); } /* @@ -388,6 +388,7 @@ vfs_getvfs(fsid_t *fsid) TAILQ_FOREACH(mp, &mountlist, mnt_list) { if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] && mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) { + vfs_ref(mp); mtx_unlock(&mountlist_mtx); return (mp); } @@ -428,6 +429,7 @@ void vfs_getnewfsid(struct mount *mp) { static u_int16_t mntid_base; + struct mount *nmp; fsid_t tfsid; int mtype; @@ -439,8 +441,9 @@ vfs_getnewfsid(struct mount *mp) tfsid.val[0] = makedev(255, mtype | ((mntid_base & 0xFF00) << 8) | (mntid_base & 0xFF)); mntid_base++; - if (vfs_getvfs(&tfsid) == NULL) + if ((nmp = vfs_getvfs(&tfsid)) == NULL) break; + vfs_rel(nmp); } mp->mnt_stat.f_fsid.val[0] = tfsid.val[0]; mp->mnt_stat.f_fsid.val[1] = tfsid.val[1]; @@ -3686,10 +3689,13 @@ sysctl_vfs_ctl(SYSCTL_HANDLER_ARGS) /* ensure that a specific sysctl goes to the right filesystem. */ if (strcmp(vc.vc_fstypename, "*") != 0 && strcmp(vc.vc_fstypename, mp->mnt_vfc->vfc_name) != 0) { + vfs_rel(mp); return (EINVAL); } VCTLTOREQ(&vc, req); - return (VFS_SYSCTL(mp, vc.vc_op, req)); + error = VFS_SYSCTL(mp, vc.vc_op, req); + vfs_rel(mp); + return (error); } SYSCTL_PROC(_vfs, OID_AUTO, ctl, CTLFLAG_WR, |