Implement a new system call: getvfsstat(). This system call returns
authorMatthew Dillon <dillon@dragonflybsd.org>
Sun, 1 Jun 2008 19:55:32 +0000 (19:55 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sun, 1 Jun 2008 19:55:32 +0000 (19:55 +0000)
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);

sys/kern/init_sysent.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/kern/vfs_syscalls.c
sys/sys/mount.h
sys/sys/syscall-hide.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h

index 88cfb6b..9f7e483 100644 (file)
@@ -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 */
 };
index 65939a5..1aa40e1 100644 (file)
@@ -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 */
 };
index 7ccd563..3b3eb35 100644 (file)
@@ -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 $
 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); }
index 0706ca3..3609211 100644 (file)
@@ -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 <sys/param.h>
@@ -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)
  *
index 28180b7..0dfb11e 100644 (file)
@@ -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 *);
index df9780a..f086937 100644 (file)
@@ -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)
index 985d832..81cb462 100644 (file)
@@ -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
 #define        SYS_statvfs     500
 #define        SYS_fstatvfs    501
 #define        SYS_fhstatvfs   502
-#define        SYS_MAXSYSCALL  503
+#define        SYS_getvfsstat  503
+#define        SYS_MAXSYSCALL  504
index ccf450d..44d84af 100644 (file)
@@ -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
index 6527a79..57049cb 100644 (file)
@@ -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_
index f739b0b..34196aa 100644 (file)
@@ -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;
 };