diff options
author | Jeff Roberson <jeff@FreeBSD.org> | 2006-02-23 05:18:07 +0000 |
---|---|---|
committer | Jeff Roberson <jeff@FreeBSD.org> | 2006-02-23 05:18:07 +0000 |
commit | 8febcfb92fb9a85b729a6ded4a014202b50a2060 (patch) | |
tree | f4cacdff42abbfc05f688fe2477274fa4ca3844a /sys/kern/vfs_syscalls.c | |
parent | a1db11fc4089a6c6ddc476d739ed960a4eae8fae (diff) | |
download | src-test2-8febcfb92fb9a85b729a6ded4a014202b50a2060.tar.gz src-test2-8febcfb92fb9a85b729a6ded4a014202b50a2060.zip |
Notes
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r-- | sys/kern/vfs_syscalls.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index e35d7c1d2676..479c3de7bd9b 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -249,19 +249,20 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, struct nameidata nd; mtx_lock(&Giant); - NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, pathseg, path, td); error = namei(&nd); if (error) { mtx_unlock(&Giant); return (error); } mp = nd.ni_vp->v_mount; - sp = &mp->mnt_stat; + vfs_ref(mp); NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); + vput(nd.ni_vp); #ifdef MAC error = mac_check_mount_stat(td->td_ucred, mp); if (error) { + vfs_rel(mp); mtx_unlock(&Giant); return (error); } @@ -269,10 +270,12 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, /* * Set these in case the underlying filesystem fails to do so. */ + sp = &mp->mnt_stat; sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp, td); + vfs_rel(mp); if (error) { mtx_unlock(&Giant); return (error); @@ -327,32 +330,40 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) error = getvnode(td->td_proc->p_fd, fd, &fp); if (error) return (error); + mtx_lock(&Giant); vp = fp->f_vnode; -#ifdef AUDIT vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); +#ifdef AUDIT AUDIT_ARG(vnode, vp, ARG_VNODE1); - VOP_UNLOCK(vp, 0, td); #endif mp = vp->v_mount; + if (mp) + vfs_ref(mp); + VOP_UNLOCK(vp, 0, td); fdrop(fp, td); - if (vp->v_iflag & VI_DOOMED) + if (vp->v_iflag & VI_DOOMED) { + if (mp) + vfs_rel(mp); + mtx_unlock(&Giant); return (EBADF); - mtx_lock(&Giant); + } #ifdef MAC error = mac_check_mount_stat(td->td_ucred, mp); if (error) { + vfs_rel(mp); mtx_unlock(&Giant); return (error); } #endif - sp = &mp->mnt_stat; /* * Set these in case the underlying filesystem fails to do so. */ + sp = &mp->mnt_stat; sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp, td); + vfs_rel(mp); if (error) { mtx_unlock(&Giant); return (error); @@ -4312,14 +4323,20 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) return (error); } mp = vp->v_mount; - sp = &mp->mnt_stat; + if (mp) + vfs_ref(mp); vput(vp); + if (mp == NULL) + return (EBADF); error = prison_canseemount(td->td_ucred, mp); - if (error) + if (error) { + vfs_rel(mp); return (error); + } #ifdef MAC error = mac_check_mount_stat(td->td_ucred, mp); if (error) { + vfs_rel(mp); mtx_unlock(&Giant); return (error); } @@ -4327,10 +4344,12 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) /* * Set these in case the underlying filesystem fails to do so. */ + sp = &mp->mnt_stat; sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp, td); + vfs_rel(mp); mtx_unlock(&Giant); if (error) return (error); |