summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorotto <otto@openbsd.org>2008-03-16 19:42:56 +0000
committerotto <otto@openbsd.org>2008-03-16 19:42:56 +0000
commite9fd5de7b265561605a2e9ed5444a17ed5c7c947 (patch)
treec9f469d6eb7e6a95bfb3de1bdfb4cc69650fbd14
parentfor some reason the pchb dependency on agp got left in. kill it. (diff)
downloadwireguard-openbsd-e9fd5de7b265561605a2e9ed5444a17ed5c7c947.tar.xz
wireguard-openbsd-e9fd5de7b265561605a2e9ed5444a17ed5c7c947.zip
Widen some struct statfs fields to support large filesystem stata
and add some to be able to support statvfs(2). Do the compat dance to provide backward compatibility. ok thib@ miod@
-rw-r--r--sys/compat/common/vfs_syscalls_o43.c259
-rw-r--r--sys/conf/GENERIC3
-rw-r--r--sys/conf/files3
-rw-r--r--sys/kern/syscalls.master21
-rw-r--r--sys/kern/vfs_bio.c17
-rw-r--r--sys/kern/vfs_subr.c38
-rw-r--r--sys/nfs/nfs_serv.c13
-rw-r--r--sys/nfs/nfs_vfsops.c28
-rw-r--r--sys/sys/_types.h4
-rw-r--r--sys/sys/mount.h36
-rw-r--r--sys/sys/statvfs.h46
-rw-r--r--sys/sys/types.h4
-rw-r--r--sys/sys/vnode.h4
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c12
14 files changed, 438 insertions, 50 deletions
diff --git a/sys/compat/common/vfs_syscalls_o43.c b/sys/compat/common/vfs_syscalls_o43.c
new file mode 100644
index 00000000000..f7b08a471ef
--- /dev/null
+++ b/sys/compat/common/vfs_syscalls_o43.c
@@ -0,0 +1,259 @@
+/* $OpenBSD: vfs_syscalls_o43.c,v 1.1 2008/03/16 19:42:56 otto Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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 University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/filedesc.h>
+#include <sys/kernel.h>
+#include <sys/file.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/dirent.h>
+
+#include <sys/syscallargs.h>
+
+void statfs_to_o43statfs(struct proc *, struct mount *, struct statfs *,
+ struct o43statfs *);
+
+/*
+ * Convert struct statfs -> struct ostatfs
+ */
+void
+statfs_to_o43statfs(p, mp, sp, osp)
+ struct proc *p;
+ struct mount *mp;
+ struct statfs *sp;
+ struct o43statfs *osp;
+{
+ osp->f_flags = mp->mnt_flag;
+ osp->f_bsize = sp->f_bsize;
+ osp->f_iosize = sp->f_iosize;
+ osp->f_blocks = sp->f_blocks;
+ osp->f_bfree = sp->f_bfree;
+ osp->f_bavail = sp->f_bavail;
+ osp->f_files = sp->f_files;
+ osp->f_ffree = sp->f_ffree;
+ /* Don't let non-root see filesystem id (for NFS security) */
+ if (suser(p, 0))
+ osp->f_fsid.val[0] = osp->f_fsid.val[1] = 0;
+ else
+ bcopy(&sp->f_fsid, &osp->f_fsid, sizeof(osp->f_fsid));
+ osp->f_owner = sp->f_owner;
+ osp->f_syncwrites = sp->f_syncwrites;
+ osp->f_asyncwrites = sp->f_asyncwrites;
+ osp->f_ctime = sp->f_ctime;
+ bcopy(sp->f_fstypename, osp->f_fstypename, MFSNAMELEN);
+ bcopy(sp->f_mntonname, osp->f_mntonname, MNAMELEN);
+ bcopy(sp->f_mntfromname, osp->f_mntfromname, MNAMELEN);
+ bcopy(&sp->mount_info, &osp->mount_info, sizeof(union mount_info));
+}
+
+/*
+ * Get filesystem statistics.
+ */
+/* ARGSUSED */
+int
+compat_o43_sys_statfs(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct compat_o43_sys_statfs_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct o43statfs *) buf;
+ } */ *uap = v;
+ register struct mount *mp;
+ register struct statfs *sp;
+ struct o43statfs osb;
+ int error;
+ struct nameidata nd;
+
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
+ if ((error = namei(&nd)) != 0)
+ return (error);
+ mp = nd.ni_vp->v_mount;
+ sp = &mp->mnt_stat;
+ vrele(nd.ni_vp);
+ if ((error = VFS_STATFS(mp, sp, p)) != 0)
+ return (error);
+
+ statfs_to_o43statfs(p, mp, sp, &osb);
+ return (copyout((caddr_t)&osb, (caddr_t)SCARG(uap, buf), sizeof(osb)));
+}
+
+/*
+ * Get filesystem statistics.
+ */
+/* ARGSUSED */
+int
+compat_o43_sys_fstatfs(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct compat_o43_sys_fstatfs_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct ostatfs *) buf;
+ } */ *uap = v;
+ struct file *fp;
+ struct mount *mp;
+ struct statfs *sp;
+ struct o43statfs osb;
+ int error;
+
+ if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
+ return (error);
+ mp = ((struct vnode *)fp->f_data)->v_mount;
+ sp = &mp->mnt_stat;
+ error = VFS_STATFS(mp, sp, p);
+ FRELE(fp);
+ if (error)
+ return (error);
+
+ statfs_to_o43statfs(p, mp, sp, &osb);
+ return (copyout((caddr_t)&osb, (caddr_t)SCARG(uap, buf), sizeof(osb)));
+}
+
+/*
+ * Get statistics on all filesystems.
+ */
+int
+compat_o43_sys_getfsstat(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct compat_o43_sys_getfsstat_args /* {
+ syscallarg(struct o43statfs *) buf;
+ syscallarg(long) bufsize;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ register struct mount *mp, *nmp;
+ register struct statfs *sp;
+ struct o43statfs osb;
+ caddr_t sfsp;
+ long count, maxcount;
+ int error, flags = SCARG(uap, flags);
+
+ maxcount = SCARG(uap, bufsize) / sizeof(struct ostatfs);
+ sfsp = (caddr_t)SCARG(uap, buf);
+ count = 0;
+
+ for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
+ mp = nmp) {
+ if (vfs_busy(mp, VB_READ|VB_NOWAIT)) {
+ nmp = CIRCLEQ_NEXT(mp, mnt_list);
+ continue;
+ }
+ if (sfsp && count < maxcount) {
+ sp = &mp->mnt_stat;
+
+ /* Refresh stats unless MNT_NOWAIT is specified */
+ if (flags != MNT_NOWAIT &&
+ flags != MNT_LAZY &&
+ (flags == MNT_WAIT ||
+ flags == 0) &&
+ (error = VFS_STATFS(mp, sp, p))) {
+ nmp = CIRCLEQ_NEXT(mp, mnt_list);
+ vfs_unbusy(mp);
+ continue;
+ }
+
+ statfs_to_o43statfs(p, mp, sp, &osb);
+ error = copyout((caddr_t)&osb, sfsp, sizeof(osb));
+ if (error) {
+ vfs_unbusy(mp);
+ return (error);
+ }
+ sfsp += sizeof(osb);
+ }
+ count++;
+ nmp = CIRCLEQ_NEXT(mp, mnt_list);
+ vfs_unbusy(mp);
+ }
+
+ if (sfsp && count > maxcount)
+ *retval = maxcount;
+ else
+ *retval = count;
+
+ return (0);
+}
+
+
+/* ARGSUSED */
+int
+compat_o43_sys_fhstatfs(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_fhstatfs_args /*
+ syscallarg(const fhandle_t *) fhp;
+ syscallarg(struct o43statfs *) buf;
+ } */ *uap = v;
+ struct statfs *sp;
+ struct o43statfs osb;
+ fhandle_t fh;
+ struct mount *mp;
+ struct vnode *vp;
+ int error;
+
+ /*
+ * Must be super user
+ */
+ if ((error = suser(p, 0)))
+ return (error);
+
+ if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
+ return (error);
+
+ if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
+ return (ESTALE);
+ if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
+ return (error);
+ mp = vp->v_mount;
+ sp = &mp->mnt_stat;
+ vput(vp);
+ if ((error = VFS_STATFS(mp, sp, p)) != 0)
+ return (error);
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+ statfs_to_o43statfs(p, mp, sp, &osb);
+ return copyout((caddr_t)&osb, SCARG(uap, buf), sizeof(osb));
+}
+
diff --git a/sys/conf/GENERIC b/sys/conf/GENERIC
index ba185874a69..9e825d58684 100644
--- a/sys/conf/GENERIC
+++ b/sys/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.139 2008/01/05 17:33:28 mbalmer Exp $
+# $OpenBSD: GENERIC,v 1.140 2008/03/16 19:42:57 otto Exp $
#
# Machine-independent option; used by all architectures for their
# GENERIC kernel
@@ -25,6 +25,7 @@ option SYSVSHM # System V-like memory sharing
option UVM_SWAP_ENCRYPT# support encryption of pages going to swap
option COMPAT_43 # and 4.3BSD
+option COMPAT_O43 # and OpenBSD 4.3
option LKM # loadable kernel modules
diff --git a/sys/conf/files b/sys/conf/files
index c0b45aa724e..f40bef8b826 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.425 2008/03/16 19:00:28 oga Exp $
+# $OpenBSD: files,v 1.426 2008/03/16 19:42:57 otto Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -992,6 +992,7 @@ file compat/common/vfs_syscalls_25.c !small_kernel &
(compat_freebsd | compat_bsdos | compat_sunos | compat_hpux)
file compat/common/vfs_syscalls_35.c !small_kernel &
(compat_freebsd | compat_bsdos | compat_sunos | compat_hpux)
+file compat/common/vfs_syscalls_o43.c !small_kernel & compat_o43
file compat/common/kern_ipc_35.c !small_kernel & compat_35
file compat/common/kern_ipc_23.c !small_kernel & compat_23
file compat/common/kern_exit_43.c !small_kernel
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 9611838bc9d..7c8970714aa 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,4 +1,4 @@
-; $OpenBSD: syscalls.master,v 1.89 2008/01/05 00:36:13 miod Exp $
+; $OpenBSD: syscalls.master,v 1.90 2008/03/16 19:42:57 otto Exp $
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -514,17 +514,17 @@
#else
259 UNIMPL
#endif
-260 STD { int sys_getfsstat(struct statfs *buf, size_t bufsize, \
+260 COMPAT_O43 { int sys_getfsstat(struct o43statfs *buf, size_t bufsize, \
int flags); }
-261 STD { int sys_statfs(const char *path, \
- struct statfs *buf); }
-262 STD { int sys_fstatfs(int fd, struct statfs *buf); }
+261 COMPAT_O43 { int sys_statfs(const char *path, \
+ struct o43statfs *buf); }
+262 COMPAT_O43 { int sys_fstatfs(int fd, struct o43statfs *buf); }
263 STD { int sys_pipe(int *fdp); }
264 STD { int sys_fhopen(const fhandle_t *fhp, int flags); }
265 COMPAT_35 { int sys_fhstat(const fhandle_t *fhp, \
struct stat35 *sb); }
-266 STD { int sys_fhstatfs(const fhandle_t *fhp, \
- struct statfs *buf); }
+266 COMPAT_O43 { int sys_fhstatfs(const fhandle_t *fhp, \
+ struct o43statfs *buf); }
267 STD { ssize_t sys_preadv(int fd, \
const struct iovec *iovp, int iovcnt, \
int pad, off_t offset); }
@@ -611,3 +611,10 @@
304 STD { int sys___getcwd(char *buf, size_t len); }
305 STD { int sys_adjfreq(const int64_t *freq, \
int64_t *oldfreq); }
+306 STD { int sys_getfsstat(struct statfs *buf, size_t bufsize, \
+ int flags); }
+307 STD { int sys_statfs(const char *path, \
+ struct statfs *buf); }
+308 STD { int sys_fstatfs(int fd, struct statfs *buf); }
+309 STD { int sys_fhstatfs(const fhandle_t *fhp, \
+ struct statfs *buf); }
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 8b2720b36b6..4d11266537c 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_bio.c,v 1.102 2007/10/21 15:54:55 beck Exp $ */
+/* $OpenBSD: vfs_bio.c,v 1.103 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: vfs_bio.c,v 1.44 1996/06/11 11:15:36 pk Exp $ */
/*-
@@ -377,6 +377,7 @@ struct buf *
bio_doread(struct vnode *vp, daddr64_t blkno, int size, int async)
{
struct buf *bp;
+ struct mount *mp;
bp = getblk(vp, blkno, size, 0, 0);
@@ -395,6 +396,20 @@ bio_doread(struct vnode *vp, daddr64_t blkno, int size, int async)
brelse(bp);
}
+ mp = vp->v_type == VBLK? vp->v_specmountpoint : vp->v_mount;
+
+ /*
+ * Collect statistics on synchronous and asynchronous reads.
+ * Reads from block devices are charged to their associated
+ * filesystem (if any).
+ */
+ if (mp != NULL) {
+ if (async == 0)
+ mp->mnt_stat.f_syncreads++;
+ else
+ mp->mnt_stat.f_asyncreads++;
+ }
+
return (bp);
}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 05db45dfeb3..a3894346e16 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.161 2007/12/13 18:22:36 blambert Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.162 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -2228,20 +2228,23 @@ vfs_mount_print(struct mount *mp, int full, int (*pr)(const char *, ...))
vfc->vfc_vfsops, vfc->vfc_name, vfc->vfc_typenum,
vfc->vfc_refcount, vfc->vfc_flags);
- (*pr)("statvfs cache: bsize %x iosize %x\nblocks %u free %u avail %u\n",
+ (*pr)("statvfs cache: bsize %x iosize %x\nblocks %llu free %llu avail %lld\n",
mp->mnt_stat.f_bsize, mp->mnt_stat.f_iosize, mp->mnt_stat.f_blocks,
mp->mnt_stat.f_bfree, mp->mnt_stat.f_bavail);
- (*pr)(" files %u ffiles %u\n", mp->mnt_stat.f_files,
- mp->mnt_stat.f_ffree);
+ (*pr)(" files %llu ffiles %llu favail $lld\n", mp->mnt_stat.f_files,
+ mp->mnt_stat.f_ffree, mp->mnt_stat.f_favail);
(*pr)(" f_fsidx {0x%x, 0x%x} owner %u ctime 0x%x\n",
mp->mnt_stat.f_fsid.val[0], mp->mnt_stat.f_fsid.val[1],
mp->mnt_stat.f_owner, mp->mnt_stat.f_ctime);
- (*pr)(" syncwrites %lu asyncwrites = %lu\n",
+ (*pr)(" syncwrites %llu asyncwrites = %llu\n",
mp->mnt_stat.f_syncwrites, mp->mnt_stat.f_asyncwrites);
+ (*pr)(" syncreads %llu asyncreads = %llu\n",
+ mp->mnt_stat.f_syncreads, mp->mnt_stat.f_asyncreads);
+
(*pr)(" fstype \"%s\" mnton \"%s\" mntfrom \"%s\"\n",
mp->mnt_stat.f_fstypename, mp->mnt_stat.f_mntonname,
mp->mnt_stat.f_mntfromname);
@@ -2273,3 +2276,28 @@ vfs_mount_print(struct mount *mp, int full, int (*pr)(const char *, ...))
}
}
#endif /* DDB */
+
+void
+copy_statfs_info(struct statfs *sbp, const struct mount *mp)
+{
+ const struct statfs *mbp;
+
+ strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
+
+ if (sbp == (mbp = &mp->mnt_stat))
+ return;
+
+ sbp->f_fsid = mbp->f_fsid;
+ sbp->f_owner = mbp->f_owner;
+ sbp->f_flags = mbp->f_flags;
+ sbp->f_syncwrites = mbp->f_syncwrites;
+ sbp->f_asyncwrites = mbp->f_asyncwrites;
+ sbp->f_syncreads = mbp->f_syncreads;
+ sbp->f_asyncreads = mbp->f_asyncreads;
+ sbp->f_namemax = mbp->f_namemax;
+ bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
+ bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
+ bcopy(&mp->mnt_stat.mount_info.ufs_args, &sbp->mount_info.ufs_args,
+ sizeof(struct ufs_args));
+}
+
diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c
index 53de291d927..c545fba06ba 100644
--- a/sys/nfs/nfs_serv.c
+++ b/sys/nfs/nfs_serv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_serv.c,v 1.48 2008/01/06 17:38:23 blambert Exp $ */
+/* $OpenBSD: nfs_serv.c,v 1.49 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: nfs_serv.c,v 1.34 1997/05/12 23:37:12 fvdl Exp $ */
/*
@@ -3061,12 +3061,11 @@ nfsrv_statfs(nfsd, slp, procp, mrq)
tval = (u_quad_t)sf->f_bavail;
tval *= (u_quad_t)sf->f_bsize;
txdr_hyper(tval, &sfp->sf_abytes);
- sfp->sf_tfiles.nfsuquad[0] = 0;
- sfp->sf_tfiles.nfsuquad[1] = txdr_unsigned(sf->f_files);
- sfp->sf_ffiles.nfsuquad[0] = 0;
- sfp->sf_ffiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
- sfp->sf_afiles.nfsuquad[0] = 0;
- sfp->sf_afiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
+ tval = (u_quad_t)sf->f_files;
+ txdr_hyper(tval, &sfp->sf_tfiles);
+ tval = (u_quad_t)sf->f_ffree;
+ txdr_hyper(tval, &sfp->sf_ffiles);
+ txdr_hyper(tval, &sfp->sf_afiles);
sfp->sf_invarsec = 0;
} else {
sfp->sf_tsize = txdr_unsigned(NFS_MAXDGRAMDATA);
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c
index 81acebb6371..a04ca7f69fe 100644
--- a/sys/nfs/nfs_vfsops.c
+++ b/sys/nfs/nfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vfsops.c,v 1.69 2008/01/06 18:38:32 deraadt Exp $ */
+/* $OpenBSD: nfs_vfsops.c,v 1.70 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.46.4.1 1996/05/25 22:40:35 fvdl Exp $ */
/*
@@ -46,6 +46,7 @@
#include <sys/mount.h>
#include <sys/buf.h>
#include <sys/mbuf.h>
+#include <sys/dirent.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/systm.h>
@@ -145,15 +146,18 @@ nfs_statfs(mp, sbp, p)
if (v3) {
sbp->f_bsize = NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_tbytes);
- sbp->f_blocks = (u_int32_t)(tquad / (u_quad_t)NFS_FABLKSIZE);
+ sbp->f_blocks = tquad / (u_quad_t)NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_fbytes);
- sbp->f_bfree = (u_int32_t)(tquad / (u_quad_t)NFS_FABLKSIZE);
+ sbp->f_bfree = tquad / (u_quad_t)NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_abytes);
- sbp->f_bavail = (int32_t)((quad_t)tquad / (quad_t)NFS_FABLKSIZE);
- sbp->f_files = (fxdr_unsigned(int32_t,
- sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
- sbp->f_ffree = (fxdr_unsigned(int32_t,
- sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
+ sbp->f_bavail = (quad_t)tquad / (quad_t)NFS_FABLKSIZE;
+
+ tquad = fxdr_hyper(&sfp->sf_tfiles);
+ sbp->f_files = tquad;
+ tquad = fxdr_hyper(&sfp->sf_ffiles);
+ sbp->f_ffree = tquad;
+ sbp->f_favail = tquad;
+ sbp->f_namemax = MAXNAMLEN;
} else {
sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
@@ -162,13 +166,7 @@ nfs_statfs(mp, sbp, p)
sbp->f_files = 0;
sbp->f_ffree = 0;
}
- if (sbp != &mp->mnt_stat) {
- bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
- bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
- bcopy(&mp->mnt_stat.mount_info.nfs_args,
- &sbp->mount_info.nfs_args, sizeof(struct nfs_args));
- }
- strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
+ copy_statfs_info(sbp, mp);
m_freem(mrep);
nfsmout:
vrele(vp);
diff --git a/sys/sys/_types.h b/sys/sys/_types.h
index 7a91283339b..f31ae95efc3 100644
--- a/sys/sys/_types.h
+++ b/sys/sys/_types.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: _types.h,v 1.1 2006/01/06 18:53:05 millert Exp $ */
+/* $OpenBSD: _types.h,v 1.2 2008/03/16 19:42:57 otto Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -56,6 +56,8 @@ typedef __int32_t __swblk_t; /* swap offset */
typedef __uint32_t __uid_t; /* user id */
typedef __uint32_t __useconds_t; /* microseconds */
typedef __int32_t __suseconds_t; /* microseconds (signed) */
+typedef __uint64_t __fsblkcnt_t; /* file system block count */
+typedef __uint64_t __fsfilcnt_t; /* file system file count */
/*
* mbstate_t is an opaque object to keep conversion state, during multibyte
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index c838a545f51..dc0ce42f237 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount.h,v 1.81 2007/06/01 05:37:14 deraadt Exp $ */
+/* $OpenBSD: mount.h,v 1.82 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: mount.h,v 1.48 1996/02/18 11:55:47 fvdl Exp $ */
/*
@@ -282,8 +282,40 @@ union mount_info {
char __align[160]; /* 64-bit alignment and room to grow */
};
-/* new statfs structure with mount options */
+/* new statfs structure with mount options and statvfs fields */
struct statfs {
+ u_int32_t f_flags; /* copy of mount flags */
+ u_int32_t f_bsize; /* file system block size */
+ u_int32_t f_iosize; /* optimal transfer block size */
+
+ /* unit is f_bsize */
+ u_int64_t f_blocks; /* total data blocks in file system */
+ u_int64_t f_bfree; /* free blocks in fs */
+ int64_t f_bavail; /* free blocks avail to non-superuser */
+
+ u_int64_t f_files; /* total file nodes in file system */
+ u_int64_t f_ffree; /* free file nodes in fs */
+ int64_t f_favail; /* free file nodes avail to non-root */
+
+ u_int64_t f_syncwrites; /* count of sync writes since mount */
+ u_int64_t f_syncreads; /* count of sync reads since mount */
+ u_int64_t f_asyncwrites; /* count of async writes since mount */
+ u_int64_t f_asyncreads; /* count of async reads since mount */
+
+ fsid_t f_fsid; /* file system id */
+ u_int32_t f_namemax; /* maximum filename length */
+ uid_t f_owner; /* user that mounted the file system */
+ u_int32_t f_ctime; /* last mount [-u] time */
+ u_int32_t f_spare[3]; /* spare for later */
+
+ char f_fstypename[MFSNAMELEN]; /* fs type name */
+ char f_mntonname[MNAMELEN]; /* directory on which mounted */
+ char f_mntfromname[MNAMELEN]; /* mounted file system */
+ union mount_info mount_info; /* per-filesystem mount options */
+};
+
+/* old (pre-4.3) statfs structure with mount options */
+struct o43statfs {
u_int32_t f_flags; /* copy of mount flags */
int32_t f_bsize; /* fundamental file system block size */
u_int32_t f_iosize; /* optimal transfer block size */
diff --git a/sys/sys/statvfs.h b/sys/sys/statvfs.h
new file mode 100644
index 00000000000..3c171058b92
--- /dev/null
+++ b/sys/sys/statvfs.h
@@ -0,0 +1,46 @@
+/* $OpenBSD: statvfs.h,v 1.1 2008/03/16 19:42:57 otto Exp $ */
+
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_STATVFS_H_
+#define _SYS_STATVFS_H_
+
+#include <sys/types.h>
+
+struct statvfs {
+ unsigned long f_bsize; /* file system block size */
+ unsigned long f_frsize; /* fundamental file system block size */
+ fsblkcnt_t f_blocks; /* number of blocks (unit f_frsize) */
+ fsblkcnt_t f_bfree; /* free blocks in file system */
+ fsblkcnt_t f_bavail; /* free blocks for non-root */
+ fsfilcnt_t f_files; /* total file inodes */
+ fsfilcnt_t f_ffree; /* free file inodes */
+ fsfilcnt_t f_favail; /* free file inodes for to non-root */
+ unsigned long f_fsid; /* file system id */
+ unsigned long f_flag; /* bit mask of f_flag values */
+ unsigned long f_namemax; /* maximum filename length */
+};
+
+#define ST_RDONLY 0x0001L /* read-only filesystem */
+#define ST_NOSUID 0x0002L /* nosuid flag set */
+
+__BEGIN_DECLS
+int fstatvfs(int, struct statvfs *);
+int statvfs(const char *, struct statvfs *);
+__END_DECLS
+
+#endif /* !_SYS_STATVFS_H_ */
diff --git a/sys/sys/types.h b/sys/sys/types.h
index 7be89167c38..9fffc94acae 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: types.h,v 1.30 2006/10/03 19:49:06 pedro Exp $ */
+/* $OpenBSD: types.h,v 1.31 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: types.h,v 1.29 1996/11/15 22:48:25 jtc Exp $ */
/*-
@@ -146,6 +146,8 @@ typedef __swblk_t swblk_t; /* swap offset */
typedef __uid_t uid_t; /* user id */
typedef __useconds_t useconds_t; /* microseconds */
typedef __suseconds_t suseconds_t; /* microseconds (signed) */
+typedef __fsblkcnt_t fsblkcnt_t; /* file system block count */
+typedef __fsfilcnt_t fsfilcnt_t; /* file system file count */
/*
* XPG4.2 states that inclusion of <netinet/in.h> must pull these
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index d35a0b8644f..85855330a33 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnode.h,v 1.90 2007/12/27 13:59:12 thib Exp $ */
+/* $OpenBSD: vnode.h,v 1.91 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
@@ -340,6 +340,7 @@ struct mount;
struct nameidata;
struct proc;
struct stat;
+struct statfs;
struct ucred;
struct uio;
struct vattr;
@@ -371,6 +372,7 @@ int vrecycle(struct vnode *, struct proc *);
void vrele(struct vnode *);
void vref(struct vnode *);
void vprint(char *, struct vnode *);
+void copy_statfs_info(struct statfs *, const struct mount *);
/* vfs_getcwd.c */
int vfs_getcwd_scandir(struct vnode **, struct vnode **, char **, char *,
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 76c93f18d08..dd315612dae 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_vfsops.c,v 1.112 2008/01/05 19:49:26 otto Exp $ */
+/* $OpenBSD: ffs_vfsops.c,v 1.113 2008/03/16 19:42:57 otto Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */
/*
@@ -842,6 +842,7 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p)
mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1];
else
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
+ mp->mnt_stat.f_namemax = MAXNAMLEN;
mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
mp->mnt_flag |= MNT_LOCAL;
ump->um_mountp = mp;
@@ -1110,13 +1111,8 @@ ffs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
sbp->f_bavail = sbp->f_bfree - ((int64_t)fs->fs_dsize * fs->fs_minfree / 100);
sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO;
sbp->f_ffree = fs->fs_cstotal.cs_nifree;
- if (sbp != &mp->mnt_stat) {
- bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
- bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
- bcopy(&mp->mnt_stat.mount_info.ufs_args,
- &sbp->mount_info.ufs_args, sizeof(struct ufs_args));
- }
- strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
+ sbp->f_favail = sbp->f_ffree;
+ copy_statfs_info(sbp, mp);
return (0);
}