summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2006-03-31 03:53:25 +0000
committerjeff <jeff@FreeBSD.org>2006-03-31 03:53:25 +0000
commitb9e82e7feff34d930f11589e465848e6fe444742 (patch)
tree17e0691710ce344ab5075eb186e66cf710795c4f /sys
parentd018a9a82031a9c4b99602056e747592e74b6b80 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_subr.c12
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,
OpenPOWER on IntegriCloud