summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordenny <denny@cvs.openbsd.org>1997-06-16 04:37:51 +0000
committerdenny <denny@cvs.openbsd.org>1997-06-16 04:37:51 +0000
commit917618fd0d4785021ed5c6f96f068964606abaa7 (patch)
tree4f7a6593c8f299e8bb48793499edfe19cdcbd76f
parent7e648a5e6d2f98a29cf7cc995989553a1b895e94 (diff)
Better support for unmounted filesystems (i.e. df /dev/rsd0a):
- interpret the superblock of lfs, ext2fs, and ffs filesystems. - never mount() an offline filesystem, always read its superblock. - use the same algorithm as statfs() for ffs, get the same answers. Even so, now I'm really unsure this code should remain in df. Similar functionality should be added to dumpfs or fsck instead.
-rw-r--r--bin/df/Makefile3
-rw-r--r--bin/df/df.c106
-rw-r--r--bin/df/ext2fs_df.c111
-rw-r--r--bin/df/ffs_df.c97
-rw-r--r--bin/df/lfs_df.c98
5 files changed, 333 insertions, 82 deletions
diff --git a/bin/df/Makefile b/bin/df/Makefile
index a07eb37e972..ce0b720bc80 100644
--- a/bin/df/Makefile
+++ b/bin/df/Makefile
@@ -1,7 +1,8 @@
-# $OpenBSD: Makefile,v 1.2 1996/06/23 14:19:50 deraadt Exp $
+# $OpenBSD: Makefile,v 1.3 1997/06/16 04:37:48 denny Exp $
# $NetBSD: Makefile,v 1.9 1995/03/21 09:04:14 cgd Exp $
PROG= df
+SRCS= df.c ffs_df.c lfs_df.c ext2fs_df.c
BINGRP= operator
BINMODE=2555
diff --git a/bin/df/df.c b/bin/df/df.c
index da951b82862..e227fbbfd3e 100644
--- a/bin/df/df.c
+++ b/bin/df/df.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: df.c,v 1.15 1997/06/01 07:03:18 downsj Exp $ */
+/* $OpenBSD: df.c,v 1.16 1997/06/16 04:37:49 denny Exp $ */
/* $NetBSD: df.c,v 1.21.2.1 1995/11/01 00:06:11 jtc Exp $ */
/*
@@ -49,7 +49,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)df.c 8.7 (Berkeley) 4/2/94";
#else
-static char rcsid[] = "$OpenBSD: df.c,v 1.15 1997/06/01 07:03:18 downsj Exp $";
+static char rcsid[] = "$OpenBSD: df.c,v 1.16 1997/06/16 04:37:49 denny Exp $";
#endif
#endif /* not lint */
@@ -65,15 +65,19 @@ static char rcsid[] = "$OpenBSD: df.c,v 1.15 1997/06/01 07:03:18 downsj Exp $";
#include <string.h>
#include <unistd.h>
-int bread __P((off_t, void *, int));
+int bread __P((int, off_t, void *, int));
char *getmntpt __P((char *));
void prtstat __P((struct statfs *, int));
-int ufs_df __P((char *, struct statfs *));
int selected __P((const char *));
void maketypelist __P((char *));
long regetmntinfo __P((struct statfs **, long));
void usage __P((void));
+int raw_df __P((char *, struct statfs *));
+extern int ffs_df __P((int, char *, struct statfs *));
+extern int lfs_df __P((int, char *, struct statfs *));
+extern int e2fs_df __P((int, char *, struct statfs *));
+
int hflag, iflag, kflag, lflag, nflag;
char **typelist = NULL;
struct ufs_args mdev;
@@ -134,34 +138,10 @@ main(argc, argv)
warn("%s", *argv);
continue;
}
- } else if (S_ISCHR(stbuf.st_mode)) {
- if (!ufs_df(*argv, &mntbuf[mntsize]))
+ } else if (S_ISCHR(stbuf.st_mode) || S_ISBLK(stbuf.st_mode)) {
+ if (!raw_df(*argv, &mntbuf[mntsize]))
++mntsize;
continue;
- } else if (S_ISBLK(stbuf.st_mode)) {
- if ((mntpt = getmntpt(*argv)) == 0) {
- /* XXX can be DOS'd, not very important */
- mntpt = mktemp(strdup("/tmp/df.XXXXXXXXXX"));
- mdev.fspec = *argv;
- if (mkdir(mntpt, DEFFILEMODE) != 0) {
- warn("%s", mntpt);
- continue;
- }
- if (mount(MOUNT_FFS, mntpt, MNT_RDONLY,
- &mdev) != 0) {
- (void)rmdir(mntpt);
- if (!ufs_df(*argv, &mntbuf[mntsize]))
- ++mntsize;
- continue;
- } else if (!statfs(mntpt, &mntbuf[mntsize])) {
- mntbuf[mntsize].f_mntonname[0] = '\0';
- ++mntsize;
- } else
- warn("%s", *argv);
- (void)unmount(mntpt, 0);
- (void)rmdir(mntpt);
- continue;
- }
} else
mntpt = *argv;
/*
@@ -419,71 +399,35 @@ prtstat(sfsp, maxwidth)
(void)printf(" %s\n", sfsp->f_mntonname);
}
-/*
- * This code constitutes the pre-system call Berkeley df code for extracting
- * information from filesystem superblocks.
- */
-#include <ufs/ffs/fs.h>
-#include <errno.h>
-#include <fstab.h>
-
-union {
- struct fs iu_fs;
- char dummy[SBSIZE];
-} sb;
-#define sblock sb.iu_fs
-
-int rfd;
-
int
-ufs_df(file, sfsp)
+raw_df(file, sfsp)
char *file;
struct statfs *sfsp;
{
- char *mntpt;
- static int synced;
-
- if (synced++ == 0)
- sync();
+ int rfd;
if ((rfd = open(file, O_RDONLY)) < 0) {
warn("%s", file);
return (-1);
}
- if (bread((off_t)SBOFF, &sblock, SBSIZE) == 0) {
- (void)close(rfd);
- return (-1);
- }
- if (sblock.fs_magic != FS_MAGIC) {
- (void)close(rfd);
+
+ if (ffs_df(rfd, file, sfsp) == 0) {
+ return (0);
+ } else if (lfs_df(rfd, file, sfsp) == 0) {
+ return (0);
+ } else if (e2fs_df(rfd, file, sfsp) == 0) {
+ return (0);
+ } else {
return (-1);
}
- sfsp->f_type = 0;
- sfsp->f_flags = 0;
- sfsp->f_bsize = sblock.fs_fsize;
- sfsp->f_iosize = sblock.fs_bsize;
- sfsp->f_blocks = sblock.fs_dsize;
- sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
- sblock.fs_cstotal.cs_nffree;
- sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
- (sblock.fs_dsize - sfsp->f_bfree);
- if (sfsp->f_bavail < 0)
- sfsp->f_bavail = 0;
- sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg;
- sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
- sfsp->f_fsid.val[0] = 0;
- sfsp->f_fsid.val[1] = 0;
- if ((mntpt = getmntpt(file)) == 0)
- mntpt = "";
- memmove(&sfsp->f_mntonname[0], mntpt, MNAMELEN);
- memmove(&sfsp->f_mntfromname[0], file, MNAMELEN);
- strncpy(sfsp->f_fstypename, MOUNT_FFS, MFSNAMELEN);
- (void)close(rfd);
- return (0);
+
+ close (rfd);
+
}
int
-bread(off, buf, cnt)
+bread(rfd, off, buf, cnt)
+ int rfd;
off_t off;
void *buf;
int cnt;
diff --git a/bin/df/ext2fs_df.c b/bin/df/ext2fs_df.c
new file mode 100644
index 00000000000..fbd22cdecf1
--- /dev/null
+++ b/bin/df/ext2fs_df.c
@@ -0,0 +1,111 @@
+/*
+ * This file is substantially derived from src/sys/ufs/ext2fs/ext2fs_vfsops.c:e2fs_statfs().
+ * That file's copyright is applied here.
+ */
+
+/* Modified for EXT2FS on NetBSD by Manuel Bouyer, April 1997 */
+
+/*
+ * Copyright (c) 1989, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)ffs_vfsops.c 8.14 (Berkeley) 11/28/94
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <fstab.h>
+#include <ufs/ext2fs/ext2fs.h>
+#include <ufs/ext2fs/ext2fs_dinode.h>
+
+int e2fs_df __P((int, char *, struct statfs *));
+
+extern int bread __P((int, off_t, void *, int));
+extern char *getmntpt __P((char *));
+
+union {
+ struct ext2fs ie_fs;
+ char dummy[SBSIZE];
+} sb;
+#define sblock sb.ie_fs
+
+int
+e2fs_df(rfd, file, sfsp)
+ int rfd;
+ char *file;
+ struct statfs *sfsp;
+{
+ char *mntpt;
+ u_int32_t overhead, overhead_per_group;
+ int32_t ncg, ngdb, ipb, itpg;
+
+ if (bread(rfd, (off_t)SBOFF, &sblock, SBSIZE) == 0) {
+ return (-1);
+ }
+ if ((sblock.e2fs_magic != E2FS_MAGIC) ||
+ (sblock.e2fs_rev != E2FS_REV)) {
+ return (-1);
+ }
+ sfsp->f_type = 0; /* Unused field, set to 0 */
+ sfsp->f_flags = 0; /* The fs is not mapped, so no flags */
+ sfsp->f_bsize = 1024 << sblock.e2fs_log_bsize;
+ sfsp->f_iosize = 1024 << sblock.e2fs_log_bsize;
+
+ ipb = sfsp->f_bsize / sizeof(struct ext2fs_dinode);
+ itpg = sblock.e2fs_ipg/ipb;
+
+ ncg = howmany(sblock.e2fs_bcount - sblock.e2fs_first_dblock,
+ sblock.e2fs_bpg);
+ ngdb = howmany(ncg, sfsp->f_bsize / sizeof(struct ext2_gd));
+ overhead_per_group = 1 /* super block */ +
+ ngdb +
+ 1 /* block bitmap */ +
+ 1 /* inode bitmap */ +
+ itpg;
+ overhead = sblock.e2fs_first_dblock + ncg * overhead_per_group;
+
+ sfsp->f_blocks = sblock.e2fs_bcount - overhead;
+ sfsp->f_bfree = sblock.e2fs_fbcount;
+ sfsp->f_bavail = sfsp->f_bfree - sblock.e2fs_rbcount;
+ sfsp->f_files = sblock.e2fs_icount;
+ sfsp->f_ffree = sblock.e2fs_ficount;
+ sfsp->f_fsid.val[0] = 0;
+ sfsp->f_fsid.val[1] = 0;
+ if ((mntpt = getmntpt(file)) == 0)
+ mntpt = "";
+ memmove(&sfsp->f_mntonname[0], mntpt, MNAMELEN);
+ memmove(&sfsp->f_mntfromname[0], file, MNAMELEN);
+ strncpy(sfsp->f_fstypename, MOUNT_EXT2FS, MFSNAMELEN-1);
+ sfsp->f_fstypename[MFSNAMELEN-1] = '\0';
+ return (0);
+}
diff --git a/bin/df/ffs_df.c b/bin/df/ffs_df.c
new file mode 100644
index 00000000000..88778f996f0
--- /dev/null
+++ b/bin/df/ffs_df.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1980, 1990, 1993, 1994
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1980, 1990, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+
+int ffs_df __P((int, char *, struct statfs *));
+
+extern int bread __P((int, off_t, void *, int));
+extern char *getmntpt __P((char *));
+
+union {
+ struct fs iu_fs;
+ char dummy[SBSIZE];
+} sb;
+#define sblock sb.iu_fs
+
+int
+ffs_df(rfd, file, sfsp)
+ int rfd;
+ char *file;
+ struct statfs *sfsp;
+{
+ char *mntpt;
+
+ if (bread(rfd, (off_t)SBOFF, &sblock, SBSIZE) == 0) {
+ return (-1);
+ }
+ if (sblock.fs_magic != FS_MAGIC) {
+ return (-1);
+ }
+ sfsp->f_type = 0;
+ sfsp->f_flags = 0;
+ sfsp->f_bsize = sblock.fs_fsize;
+ sfsp->f_iosize = sblock.fs_bsize;
+ sfsp->f_blocks = sblock.fs_dsize;
+ sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
+ sblock.fs_cstotal.cs_nffree;
+ sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
+ (sblock.fs_dsize - sfsp->f_bfree);
+ sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg - ROOTINO;
+ sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
+ sfsp->f_fsid.val[0] = 0;
+ sfsp->f_fsid.val[1] = 0;
+ if ((mntpt = getmntpt(file)) == 0)
+ mntpt = "";
+ memmove(&sfsp->f_mntonname[0], mntpt, MNAMELEN);
+ memmove(&sfsp->f_mntfromname[0], file, MNAMELEN);
+ strncpy(sfsp->f_fstypename, MOUNT_FFS, MFSNAMELEN-1);
+ sfsp->f_fstypename[MFSNAMELEN-1] = '\0';
+ return (0);
+}
diff --git a/bin/df/lfs_df.c b/bin/df/lfs_df.c
new file mode 100644
index 00000000000..cf6121462f5
--- /dev/null
+++ b/bin/df/lfs_df.c
@@ -0,0 +1,98 @@
+/*
+ * This file is substantially duplicated from src/sys/ufs/lfs/lfs_vfsops.c:lfs_statfs().
+ * That file's copyright is applied here.
+ */
+/*
+ * Copyright (c) 1989, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)lfs_vfsops.c 8.20 (Berkeley) 6/10/95
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <fstab.h>
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/lfs/lfs.h>
+
+int lfs_df __P((int, char *, struct statfs *));
+
+extern int bread __P((int, off_t, void *, int));
+extern char *getmntpt __P((char *));
+
+union {
+ struct lfs il_fs;
+ char dummy[LFS_SBPAD];
+} sb;
+#define sblock sb.il_fs
+
+int
+lfs_df(rfd, file, sfsp)
+ int rfd;
+ char *file;
+ struct statfs *sfsp;
+{
+ char *mntpt;
+
+ if (bread(rfd, (off_t)LFS_LABELPAD, &sblock, LFS_SBPAD) == 0) {
+ return (-1);
+ }
+ if (sblock.lfs_magic != LFS_MAGIC) {
+ return (-1);
+ }
+ sfsp->f_type = 0; /* Unused field, set to 0 */
+ sfsp->f_flags = 0; /* The fs is not mapped, so no flags */
+ sfsp->f_bsize = sblock.lfs_bsize;
+ sfsp->f_iosize = sblock.lfs_bsize;
+ sfsp->f_blocks = dbtofrags(&sblock, sblock.lfs_dsize);
+ sfsp->f_bfree = dbtofrags(&sblock, sblock.lfs_bfree);
+ sfsp->f_bavail = sblock.lfs_dsize * (100 - sblock.lfs_minfree) / 100;
+ sfsp->f_bavail = (sfsp->f_bavail > sblock.lfs_bfree) ?
+ sblock.lfs_bfree : sfsp->f_bavail;
+ sfsp->f_bavail = dbtofrags(&sblock, sfsp->f_bavail);
+ if (sfsp->f_bavail < 0)
+ sfsp->f_bavail = 0;
+
+ sfsp->f_files = sblock.lfs_nfiles;
+ sfsp->f_ffree = sblock.lfs_bfree * sblock.lfs_inopb;
+ sfsp->f_fsid.val[0] = 0;
+ sfsp->f_fsid.val[1] = 0;
+ if ((mntpt = getmntpt(file)) == 0)
+ mntpt = "";
+ memmove(&sfsp->f_mntonname[0], mntpt, MNAMELEN);
+ memmove(&sfsp->f_mntfromname[0], file, MNAMELEN);
+ strncpy(sfsp->f_fstypename, MOUNT_LFS, MFSNAMELEN-1);
+ sfsp->f_fstypename[MFSNAMELEN-1] = '\0';
+ return (0);
+}