Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/resize_ffs Preliminary version of resize_ffs, based on ...
details: https://anonhg.NetBSD.org/src/rev/d7376801b152
branches: trunk
changeset: 543265:d7376801b152
user: jtk <jtk%NetBSD.org@localhost>
date: Fri Feb 21 04:08:54 2003 +0000
description:
Preliminary version of resize_ffs, based on der Mouse's fsresize tool.
I didn't have time to clean it up completely before my legal status
w.r.t. open source projects goes into limbo for a while. Other
developers are encouraged to play with the tool and get it into
release-worthy shape.
TODO list (see TODO file)
* verify it builds on -current, put it into release lists/etc. and src/sbin/Makefile
(built & tested on 1.6.1)
* make it ask questions before doing any work (confirm)
* create regression test suite (see discussions on tech-kern and
developers) and fix any bugs
* verify conversion to ANSI C didn't break anything
* port to UFS2
diffstat:
sbin/resize_ffs/Makefile | 6 +
sbin/resize_ffs/TODO | 15 +
sbin/resize_ffs/resize_ffs.8 | 105 ++
sbin/resize_ffs/resize_ffs.c | 1883 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 2009 insertions(+), 0 deletions(-)
diffs (truncated from 2025 to 300 lines):
diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/Makefile Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile,v 1.1 2003/02/21 04:08:54 jtk Exp $
+
+PROG=resize_ffs
+MAN=resize_ffs.8
+
+.include <bsd.prog.mk>
diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/TODO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/TODO Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,15 @@
+Preliminary version of resize_ffs, based on der Mouse's fsresize tool.
+I didn't have time to clean it up completely before my legal status
+w.r.t. open source projects goes into limbo for a while. Other
+developers are encouraged to play with the tool and get it into
+release-worthy shape.
+
+TODO list (see TODO file)
+
+* verify it builds on -current, put it into release lists/etc. and src/sbin/Makefile
+ (built & tested on 1.6.1)
+* make it ask questions before doing any work (confirm)
+* create regression test suite (see discussions on tech-kern and
+ developers) and fix any bugs
+* verify conversion to ANSI C didn't break anything
+* port to UFS2
diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/resize_ffs.8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/resize_ffs.8 Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,105 @@
+.\" $NetBSD: resize_ffs.8,v 1.1 2003/02/21 04:08:55 jtk Exp $
+.\" As its sole author, I explicitly place this man page in the public
+.\" domain. Anyone may use it in any way for any purpose (though I would
+.\" appreciate credit where it is due).
+.\"
+.\" /~\ The ASCII der Mouse
+.\" \ / Ribbon Campaign
+.\" X Against HTML mouse%rodents.montreal.qc.ca@localhost
+.\" / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
+.Dd February 20, 2003
+.Dt RESIZE_FFS 8
+.Sh NAME
+.Nm resize_ffs
+.Nd resize an on-disk filesystem
+.Sh SYNOPSIS
+.Nm
+.Ar filesystem-raw-device
+.Ar newsize
+.Sh DESCRIPTION
+.Nm
+resizes a filesystem on disk.
+.Ar filesystem
+is the name of the raw disk device where the filesystem resides;
+.Ar newsize
+is the desired new filesystem size, in sectors. (Sectors are almost
+always 512 bytes, and
+.Nm
+can both grow and shrink filesystems. When growing, the disk device
+must of course be large enough to contain the new filesystem;
+.Nm
+simply extends the filesystem data structures into the new space. When
+shrinking,
+.Nm
+assumes this. It will not work correctly for filesystems with other
+sector sizes.)
+.Nm
+has to copy anything that currently resides in the space being shrunk
+away; there must be enough space free on the filesystem for this to
+succeed. If there isn't,
+.Nm
+will complain and exit; when this happens, it attempts to always leave
+the filesystem in a consistent state, but it is probably a good idea to
+check the filesystem with
+.Xr fsck 8 .
+.Pp
+.Sh WARNING
+.Nm
+should still be considered experimental. It still needs to be validated
+with a rigorous regression test suite.
+
+.Em Interrupting
+.Nm
+.Em "may leave your file system in an inconsistent state and require a"
+.Em "restore from backup."
+It attempts to write in the proper order to avoid problems, but as it is
+still considered experimental, you should take great care when using it.
+.Pp
+When
+.Nm
+is applied to a consistent filesystem, it should always produce a
+consistent filesystem; if the filesystem is not consistent to start
+with,
+.Nm
+may misbehave, anything from dumping core to completely curdling the
+data. It's probably wise to
+.Xr fsck 8
+the filesystem before and after, just to be safe.
+.\" Remove this when (if) fsck gets fixed.
+.Pp
+There is a bug somewhere in fsck; it does not check certain data
+structures enough. A past version of this program had a bug that
+produced corrupted rotation layout summary tables, which would panic
+the kernel. This bug is believed fixed, and there are currently no
+known bugs in the program. However, you should be aware that just
+because fsck is happy with the filesystem does not mean it is intact.
+.Sh EXAMPLES
+.Nm
+.Li /dev/rsd1e 29574
+.Sh SEE ALSO
+.Xr fs 5 ,
+.Xr newfs 8 ,
+.Xr fsck 8
+.Sh AUTHOR
+.Li der Mouse <mouse%rodents.montreal.qc.ca@localhost>
+.Pp
+A big bug-finding kudos goes to John Kohl for finding the rotational
+layout bug referred
+to in the WARNING section above.
+.Sh BUGS
+Has not been tested and probably won't work on opposite-endian file
+systems.
+.Pp
+Can fail to shrink a filesystem when there actually is enough space,
+because it does not distinguish between a block allocated as a block
+and a block fully occupied by two or more frags. This is unlikely to
+occur in practice; except for pathological cases, it can happen only
+when the new size is extremely close to the minimum possible.
+.Pp
+Has no intelligence whatever when it comes to allocating blocks to copy
+data into when shrinking.
+.Sh HISTORY
+The
+.Nm
+command first appeared in
+.Nx 2.0 .
diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/resize_ffs.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/resize_ffs.c Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,1883 @@
+/* $NetBSD: resize_ffs.c,v 1.1 2003/02/21 04:08:55 jtk Exp $ */
+/* From sources sent on February 17, 2003 */
+/*-
+ * As its sole author, I explicitly place this code in the public
+ * domain. Anyone may use it for any purpose (though I would
+ * appreciate credit where it is due).
+ *
+ * der Mouse
+ *
+ * mouse%rodents.montreal.qc.ca@localhost
+ * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
+ */
+/*
+ * ffs_resize:
+ *
+ * Resize a filesystem. Is capable of both growing and shrinking.
+ *
+ * Usage: fsresize filesystem newsize
+ *
+ * Example: fsresize /dev/rsd1e 29574
+ *
+ * newsize is in DEV_BSIZE units (ie, disk sectors, usually 512 bytes
+ * each).
+ *
+ * Note: this currently requires gcc to build, since it is written
+ * depending on gcc-specific features, notably nested function
+ * definitions (which in at least a few cases depend on the lexical
+ * scoping gcc provides, so they can't be trivially moved outside).
+ *
+ * It will not do anything useful with filesystems in other than
+ * host-native byte order. This really should be fixed (it's largely
+ * a historical accident; the original version of this program is
+ * older than bi-endian support in FFS).
+ *
+ * Many thanks go to John Kohl <jtk%netbsd.org@localhost> for finding bugs: the
+ * one responsible for the "realloccgblk: can't find blk in cyl"
+ * problem and a more minor one which left fs_dsize wrong when
+ * shrinking. (These actually indicate bugs in fsck too - it should
+ * have caught and fixed them.)
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/param.h> /* MAXFRAG */
+#include <ufs/ufs/dinode.h> /* ufs_daddr_t */
+#include <ufs/ffs/fs.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/ufs_bswap.h> /* ufs_rw32 */
+
+extern const char *__progname;
+
+/* Patchup for systems that don't yet have __progname */
+#ifdef NO_PROGNAME
+const char *__progname;
+int main(int, char **);
+int main_(int, char **);
+int
+main(int ac, char **av)
+#define main main_
+{
+ __progname = av[0];
+ return (main(ac, av));
+}
+#endif
+
+/* Suppress warnings about unused arguments */
+#if defined(__GNUC__) && \
+ ( (__GNUC__ > 2) || \
+ ( (__GNUC__ == 2) && \
+ defined(__GNUC_MINOR__) && \
+ (__GNUC_MINOR__ >= 7) ) )
+#define UNUSED_ARG(x) x __attribute__((__unused__))
+#define INLINE inline
+#else
+#define UNUSED_ARG(x) x
+#define INLINE /**/
+#endif
+
+/* new size of filesystem, in sectors */
+static int newsize;
+
+/* fd open onto disk device */
+static int fd;
+
+/* must we break up big I/O operations - see checksmallio() */
+static int smallio;
+
+/* size of a cg, in bytes, rounded up to a frag boundary */
+static int cgblksz;
+
+/* Superblocks. */
+static struct fs *oldsb; /* before we started */
+static struct fs *newsb; /* copy to work with */
+/* Buffer to hold the above. Make sure it's aligned correctly. */
+static char sbbuf[2 * SBSIZE] __attribute__((__aligned__(__alignof__(struct fs))));
+
+/* a cg's worth of brand new squeaky-clean inodes */
+static struct dinode *zinodes;
+
+/* pointers to the in-core cgs, read off disk and possibly modified */
+static struct cg **cgs;
+
+/* pointer to csum array - the stuff pointed to on-disk by fs_csaddr */
+static struct csum *csums;
+
+/* per-cg flags, indexed by cg number */
+static unsigned char *cgflags;
+#define CGF_DIRTY 0x01 /* needs to be written to disk */
+#define CGF_BLKMAPS 0x02 /* block bitmaps need rebuilding */
+#define CGF_INOMAPS 0x04 /* inode bitmaps need rebuilding */
+
+/* when shrinking, these two arrays record how we want blocks to move. */
+/* if blkmove[i] is j, the frag that started out as frag #i should end */
+/* up as frag #j. inomove[i]=j means, similarly, that the inode that */
+/* started out as inode i should end up as inode j. */
+static unsigned int *blkmove;
+static unsigned int *inomove;
+
+/* in-core copies of all inodes in the fs, indexed by inumber */
+static struct dinode *inodes;
+
+/* per-inode flags, indexed by inumber */
+static unsigned char *iflags;
+#define IF_DIRTY 0x01 /* needs to be written to disk */
+#define IF_BDIRTY 0x02 /* like DIRTY, but is set on first inode in a
+ * block of inodes, and applies to the whole
+ * block. */
+
+/*
+ * See if we need to break up large I/O operations. This should never
+ * be needed, but under at least one <version,platform> combination,
+ * large enough disk transfers to the raw device hang. So if we're
+ * talking to a character special device, play it safe; in this case,
+ * readat() and writeat() break everything up into pieces no larger
+ * than 8K, doing multiple syscalls for larger operations.
+ */
+static void
+checksmallio(void)
+{
+ struct stat stb;
+
+ fstat(fd, &stb);
+ smallio = ((stb.st_mode & S_IFMT) == S_IFCHR);
+}
+/*
+ * Read size bytes starting at blkno into buf. blkno is in DEV_BSIZE
+ * units, ie, after fsbtodb(); size is in bytes.
+ */
+static void
+readat(off_t blkno, void *buf, int size)
Home |
Main Index |
Thread Index |
Old Index