diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_syscalls.c | 106 |
1 files changed, 41 insertions, 65 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index f2ddf66..262b235 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -256,6 +256,45 @@ statfs_scale_blocks(struct statfs *sf, long max_size) sf->f_bavail >>= shift; } +static int +kern_do_statfs(struct thread *td, struct mount *mp, struct statfs *buf) +{ + struct statfs *sp, sb; + int error; + + if (mp == NULL) + return (EBADF); + error = vfs_busy(mp, 0); + vfs_rel(mp); + if (error != 0) + return (error); +#ifdef MAC + error = mac_mount_check_stat(td->td_ucred, mp); + if (error != 0) + goto out; +#endif + /* + * 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); + if (error != 0) + goto out; + if (priv_check(td, PRIV_VFS_GENERATION)) { + bcopy(sp, &sb, sizeof(sb)); + sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; + prison_enforce_statfs(td->td_ucred, mp, &sb); + sp = &sb; + } + *buf = *sp; +out: + vfs_unbusy(mp); + return (error); +} + /* * Get filesystem statistics. */ @@ -287,7 +326,6 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, struct statfs *buf) { struct mount *mp; - struct statfs *sp, sb; struct nameidata nd; int error; @@ -300,35 +338,7 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, vfs_ref(mp); NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); - error = vfs_busy(mp, 0); - vfs_rel(mp); - if (error != 0) - return (error); -#ifdef MAC - error = mac_mount_check_stat(td->td_ucred, mp); - if (error != 0) - goto out; -#endif - /* - * 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); - if (error != 0) - goto out; - if (priv_check(td, PRIV_VFS_GENERATION)) { - bcopy(sp, &sb, sizeof(sb)); - sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; - prison_enforce_statfs(td->td_ucred, mp, &sb); - sp = &sb; - } - *buf = *sp; -out: - vfs_unbusy(mp); - return (error); + return (kern_do_statfs(td, mp, buf)); } /* @@ -362,7 +372,6 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) { struct file *fp; struct mount *mp; - struct statfs *sp, sb; struct vnode *vp; cap_rights_t rights; int error; @@ -382,40 +391,7 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) vfs_ref(mp); VOP_UNLOCK(vp, 0); fdrop(fp, td); - if (mp == NULL) { - error = EBADF; - goto out; - } - error = vfs_busy(mp, 0); - vfs_rel(mp); - if (error != 0) - return (error); -#ifdef MAC - error = mac_mount_check_stat(td->td_ucred, mp); - if (error != 0) - goto out; -#endif - /* - * 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); - if (error != 0) - goto out; - if (priv_check(td, PRIV_VFS_GENERATION)) { - bcopy(sp, &sb, sizeof(sb)); - sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; - prison_enforce_statfs(td->td_ucred, mp, &sb); - sp = &sb; - } - *buf = *sp; -out: - if (mp) - vfs_unbusy(mp); - return (error); + return (kern_do_statfs(td, mp, buf)); } /* |