summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2006-03-31 03:54:20 +0000
committerjeff <jeff@FreeBSD.org>2006-03-31 03:54:20 +0000
commit32b1878006f50d14c52851c90a362f1012c69f43 (patch)
treedb33a736e9b94a3a4157303b09a71a143008ad95
parentb9e82e7feff34d930f11589e465848e6fe444742 (diff)
downloadFreeBSD-src-32b1878006f50d14c52851c90a362f1012c69f43.zip
FreeBSD-src-32b1878006f50d14c52851c90a362f1012c69f43.tar.gz
- Release the references acquired by VOP_GETWRITEMOUNT and vfs_getvfs().
Discussed with: tegge Tested by: kris Sponsored by: Isilon Systems, Inc.
-rw-r--r--sys/kern/vfs_extattr.c25
-rw-r--r--sys/kern/vfs_syscalls.c25
-rw-r--r--sys/kern/vfs_vnops.c18
-rw-r--r--sys/nfsserver/nfs_serv.c11
-rw-r--r--sys/nfsserver/nfs_srvsubs.c6
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c1
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c7
7 files changed, 62 insertions, 31 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index bc5a904..35f381e 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -276,6 +276,8 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
*buf = *sp;
out:
VFS_UNLOCK_GIANT(vfslocked);
+ if (mtx_owned(&Giant))
+ printf("statfs(%d): %s: %d\n", vfslocked, path, error);
return (error);
}
@@ -2088,6 +2090,8 @@ kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
NDFREE(&nd, NDF_ONLY_PNBUF);
vput(nd.ni_vp);
VFS_UNLOCK_GIANT(vfslocked);
+ if (mtx_owned(&Giant))
+ printf("stat(%d): %s\n", vfslocked, path);
if (error)
return (error);
*sbp = sb;
@@ -4059,12 +4063,9 @@ fhopen(td, uap)
if (error)
return(error);
/* find the mount point */
- vfslocked = 0;
mp = vfs_getvfs(&fhp.fh_fsid);
- if (mp == NULL) {
- error = ESTALE;
- goto out;
- }
+ if (mp == NULL)
+ return (ESTALE);
vfslocked = VFS_LOCK_GIANT(mp);
/* now give me my vnode, it gets returned to me locked */
error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
@@ -4196,6 +4197,7 @@ fhopen(td, uap)
VOP_UNLOCK(vp, 0, td);
fdrop(fp, td);
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
td->td_retval[0] = indx;
return (0);
@@ -4203,6 +4205,7 @@ fhopen(td, uap)
bad:
vput(vp);
out:
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -4243,11 +4246,13 @@ fhstat(td, uap)
return (ESTALE);
vfslocked = VFS_LOCK_GIANT(mp);
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) {
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
vput(vp);
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
if (error)
return (error);
@@ -4305,17 +4310,11 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
error = VFS_FHTOVP(mp, &fh.fh_fid, &vp);
if (error) {
VFS_UNLOCK_GIANT(vfslocked);
+ vfs_rel(mp);
return (error);
}
- sp = NULL;
- mp = vp->v_mount;
- if (mp)
- vfs_ref(mp);
vput(vp);
- if (mp == NULL) {
- VFS_UNLOCK_GIANT(vfslocked);
- return (EBADF);
- }
+ sp = NULL;
error = prison_canseemount(td->td_ucred, mp);
if (error)
goto out;
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index bc5a904..35f381e 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -276,6 +276,8 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
*buf = *sp;
out:
VFS_UNLOCK_GIANT(vfslocked);
+ if (mtx_owned(&Giant))
+ printf("statfs(%d): %s: %d\n", vfslocked, path, error);
return (error);
}
@@ -2088,6 +2090,8 @@ kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
NDFREE(&nd, NDF_ONLY_PNBUF);
vput(nd.ni_vp);
VFS_UNLOCK_GIANT(vfslocked);
+ if (mtx_owned(&Giant))
+ printf("stat(%d): %s\n", vfslocked, path);
if (error)
return (error);
*sbp = sb;
@@ -4059,12 +4063,9 @@ fhopen(td, uap)
if (error)
return(error);
/* find the mount point */
- vfslocked = 0;
mp = vfs_getvfs(&fhp.fh_fsid);
- if (mp == NULL) {
- error = ESTALE;
- goto out;
- }
+ if (mp == NULL)
+ return (ESTALE);
vfslocked = VFS_LOCK_GIANT(mp);
/* now give me my vnode, it gets returned to me locked */
error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
@@ -4196,6 +4197,7 @@ fhopen(td, uap)
VOP_UNLOCK(vp, 0, td);
fdrop(fp, td);
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
td->td_retval[0] = indx;
return (0);
@@ -4203,6 +4205,7 @@ fhopen(td, uap)
bad:
vput(vp);
out:
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -4243,11 +4246,13 @@ fhstat(td, uap)
return (ESTALE);
vfslocked = VFS_LOCK_GIANT(mp);
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) {
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
vput(vp);
+ vfs_rel(mp);
VFS_UNLOCK_GIANT(vfslocked);
if (error)
return (error);
@@ -4305,17 +4310,11 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
error = VFS_FHTOVP(mp, &fh.fh_fid, &vp);
if (error) {
VFS_UNLOCK_GIANT(vfslocked);
+ vfs_rel(mp);
return (error);
}
- sp = NULL;
- mp = vp->v_mount;
- if (mp)
- vfs_ref(mp);
vput(vp);
- if (mp == NULL) {
- VFS_UNLOCK_GIANT(vfslocked);
- return (EBADF);
- }
+ sp = NULL;
error = prison_canseemount(td->td_ucred, mp);
if (error)
goto out;
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 4771c3f..752b070 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -889,6 +889,8 @@ vn_start_write(vp, mpp, flags)
if ((mp = *mpp) == NULL)
return (0);
MNT_ILOCK(mp);
+ if (vp == NULL)
+ MNT_REF(mp);
/*
* Check on status of suspension.
*/
@@ -906,6 +908,7 @@ vn_start_write(vp, mpp, flags)
goto unlock;
mp->mnt_writeopcount++;
unlock:
+ MNT_REL(mp);
MNT_IUNLOCK(mp);
return (error);
}
@@ -939,19 +942,25 @@ vn_write_suspend_wait(vp, mp, flags)
if (mp == NULL)
return (0);
MNT_ILOCK(mp);
+ if (vp == NULL)
+ MNT_REF(mp);
if ((mp->mnt_kern_flag & MNTK_SUSPENDED) == 0) {
+ MNT_REL(mp);
MNT_IUNLOCK(mp);
return (0);
}
if (flags & V_NOWAIT) {
+ MNT_REL(mp);
MNT_IUNLOCK(mp);
return (EWOULDBLOCK);
}
/*
* Wait for the suspension to finish.
*/
- return (msleep(&mp->mnt_flag, MNT_MTX(mp),
- (PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0));
+ error = msleep(&mp->mnt_flag, MNT_MTX(mp),
+ (PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0);
+ vfs_rel(mp);
+ return (error);
}
/*
@@ -986,13 +995,17 @@ vn_start_secondary_write(vp, mpp, flags)
if ((mp = *mpp) == NULL)
return (0);
MNT_ILOCK(mp);
+ if (vp == NULL)
+ MNT_REF(mp);
if ((mp->mnt_kern_flag & (MNTK_SUSPENDED | MNTK_SUSPEND2)) == 0) {
mp->mnt_secondary_writes++;
mp->mnt_secondary_accwrites++;
+ MNT_REL(mp);
MNT_IUNLOCK(mp);
return (0);
}
if (flags & V_NOWAIT) {
+ MNT_REL(mp);
MNT_IUNLOCK(mp);
return (EWOULDBLOCK);
}
@@ -1001,6 +1014,7 @@ vn_start_secondary_write(vp, mpp, flags)
*/
error = msleep(&mp->mnt_flag, MNT_MTX(mp),
(PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0);
+ vfs_rel(mp);
if (error == 0)
goto retry;
return (error);
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index f7597e4..3b8285f 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -338,6 +338,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
VATTR_NULL(vap);
@@ -1103,6 +1104,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mntp, V_WAIT);
+ vfs_rel(mntp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
if (v3) {
@@ -1754,6 +1756,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_srvnamesiz(len);
@@ -2058,6 +2061,7 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_srvnamesiz(len);
@@ -2260,6 +2264,7 @@ nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_srvnamesiz(len);
@@ -2394,6 +2399,7 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant);
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant);
NFSD_LOCK();
nfsm_srvnamesiz(len);
@@ -2637,6 +2643,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_srvmtofh(dfhp);
@@ -2801,6 +2808,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_srvnamesiz(len);
@@ -2991,6 +2999,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_srvnamesiz(len);
@@ -3164,6 +3173,7 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_srvnamesiz(len);
@@ -4024,6 +4034,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
(void) vn_start_write(NULL, &mp, V_WAIT);
+ vfs_rel(mp); /* The write holds a ref. */
mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED);
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index 1aa976a..375a1d2 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -1069,6 +1069,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp,
int i;
struct ucred *credanon;
int error, exflags;
+ int vfslocked;
#ifdef MNT_EXNORESPORT /* XXX needs mountd and /etc/exports help yet */
struct sockaddr_int *saddr;
#endif
@@ -1087,7 +1088,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp,
if (!mp)
return (ESTALE);
NFSD_UNLOCK();
- mtx_lock(&Giant); /* VFS */
+ vfslocked = VFS_LOCK_GIANT(mp);
error = VFS_CHECKEXP(mp, nam, &exflags, &credanon);
if (error)
goto out;
@@ -1124,7 +1125,8 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp,
if (!lockflag)
VOP_UNLOCK(*vpp, 0, td);
out:
- mtx_unlock(&Giant); /* VFS */
+ vfs_rel(mp);
+ VFS_UNLOCK_GIANT(vfslocked);
NFSD_LOCK();
return (error);
}
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 16e953e..77e7ad1 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -259,6 +259,7 @@ restart:
wrtmp = NULL;
if (wrtmp != mp)
panic("ffs_snapshot: mount mismatch");
+ vfs_rel(wrtmp);
if (vn_start_write(NULL, &wrtmp, V_NOWAIT) != 0) {
NDFREE(&nd, NDF_ONLY_PNBUF);
vput(nd.ni_dvp);
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index ae7f148..0d8372a 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -600,6 +600,7 @@ ffs_mountfs(devvp, mp, td)
int32_t *lp;
struct ucred *cred;
struct g_consumer *cp;
+ struct mount *nmp;
dev = devvp->v_rdev;
cred = td ? td->td_ucred : NOCRED;
@@ -749,9 +750,13 @@ ffs_mountfs(devvp, mp, td)
mp->mnt_data = (qaddr_t)ump;
mp->mnt_stat.f_fsid.val[0] = fs->fs_id[0];
mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1];
+ nmp = NULL;
if (fs->fs_id[0] == 0 || fs->fs_id[1] == 0 ||
- vfs_getvfs(&mp->mnt_stat.f_fsid))
+ (nmp = vfs_getvfs(&mp->mnt_stat.f_fsid))) {
+ if (nmp)
+ vfs_rel(nmp);
vfs_getnewfsid(mp);
+ }
mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
mp->mnt_flag |= MNT_LOCAL;
if ((fs->fs_flags & FS_MULTILABEL) != 0)
OpenPOWER on IntegriCloud