From d9fad06efb17ebed7dc91f2c8ed986184e89e0a1 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 1 Jun 2008 19:27:37 +0000 Subject: [PATCH] * Implement new system calls in the kernel: statvfs(), fstatvfs(), fhstatvfs(). * Implement a new VFS op, VFS_STATVFS(). Implement a default for this new op for VFSs which do not implement VFS_STATVFS(), which calls VFS_STATFS() and converts the structure (using Joerg's conversion procedure from libc). * Remove statvfs(), fstatvfs(), and fhstatvfs() from libc. These functions are now system calls. --- lib/libc/include/libc_private.h | 4 +- lib/libc/sys/Makefile.inc | 3 +- lib/libc/sys/__cvtstatvfs.c | 90 ------------------- lib/libc/sys/fstatvfs.c | 53 ----------- lib/libc/sys/statvfs.c | 53 ----------- sys/kern/init_sysent.c | 6 +- sys/kern/syscalls.c | 5 +- sys/kern/syscalls.master | 6 +- sys/kern/vfs_default.c | 70 ++++++++++++++- sys/kern/vfs_init.c | 6 +- sys/kern/vfs_syscalls.c | 150 +++++++++++++++++++++++++++++++- sys/sys/kern_syscall.h | 5 +- sys/sys/mount.h | 16 +++- sys/sys/mountctl.h | 3 +- sys/sys/syscall-hide.h | 5 +- sys/sys/syscall.h | 7 +- sys/sys/syscall.mk | 7 +- sys/sys/sysproto.h | 26 +++++- sys/sys/sysunion.h | 5 +- 19 files changed, 300 insertions(+), 220 deletions(-) delete mode 100644 lib/libc/sys/__cvtstatvfs.c delete mode 100644 lib/libc/sys/fstatvfs.c delete mode 100644 lib/libc/sys/statvfs.c diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index c4f0219771..ec87234961 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libc/include/libc_private.h,v 1.3 1999/08/27 23:59:47 peter Exp $ - * $DragonFly: src/lib/libc/include/libc_private.h,v 1.7 2005/07/21 21:33:26 joerg Exp $ + * $DragonFly: src/lib/libc/include/libc_private.h,v 1.8 2008/06/01 19:27:32 dillon Exp $ * * Private definitions for libc, libc_r and libpthread. * @@ -81,6 +81,4 @@ void *__get_errno_GOT_ptr(void); struct statfs; struct statvfs; -void __cvtstatvfs(const struct statfs *, struct statvfs *); - #endif /* _LIBC_PRIVATE_H_ */ diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index e32bfefd9f..67d280cf2f 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,6 +1,6 @@ # @(#)Makefile.inc 8.3 (Berkeley) 10/24/94 # $FreeBSD: src/lib/libc/sys/Makefile.inc,v 1.75.2.7 2003/04/22 17:31:18 trhodes Exp $ -# $DragonFly: src/lib/libc/sys/Makefile.inc,v 1.32 2008/02/22 05:19:25 swildner Exp $ +# $DragonFly: src/lib/libc/sys/Makefile.inc,v 1.33 2008/06/01 19:27:33 dillon Exp $ # sys sources .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys ${.CURDIR}/../libc/sys @@ -19,7 +19,6 @@ # Sources common to both syscall interfaces: SRCS+= ftruncate.c lseek.c mmap.c truncate.c SRCS+= pread.c pwrite.c preadv.c pwritev.c -SRCS+= __cvtstatvfs.c fstatvfs.c statvfs.c # Add machine dependent asm sources: SRCS+=${MDASM} diff --git a/lib/libc/sys/__cvtstatvfs.c b/lib/libc/sys/__cvtstatvfs.c deleted file mode 100644 index d7bd4aca94..0000000000 --- a/lib/libc/sys/__cvtstatvfs.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2005 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Joerg Sonnenberger . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/lib/libc/sys/Attic/__cvtstatvfs.c,v 1.1 2005/07/21 21:33:26 joerg Exp $ - */ - -#include -#include -#include - -#include - -#include "libc_private.h" - -void -__cvtstatvfs(const struct statfs *in, struct statvfs *out) -{ - memset(out, 0, sizeof(*out)); - - out->f_bsize = in->f_bsize; - out->f_frsize = in->f_bsize; - out->f_blocks = in->f_blocks; - out->f_bfree = in->f_bfree; - out->f_bavail = in->f_bavail; - out->f_files = in->f_files; - out->f_ffree = in->f_ffree; - /* - * XXX - * This field counts the number of available inodes to non-root - * users, but this information is not available via statfs. - * Just ignore this issue by returning the totoal number instead. - */ - out->f_favail = in->f_ffree; - /* - * XXX - * This field has a different meaning for statfs and statvfs. - * For the former it is the cookie exported for NFS and not - * intended for normal userland use. - */ - out->f_fsid = 0; - - out->f_flag = 0; - if (in->f_flags & MNT_RDONLY) - out->f_flag |= ST_RDONLY; - if (in->f_flags & MNT_NOSUID) - out->f_flag |= ST_NOSUID; - out->f_namemax = 0; - out->f_owner = in->f_owner; - /* - * XXX - * statfs contains the type as string, statvfs expects it as - * enumeration. - */ - out->f_type = 0; - - out->f_syncreads = in->f_syncreads; - out->f_syncwrites = in->f_syncwrites; - out->f_asyncreads = in->f_asyncreads; - out->f_asyncwrites = in->f_asyncwrites; -} diff --git a/lib/libc/sys/fstatvfs.c b/lib/libc/sys/fstatvfs.c deleted file mode 100644 index 3aa119e064..0000000000 --- a/lib/libc/sys/fstatvfs.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2005 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Joerg Sonnenberger . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/lib/libc/sys/Attic/fstatvfs.c,v 1.1 2005/07/21 21:33:26 joerg Exp $ - */ - -#include -#include -#include - -#include "libc_private.h" - -int -fstatvfs(int fd, struct statvfs *vfs) -{ - struct statfs sfs; - - if (fstatfs(fd, &sfs)) - return(-1); - - __cvtstatvfs(&sfs, vfs); - return(0); -} diff --git a/lib/libc/sys/statvfs.c b/lib/libc/sys/statvfs.c deleted file mode 100644 index 055d7d9ff3..0000000000 --- a/lib/libc/sys/statvfs.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2005 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Joerg Sonnenberger . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/lib/libc/sys/Attic/statvfs.c,v 1.1 2005/07/21 21:33:26 joerg Exp $ - */ - -#include -#include -#include - -#include "libc_private.h" - -int -statvfs(const char * __restrict path, struct statvfs * __restrict vfs) -{ - struct statfs sfs; - - if (statfs(path, &sfs)) - return(-1); - - __cvtstatvfs(&sfs, vfs); - return(0); -} diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 3179b1604f..88cfb6b47b 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/init_sysent.c,v 1.60 2008/05/19 10:19:49 corecode Exp $ + * $DragonFly: src/sys/kern/init_sysent.c,v 1.61 2008/06/01 19:27:35 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp */ @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -534,4 +535,7 @@ struct sysent sysent[] = { { AS(lwp_kill_args), (sy_call_t *)sys_lwp_kill }, /* 497 = lwp_kill */ { AS(lwp_rtprio_args), (sy_call_t *)sys_lwp_rtprio }, /* 498 = lwp_rtprio */ { AS(pselect_args), (sy_call_t *)sys_pselect }, /* 499 = pselect */ + { AS(statvfs_args), (sy_call_t *)sys_statvfs }, /* 500 = statvfs */ + { AS(fstatvfs_args), (sy_call_t *)sys_fstatvfs }, /* 501 = fstatvfs */ + { AS(fhstatvfs_args), (sy_call_t *)sys_fhstatvfs }, /* 502 = fhstatvfs */ }; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index c8f3e94be8..65939a5eed 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -2,7 +2,7 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/syscalls.c,v 1.59 2008/05/19 10:19:49 corecode Exp $ + * $DragonFly: src/sys/kern/syscalls.c,v 1.60 2008/06/01 19:27:35 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp */ @@ -509,4 +509,7 @@ char *syscallnames[] = { "lwp_kill", /* 497 = lwp_kill */ "lwp_rtprio", /* 498 = lwp_rtprio */ "pselect", /* 499 = pselect */ + "statvfs", /* 500 = statvfs */ + "fstatvfs", /* 501 = fstatvfs */ + "fhstatvfs", /* 502 = fhstatvfs */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index e8ace9745c..7ccd563d4f 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp $ + $DragonFly: src/sys/kern/syscalls.master,v 1.58 2008/06/01 19:27:35 dillon Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; $FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.10 2002/07/12 08:22:46 alfred Exp $ @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef COMPAT_43 #include @@ -684,3 +685,6 @@ 499 STD BSD { int pselect(int nd, fd_set *in, fd_set *ou, \ fd_set *ex, const struct timespec *ts, \ const sigset_t *sigmask); } +500 STD BSD { int statvfs(const char *path, struct statvfs *buf); } +501 STD BSD { int fstatvfs(int fd, struct statvfs *buf); } +502 STD BSD { int fhstatvfs(const struct fhandle *u_fhp, struct statvfs *buf); } diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index ee24f5401f..8f655b1fc0 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -5,7 +5,8 @@ * This code is derived from software contributed * to Berkeley by John Heidemann of the UCLA Ficus project. * - * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project + * The statvfs->statfs conversion code was contributed to the DragonFly + * Project by Joerg Sonnenberger . * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,9 +36,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * + * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $ - * $DragonFly: src/sys/kern/vfs_default.c,v 1.52 2008/01/18 19:13:16 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_default.c,v 1.53 2008/06/01 19:27:35 dillon Exp $ */ #include @@ -1291,6 +1292,69 @@ vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) return (EOPNOTSUPP); } +/* + * If the VFS does not implement statvfs, then call statfs and convert + * the values. This code was taken from libc's __cvtstatvfs() function, + * contributed by Joerg Sonnenberger. + */ +int +vfs_stdstatvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred) +{ + struct statfs *in; + int error; + + in = &mp->mnt_stat; + error = VFS_STATFS(mp, in, cred); + if (error == 0) { + bzero(sbp, sizeof(*sbp)); + + sbp->f_bsize = in->f_bsize; + sbp->f_frsize = in->f_bsize; + sbp->f_blocks = in->f_blocks; + sbp->f_bfree = in->f_bfree; + sbp->f_bavail = in->f_bavail; + sbp->f_files = in->f_files; + sbp->f_ffree = in->f_ffree; + + /* + * XXX + * This field counts the number of available inodes to non-root + * users, but this information is not available via statfs. + * Just ignore this issue by returning the total number + * instead. + */ + sbp->f_favail = in->f_ffree; + + /* + * XXX + * This field has a different meaning for statfs and statvfs. + * For the former it is the cookie exported for NFS and not + * intended for normal userland use. + */ + sbp->f_fsid = 0; + + sbp->f_flag = 0; + if (in->f_flags & MNT_RDONLY) + sbp->f_flag |= ST_RDONLY; + if (in->f_flags & MNT_NOSUID) + sbp->f_flag |= ST_NOSUID; + sbp->f_namemax = 0; + sbp->f_owner = in->f_owner; + /* + * XXX + * statfs contains the type as string, statvfs expects it as + * enumeration. + */ + sbp->f_type = 0; + + sbp->f_syncreads = in->f_syncreads; + sbp->f_syncwrites = in->f_syncwrites; + sbp->f_asyncreads = in->f_asyncreads; + sbp->f_asyncwrites = in->f_asyncwrites; + } + return (error); +} + int vfs_stdvptofh(struct vnode *vp, struct fid *fhp) { diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index e85c58638d..c85aea63b4 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -70,7 +70,7 @@ * * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94 * $FreeBSD: src/sys/kern/vfs_init.c,v 1.59 2002/04/30 18:44:32 dillon Exp $ - * $DragonFly: src/sys/kern/vfs_init.c,v 1.14 2006/09/05 00:55:45 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_init.c,v 1.15 2008/06/01 19:27:35 dillon Exp $ */ /* * Manage vnode VOP operations vectors @@ -315,6 +315,10 @@ vfs_register(struct vfsconf *vfc) /* return file system's status */ vfsops->vfs_statfs = vfs_stdstatfs; } + if (vfsops->vfs_statvfs == NULL) { + /* return file system's status */ + vfsops->vfs_statvfs = vfs_stdstatvfs; + } if (vfsops->vfs_sync == NULL) { /* * Flush dirty buffers. File systems can use vfs_stdsync() diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 7d1bba0beb..0706ca327e 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -37,7 +37,7 @@ * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.127 2008/05/18 05:54:25 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.128 2008/06/01 19:27:35 dillon Exp $ */ #include @@ -1128,6 +1128,107 @@ sys_fstatfs(struct fstatfs_args *uap) return (error); } +int +kern_statvfs(struct nlookupdata *nd, struct statvfs *buf) +{ + struct mount *mp; + struct statvfs *sp; + int error; + + if ((error = nlookup(nd)) != 0) + return (error); + mp = nd->nl_nch.mount; + sp = &mp->mnt_vstat; + if ((error = VFS_STATVFS(mp, sp, nd->nl_cred)) != 0) + return (error); + + sp->f_flag = 0; + if (mp->mnt_flag & MNT_RDONLY) + sp->f_flag |= ST_RDONLY; + if (mp->mnt_flag & MNT_NOSUID) + sp->f_flag |= ST_NOSUID; + bcopy(sp, buf, sizeof(*buf)); + return (0); +} + +/* + * statfs_args(char *path, struct statfs *buf) + * + * Get filesystem statistics. + */ +int +sys_statvfs(struct statvfs_args *uap) +{ + struct nlookupdata nd; + struct statvfs buf; + int error; + + error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW); + if (error == 0) + error = kern_statvfs(&nd, &buf); + nlookup_done(&nd); + if (error == 0) + error = copyout(&buf, uap->buf, sizeof(*uap->buf)); + return (error); +} + +int +kern_fstatvfs(int fd, struct statvfs *buf) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + struct file *fp; + struct mount *mp; + struct statvfs *sp; + int error; + + KKASSERT(p); + if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) + return (error); + mp = ((struct vnode *)fp->f_data)->v_mount; + if (mp == NULL) { + error = EBADF; + goto done; + } + if (fp->f_cred == NULL) { + error = EINVAL; + goto done; + } + sp = &mp->mnt_vstat; + if ((error = VFS_STATVFS(mp, sp, fp->f_cred)) != 0) + goto done; + + sp->f_flag = 0; + if (mp->mnt_flag & MNT_RDONLY) + sp->f_flag |= ST_RDONLY; + if (mp->mnt_flag & MNT_NOSUID) + sp->f_flag |= ST_NOSUID; + + bcopy(sp, buf, sizeof(*buf)); + error = 0; +done: + fdrop(fp); + return (error); +} + +/* + * fstatfs_args(int fd, struct statfs *buf) + * + * Get filesystem statistics. + */ +int +sys_fstatvfs(struct fstatvfs_args *uap) +{ + struct statvfs buf; + int error; + + error = kern_fstatvfs(uap->fd, &buf); + + if (error == 0) + error = copyout(&buf, uap->buf, sizeof(*uap->buf)); + return (error); +} + /* * getfsstat_args(struct statfs *buf, long bufsize, int flags) * @@ -3621,6 +3722,53 @@ sys_fhstatfs(struct fhstatfs_args *uap) return (copyout(sp, uap->buf, sizeof(*sp))); } +/* + * fhstatvfs_args(struct fhandle *u_fhp, struct statvfs *buf) + */ +int +sys_fhstatvfs(struct fhstatvfs_args *uap) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + struct statvfs *sp; + struct mount *mp; + struct vnode *vp; + fhandle_t fh; + int error; + + /* + * Must be super user + */ + if ((error = suser(td))) + return (error); + + if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) + return (error); + + if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) + return (ESTALE); + + if (p != NULL && !chroot_visible_mnt(mp, p)) + return (ESTALE); + + if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) + return (error); + mp = vp->v_mount; + sp = &mp->mnt_vstat; + vput(vp); + if ((error = VFS_STATVFS(mp, sp, p->p_ucred)) != 0) + return (error); + + sp->f_flag = 0; + if (mp->mnt_flag & MNT_RDONLY) + sp->f_flag |= ST_RDONLY; + if (mp->mnt_flag & MNT_NOSUID) + sp->f_flag |= ST_NOSUID; + + return (copyout(sp, uap->buf, sizeof(*sp))); +} + + /* * Syscall to push extended attribute configuration information into the * VFS. Accepts a path, which it converts to a mountpoint, as well as diff --git a/sys/sys/kern_syscall.h b/sys/sys/kern_syscall.h index 0a7c2883f7..57d9b48274 100644 --- a/sys/sys/kern_syscall.h +++ b/sys/sys/kern_syscall.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/kern_syscall.h,v 1.37 2007/06/16 19:57:08 dillon Exp $ + * $DragonFly: src/sys/sys/kern_syscall.h,v 1.38 2008/06/01 19:27:37 dillon Exp $ */ #ifndef _SYS_KERN_SYSCALL_H_ @@ -64,6 +64,7 @@ struct vnode; struct file; struct ucred; struct uuid; +struct statvfs; /* * Prototypes for syscalls in kern/kern_descrip.c @@ -135,6 +136,7 @@ int kern_chmod(struct nlookupdata *nd, int mode); int kern_chown(struct nlookupdata *nd, int uid, int gid); int kern_chroot(struct nchandle *nch); int kern_fstatfs(int fd, struct statfs *buf); +int kern_fstatvfs(int fd, struct statvfs *buf); int kern_ftruncate(int fd, off_t length); int kern_futimes(int fd, struct timeval *tptr); int kern_getdirentries(int fd, char *buf, u_int count, long *basep, int *res, @@ -155,6 +157,7 @@ int kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond); int kern_rmdir(struct nlookupdata *nd); int kern_stat(struct nlookupdata *nd, struct stat *st); int kern_statfs(struct nlookupdata *nd, struct statfs *buf); +int kern_statvfs(struct nlookupdata *nd, struct statvfs *buf); int kern_symlink(struct nlookupdata *nd, char *path, int mode); int kern_truncate(struct nlookupdata *nd, off_t length); int kern_unlink(struct nlookupdata *nd); diff --git a/sys/sys/mount.h b/sys/sys/mount.h index df099363c0..28180b7e7c 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -32,7 +32,7 @@ * * @(#)mount.h 8.21 (Berkeley) 5/20/95 * $FreeBSD: src/sys/sys/mount.h,v 1.89.2.7 2003/04/04 20:35:57 tegge Exp $ - * $DragonFly: src/sys/sys/mount.h,v 1.39 2008/05/25 18:34:45 dillon Exp $ + * $DragonFly: src/sys/sys/mount.h,v 1.40 2008/06/01 19:27:37 dillon Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -56,6 +56,9 @@ #ifndef _SYS_NAMECACHE_H_ #include #endif +#ifndef _SYS_STATVFS_H_ +#include +#endif #endif struct thread; @@ -162,6 +165,7 @@ struct mount { int mnt_kern_flag; /* kernel only flags */ int mnt_maxsymlinklen; /* max size of short symlink */ struct statfs mnt_stat; /* cache of filesystem stats */ + struct statvfs mnt_vstat; /* extended stats */ qaddr_t mnt_data; /* private data */ time_t mnt_time; /* last time written*/ u_int mnt_iosize_max; /* max IO request size */ @@ -414,6 +418,8 @@ typedef int vfs_quotactl_t(struct mount *mp, int cmds, uid_t uid, caddr_t arg, struct ucred *cred); typedef int vfs_statfs_t(struct mount *mp, struct statfs *sbp, struct ucred *cred); +typedef int vfs_statvfs_t(struct mount *mp, struct statvfs *sbp, + struct ucred *cred); typedef int vfs_sync_t(struct mount *mp, int waitfor); typedef int vfs_vget_t(struct mount *mp, ino_t ino, struct vnode **vpp); typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp, @@ -440,7 +446,8 @@ struct vfsops { vfs_vptofh_t *vfs_vptofh; vfs_init_t *vfs_init; vfs_uninit_t *vfs_uninit; - vfs_extattrctl_t *vfs_extattrctl; + vfs_extattrctl_t *vfs_extattrctl; + vfs_statvfs_t *vfs_statvfs; }; #define VFS_MOUNT(MP, PATH, DATA, CRED) \ @@ -451,6 +458,7 @@ struct vfsops { #define VFS_QUOTACTL(MP,C,U,A,CRED) \ (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A, CRED) #define VFS_STATFS(MP, SBP, CRED) (*(MP)->mnt_op->vfs_statfs)(MP, SBP, CRED) +#define VFS_STATVFS(MP, SBP, CRED) (*(MP)->mnt_op->vfs_statvfs)(MP, SBP, CRED) #define VFS_SYNC(MP, WAIT) (*(MP)->mnt_op->vfs_sync)(MP, WAIT) #define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP) #define VFS_FHTOVP(MP, FIDP, VPP) \ @@ -553,6 +561,7 @@ vfs_unmount_t vfs_stdunmount; vfs_root_t vfs_stdroot; vfs_quotactl_t vfs_stdquotactl; vfs_statfs_t vfs_stdstatfs; +vfs_statvfs_t vfs_stdstatvfs; vfs_sync_t vfs_stdsync; vfs_sync_t vfs_stdnosync; vfs_vget_t vfs_stdvget; @@ -594,15 +603,18 @@ int mountlist_scan(int (*callback)(struct mount *, void *), void *, int); __BEGIN_DECLS int fstatfs (int, struct statfs *); +int fstatvfs (int, struct statvfs *); int getfh (const char *, fhandle_t *); int getfsstat (struct statfs *, long, int); int getmntinfo (struct statfs **, int); int mount (const char *, const char *, int, void *); int statfs (const char *, struct statfs *); +int statvfs (const char *, struct statvfs *); int unmount (const char *, int); int fhopen (const struct fhandle *, int); int fhstat (const struct fhandle *, struct stat *); int fhstatfs (const struct fhandle *, struct statfs *); +int fhstatvfs (const struct fhandle *, struct statvfs *); /* C library stuff */ void endvfsent (void); diff --git a/sys/sys/mountctl.h b/sys/sys/mountctl.h index dee9bcef98..554bd973eb 100644 --- a/sys/sys/mountctl.h +++ b/sys/sys/mountctl.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/mountctl.h,v 1.14 2008/02/05 20:49:52 dillon Exp $ + * $DragonFly: src/sys/sys/mountctl.h,v 1.15 2008/06/01 19:27:37 dillon Exp $ */ #ifndef _SYS_MOUNTCTL_H_ @@ -76,6 +76,7 @@ #define MOUNTCTL_STATUS_BLK_JOURNAL 11 #define MOUNTCTL_SET_EXPORT 16 /* sys/mount.h:export_args */ +#define MOUNTCTL_STATVFS 17 /* get extended stats */ /* * Data structures for the journaling API diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index b5be50f9d1..df9780a83f 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -2,7 +2,7 @@ * System call hiders. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall-hide.h,v 1.60 2008/05/19 10:19:49 corecode Exp $ + * $DragonFly: src/sys/sys/syscall-hide.h,v 1.61 2008/06/01 19:27:37 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp */ @@ -331,3 +331,6 @@ HIDE_BSD(lwp_gettid) HIDE_BSD(lwp_kill) HIDE_BSD(lwp_rtprio) HIDE_BSD(pselect) +HIDE_BSD(statvfs) +HIDE_BSD(fstatvfs) +HIDE_BSD(fhstatvfs) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 5afb6b935b..985d832702 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -2,7 +2,7 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall.h,v 1.60 2008/05/19 10:19:49 corecode Exp $ + * $DragonFly: src/sys/sys/syscall.h,v 1.61 2008/06/01 19:27:37 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp */ @@ -342,4 +342,7 @@ #define SYS_lwp_kill 497 #define SYS_lwp_rtprio 498 #define SYS_pselect 499 -#define SYS_MAXSYSCALL 500 +#define SYS_statvfs 500 +#define SYS_fstatvfs 501 +#define SYS_fhstatvfs 502 +#define SYS_MAXSYSCALL 503 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 3b968a9e6b..ccf450def9 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,6 +1,6 @@ # DragonFly system call names. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/syscall.mk,v 1.60 2008/05/19 10:19:49 corecode Exp $ +# $DragonFly: src/sys/sys/syscall.mk,v 1.61 2008/06/01 19:27:37 dillon Exp $ # created from DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp MIASM = \ syscall.o \ @@ -282,4 +282,7 @@ MIASM = \ lwp_gettid.o \ lwp_kill.o \ lwp_rtprio.o \ - pselect.o + pselect.o \ + statvfs.o \ + fstatvfs.o \ + fhstatvfs.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 6d76085056..6527a7914b 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysproto.h,v 1.60 2008/05/19 10:19:49 corecode Exp $ + * $DragonFly: src/sys/sys/sysproto.h,v 1.61 2008/06/01 19:27:37 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp */ @@ -2124,6 +2124,27 @@ struct pselect_args { const struct timespec * ts; char ts_[PAD_(const struct timespec *)]; const sigset_t * sigmask; char sigmask_[PAD_(const sigset_t *)]; }; +struct statvfs_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + const char * path; char path_[PAD_(const char *)]; + struct statvfs * buf; char buf_[PAD_(struct statvfs *)]; +}; +struct fstatvfs_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + int fd; char fd_[PAD_(int)]; + struct statvfs * buf; char buf_[PAD_(struct statvfs *)]; +}; +struct fhstatvfs_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + const struct fhandle * u_fhp; char u_fhp_[PAD_(const struct fhandle *)]; + struct statvfs * buf; char buf_[PAD_(struct statvfs *)]; +}; #ifdef COMPAT_43 @@ -2705,6 +2726,9 @@ int sys_lwp_gettid (struct lwp_gettid_args *); int sys_lwp_kill (struct lwp_kill_args *); int sys_lwp_rtprio (struct lwp_rtprio_args *); int sys_pselect (struct pselect_args *); +int sys_statvfs (struct statvfs_args *); +int sys_fstatvfs (struct fstatvfs_args *); +int sys_fhstatvfs (struct fhstatvfs_args *); #endif /* !_SYS_SYSPROTO_H_ */ #undef PAD_ diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index 5455f580fd..f739b0b73f 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -2,7 +2,7 @@ * Union of syscall args for messaging. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysunion.h,v 1.57 2008/05/19 10:19:49 corecode Exp $ + * $DragonFly: src/sys/sys/sysunion.h,v 1.58 2008/06/01 19:27:37 dillon Exp $ * created from DragonFly: src/sys/kern/syscalls.master,v 1.57 2008/01/10 22:30:27 nth Exp */ @@ -387,4 +387,7 @@ union sysunion { struct lwp_kill_args lwp_kill; struct lwp_rtprio_args lwp_rtprio; struct pselect_args pselect; + struct statvfs_args statvfs; + struct fstatvfs_args fstatvfs; + struct fhstatvfs_args fhstatvfs; }; -- 2.41.0