From: Matthew Dillon Date: Sun, 1 Jun 2008 19:55:32 +0000 (+0000) Subject: Implement a new system call: getvfsstat(). This system call returns X-Git-Tag: v2.0.1~497 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/00fe9d4861e0ab82e7b4929f49a36ce0d017159a Implement a new system call: getvfsstat(). This system call returns an array of statfs and statvfs structures. Unfortunately there is no way to just return an array of statvfs structures because the statvfs structure does not have sufficient information in it to identify the mount point. getvfsstat(struct statfs *buf, struct statvfs *vbuf, long vbufsize, int flags); --- diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 88cfb6b47b..9f7e48336b 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $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 + * $DragonFly: src/sys/kern/init_sysent.c,v 1.62 2008/06/01 19:55:30 dillon Exp $ + * created from DragonFly */ #include "opt_compat.h" @@ -538,4 +538,5 @@ struct sysent sysent[] = { { 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 */ + { AS(getvfsstat_args), (sy_call_t *)sys_getvfsstat }, /* 503 = getvfsstat */ }; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 65939a5eed..1aa40e1a08 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $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 + * $DragonFly: src/sys/kern/syscalls.c,v 1.61 2008/06/01 19:55:30 dillon Exp $ + * created from DragonFly */ char *syscallnames[] = { @@ -512,4 +512,5 @@ char *syscallnames[] = { "statvfs", /* 500 = statvfs */ "fstatvfs", /* 501 = fstatvfs */ "fhstatvfs", /* 502 = fhstatvfs */ + "getvfsstat", /* 503 = getvfsstat */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 7ccd563d4f..3b3eb35423 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $DragonFly: src/sys/kern/syscalls.master,v 1.58 2008/06/01 19:27:35 dillon Exp $ + $DragonFly: src/sys/kern/syscalls.master,v 1.59 2008/06/01 19:55:30 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 $ @@ -688,3 +688,5 @@ 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); } +503 STD BSD { int getvfsstat(struct statfs *buf, \ + struct statvfs *vbuf, long vbufsize, int flags); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 0706ca327e..3609211742 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.128 2008/06/01 19:27:35 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.129 2008/06/01 19:55:30 dillon Exp $ */ #include @@ -1316,6 +1316,113 @@ getfsstat_callback(struct mount *mp, void *data) return(0); } +/* + * getvfsstat_args(struct statfs *buf, struct statvfs *vbuf, + long bufsize, int flags) + * + * Get statistics on all filesystems. + */ + +struct getvfsstat_info { + struct statfs *sfsp; + struct statvfs *vsfsp; + long count; + long maxcount; + int error; + int flags; + struct proc *p; +}; + +static int getvfsstat_callback(struct mount *, void *); + +/* ARGSUSED */ +int +sys_getvfsstat(struct getvfsstat_args *uap) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + struct getvfsstat_info info; + + bzero(&info, sizeof(info)); + + info.maxcount = uap->vbufsize / sizeof(struct statvfs); + info.sfsp = uap->buf; + info.vsfsp = uap->vbuf; + info.count = 0; + info.flags = uap->flags; + info.p = p; + + mountlist_scan(getvfsstat_callback, &info, MNTSCAN_FORWARD); + if (info.vsfsp && info.count > info.maxcount) + uap->sysmsg_result = info.maxcount; + else + uap->sysmsg_result = info.count; + return (info.error); +} + +static int +getvfsstat_callback(struct mount *mp, void *data) +{ + struct getvfsstat_info *info = data; + struct statfs *sp; + struct statvfs *vsp; + char *freepath; + char *fullpath; + int error; + + if (info->vsfsp && info->count < info->maxcount) { + if (info->p && !chroot_visible_mnt(mp, info->p)) + return(0); + sp = &mp->mnt_stat; + vsp = &mp->mnt_vstat; + + /* + * If MNT_NOWAIT or MNT_LAZY is specified, do not + * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY + * overrides MNT_WAIT. + */ + if (((info->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || + (info->flags & MNT_WAIT)) && + (error = VFS_STATFS(mp, sp, info->p->p_ucred))) { + return(0); + } + sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; + + if (((info->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || + (info->flags & MNT_WAIT)) && + (error = VFS_STATVFS(mp, vsp, info->p->p_ucred))) { + return(0); + } + vsp->f_flag = 0; + if (mp->mnt_flag & MNT_RDONLY) + vsp->f_flag |= ST_RDONLY; + if (mp->mnt_flag & MNT_NOSUID) + vsp->f_flag |= ST_NOSUID; + + error = mount_path(info->p, mp, &fullpath, &freepath); + if (error) { + info->error = error; + return(-1); + } + bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); + strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); + kfree(freepath, M_TEMP); + + error = copyout(sp, info->sfsp, sizeof(*sp)); + if (error == 0) + error = copyout(vsp, info->vsfsp, sizeof(*vsp)); + if (error) { + info->error = error; + return (-1); + } + ++info->sfsp; + ++info->vsfsp; + } + info->count++; + return(0); +} + + /* * fchdir_args(int fd) * diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 28180b7e7c..0dfb11efc7 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.40 2008/06/01 19:27:37 dillon Exp $ + * $DragonFly: src/sys/sys/mount.h,v 1.41 2008/06/01 19:55:32 dillon Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -606,6 +606,7 @@ int fstatfs (int, struct statfs *); int fstatvfs (int, struct statvfs *); int getfh (const char *, fhandle_t *); int getfsstat (struct statfs *, long, int); +int getvfsstat (struct statfs *, struct statvfs *, long, int); int getmntinfo (struct statfs **, int); int mount (const char *, const char *, int, void *); int statfs (const char *, struct statfs *); diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index df9780a83f..f086937930 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -2,8 +2,8 @@ * System call hiders. * * DO NOT EDIT-- this file is automatically generated. - * $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 + * $DragonFly: src/sys/sys/syscall-hide.h,v 1.62 2008/06/01 19:55:32 dillon Exp $ + * created from DragonFly */ #ifdef COMPAT_43 @@ -334,3 +334,4 @@ HIDE_BSD(pselect) HIDE_BSD(statvfs) HIDE_BSD(fstatvfs) HIDE_BSD(fhstatvfs) +HIDE_BSD(getvfsstat) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 985d832702..81cb462939 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $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 + * $DragonFly: src/sys/sys/syscall.h,v 1.62 2008/06/01 19:55:32 dillon Exp $ + * created from DragonFly */ #define SYS_syscall 0 @@ -345,4 +345,5 @@ #define SYS_statvfs 500 #define SYS_fstatvfs 501 #define SYS_fhstatvfs 502 -#define SYS_MAXSYSCALL 503 +#define SYS_getvfsstat 503 +#define SYS_MAXSYSCALL 504 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index ccf450def9..44d84af3f7 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # DragonFly system call names. # DO NOT EDIT-- this file is automatically generated. -# $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 +# $DragonFly: src/sys/sys/syscall.mk,v 1.62 2008/06/01 19:55:32 dillon Exp $ +# created from DragonFly MIASM = \ syscall.o \ exit.o \ @@ -285,4 +285,5 @@ MIASM = \ pselect.o \ statvfs.o \ fstatvfs.o \ - fhstatvfs.o + fhstatvfs.o \ + getvfsstat.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 6527a7914b..57049cbb72 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $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 + * $DragonFly: src/sys/sys/sysproto.h,v 1.62 2008/06/01 19:55:32 dillon Exp $ + * created from DragonFly */ #ifndef _SYS_SYSPROTO_H_ @@ -2145,6 +2145,15 @@ struct fhstatvfs_args { const struct fhandle * u_fhp; char u_fhp_[PAD_(const struct fhandle *)]; struct statvfs * buf; char buf_[PAD_(struct statvfs *)]; }; +struct getvfsstat_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + struct statfs * buf; char buf_[PAD_(struct statfs *)]; + struct statvfs * vbuf; char vbuf_[PAD_(struct statvfs *)]; + long vbufsize; char vbufsize_[PAD_(long)]; + int flags; char flags_[PAD_(int)]; +}; #ifdef COMPAT_43 @@ -2729,6 +2738,7 @@ int sys_pselect (struct pselect_args *); int sys_statvfs (struct statvfs_args *); int sys_fstatvfs (struct fstatvfs_args *); int sys_fhstatvfs (struct fhstatvfs_args *); +int sys_getvfsstat (struct getvfsstat_args *); #endif /* !_SYS_SYSPROTO_H_ */ #undef PAD_ diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index f739b0b73f..34196aa2aa 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -2,8 +2,8 @@ * Union of syscall args for messaging. * * DO NOT EDIT-- this file is automatically generated. - * $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 + * $DragonFly: src/sys/sys/sysunion.h,v 1.59 2008/06/01 19:55:32 dillon Exp $ + * created from DragonFly */ union sysunion { @@ -390,4 +390,5 @@ union sysunion { struct statvfs_args statvfs; struct fstatvfs_args fstatvfs; struct fhstatvfs_args fhstatvfs; + struct getvfsstat_args getvfsstat; };