diff options
author | denny <denny@cvs.openbsd.org> | 1997-06-16 04:37:51 +0000 |
---|---|---|
committer | denny <denny@cvs.openbsd.org> | 1997-06-16 04:37:51 +0000 |
commit | 917618fd0d4785021ed5c6f96f068964606abaa7 (patch) | |
tree | 4f7a6593c8f299e8bb48793499edfe19cdcbd76f | |
parent | 7e648a5e6d2f98a29cf7cc995989553a1b895e94 (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/Makefile | 3 | ||||
-rw-r--r-- | bin/df/df.c | 106 | ||||
-rw-r--r-- | bin/df/ext2fs_df.c | 111 | ||||
-rw-r--r-- | bin/df/ffs_df.c | 97 | ||||
-rw-r--r-- | bin/df/lfs_df.c | 98 |
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); +} |