diff options
author | jeff <jeff@FreeBSD.org> | 2006-03-31 03:54:20 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2006-03-31 03:54:20 +0000 |
commit | 32b1878006f50d14c52851c90a362f1012c69f43 (patch) | |
tree | db33a736e9b94a3a4157303b09a71a143008ad95 | |
parent | b9e82e7feff34d930f11589e465848e6fe444742 (diff) | |
download | FreeBSD-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.c | 25 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 25 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 18 | ||||
-rw-r--r-- | sys/nfsserver/nfs_serv.c | 11 | ||||
-rw-r--r-- | sys/nfsserver/nfs_srvsubs.c | 6 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_snapshot.c | 1 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 7 |
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) |