Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/resize_ffs Add support for byteswapped file systems (bi...



details:   https://anonhg.NetBSD.org/src/rev/2c09d2c6ca74
branches:  trunk
changeset: 760440:2c09d2c6ca74
user:      riz <riz%NetBSD.org@localhost>
date:      Wed Jan 05 02:18:15 2011 +0000

description:
Add support for byteswapped file systems (big-endian on little-endian
host, and vice versa), to fix PR#44203.

Add support for growing (but not yet shrinking) UFS2 file systems.  Partially
addresses PR#44205.

While I'm here, reformat the code for closer adherence to KNF.

Fairly extensive testing was performed, using the shortly-to-be-committed
updated ATF tests.  Patch posted to tech-userlevel on 21 December 2010,
no comments.

diffstat:

 sbin/resize_ffs/Makefile     |    7 +-
 sbin/resize_ffs/TODO         |    6 +-
 sbin/resize_ffs/resize_ffs.8 |   40 +--
 sbin/resize_ffs/resize_ffs.c |  512 ++++++++++++++++++++++++++++--------------
 4 files changed, 364 insertions(+), 201 deletions(-)

diffs (truncated from 1109 to 300 lines):

diff -r e75a50145c95 -r 2c09d2c6ca74 sbin/resize_ffs/Makefile
--- a/sbin/resize_ffs/Makefile  Wed Jan 05 00:09:43 2011 +0000
+++ b/sbin/resize_ffs/Makefile  Wed Jan 05 02:18:15 2011 +0000
@@ -1,8 +1,13 @@
-#      $NetBSD: Makefile,v 1.2 2009/04/26 05:57:48 lukem Exp $
+#      $NetBSD: Makefile,v 1.3 2011/01/05 02:18:15 riz Exp $
+
+.include <bsd.own.mk>
 
 WARNS?=        3       # XXX: sign-compare issues
 
 PROG=resize_ffs
 MAN=resize_ffs.8
+SRCS=resize_ffs.c ffs_bswap.c
+
+.PATH: ${NETBSDSRCDIR}/sys/ufs/ffs
 
 .include <bsd.prog.mk>
diff -r e75a50145c95 -r 2c09d2c6ca74 sbin/resize_ffs/TODO
--- a/sbin/resize_ffs/TODO      Wed Jan 05 00:09:43 2011 +0000
+++ b/sbin/resize_ffs/TODO      Wed Jan 05 02:18:15 2011 +0000
@@ -1,6 +1,6 @@
 resize_ffs(8) TODO list
 
-* Add support for swapped byte order
-* Fix support for disk blocks of size other than 512 bytes
-* Extend to support UFS2.  Probably growth first, then shrinking separately.
+* Test and likely fix support for disk blocks of size other than 512 bytes
+* Support shrinking UFS2 file systems
+* Make the output a bit more verbose, similar to newfs(8)
 * Expand the testing done in src/tests/sbin/resize_ffs
diff -r e75a50145c95 -r 2c09d2c6ca74 sbin/resize_ffs/resize_ffs.8
--- a/sbin/resize_ffs/resize_ffs.8      Wed Jan 05 00:09:43 2011 +0000
+++ b/sbin/resize_ffs/resize_ffs.8      Wed Jan 05 02:18:15 2011 +0000
@@ -1,4 +1,4 @@
-.\"     $NetBSD: resize_ffs.8,v 1.9 2010/12/20 00:49:23 riz Exp $
+.\"     $NetBSD: resize_ffs.8,v 1.10 2011/01/05 02:18:15 riz 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
@@ -9,22 +9,22 @@
 .\"  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 October 30, 2010
+.Dd January 4, 2011
 .Dt RESIZE_FFS 8
 .Os
 .Sh NAME
 .Nm resize_ffs
-.Nd resize an on-disk file system
+.Nd resize a file system on disk or in a file
 .Sh SYNOPSIS
 .Nm
 .Op Fl y
 .Op Fl s Ar size
-.Ar file-system-raw-device
+.Ar special
 .Sh DESCRIPTION
 .Nm
-resizes a file system on disk.
-.Ar file-system-raw-device
-is the name of the raw disk device where the file system resides;
+resizes a file system.
+.Ar special
+is the name of the raw disk device or file where the file system resides;
 (Sectors are almost always 512 bytes, and
 .Nm
 can both grow and shrink file systems.
@@ -53,7 +53,7 @@
 .Nm
 will grow the file system to the underlying device size which is
 determined from
-.Ar file-system-raw-device .
+.Ar special .
 .Pp
 The options are as follows:
 .Bl -tag -width indent
@@ -66,10 +66,6 @@
 .Nm .
 .El
 .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"
@@ -88,16 +84,7 @@
 It's probably wise to
 .Xr fsck 8
 the file system before and after, just to be safe.
-.\" Remove this when (if) fsck gets fixed.
-.Pp
-There is a bug somewhere in
-.Xr fsck 8 ;
-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
+You should be aware that just because
 .Xr fsck 8
 is happy with the file system does not mean it is intact.
 .Sh EXIT STATUS
@@ -127,15 +114,16 @@
 .Sh AUTHORS
 .An der Mouse
 .Aq mouse%rodents.montreal.qc.ca@localhost
+(primary author)
+.An Jeff Rizzo
+.Aq riz%NetBSD.org@localhost
+(Byteswapped file system and UFS2 support)
 .Pp
 A big bug-finding kudos goes to John Kohl for finding the rotational
 layout bug referred to in the
 .Sx 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 file system 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.
@@ -146,4 +134,4 @@
 Has no intelligence whatever when it comes to allocating blocks to copy
 data into when shrinking.
 .Pp
-Doesn't work with FFSv2 file systems.
+Doesn't currently support shrinking FFSv2 file systems.
diff -r e75a50145c95 -r 2c09d2c6ca74 sbin/resize_ffs/resize_ffs.c
--- a/sbin/resize_ffs/resize_ffs.c      Wed Jan 05 00:09:43 2011 +0000
+++ b/sbin/resize_ffs/resize_ffs.c      Wed Jan 05 02:18:15 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: resize_ffs.c,v 1.24 2010/12/14 21:49:21 wiz Exp $      */
+/*     $NetBSD: resize_ffs.c,v 1.25 2011/01/05 02:18:15 riz Exp $      */
 /* From sources sent on February 17, 2003 */
 /*-
  * As its sole author, I explicitly place this code in the public
@@ -27,11 +27,6 @@
  *  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 file systems 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
@@ -49,6 +44,7 @@
 #include <sys/mman.h>
 #include <sys/param.h>         /* MAXFRAG */
 #include <ufs/ffs/fs.h>
+#include <ufs/ffs/ffs_extern.h>
 #include <ufs/ufs/dir.h>
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/ufs_bswap.h> /* ufs_rw32 */
@@ -62,7 +58,7 @@
 #include <unistd.h>
 
 /* new size of file system, in sectors */
-static uint32_t newsize;
+static uint64_t newsize;
 
 /* fd open onto disk device or file */
 static int fd;
@@ -85,6 +81,22 @@
 static char sbbuf[2 * SBLOCKSIZE]
        __attribute__((__aligned__(__alignof__(struct fs))));
 
+union dinode {
+       struct ufs1_dinode dp1;
+       struct ufs2_dinode dp2;
+};
+#define DIP(dp, field)                                                       \
+       ((is_ufs2) ?                                                          \
+           (dp)->dp2.field : (dp)->dp1.field)
+
+#define DIP_ASSIGN(dp, field, value)                                         \
+       do {                                                                  \
+               if (is_ufs2)                                                  \
+                       (dp)->dp2.field = (value);                            \
+               else                                                          \
+                       (dp)->dp1.field = (value);                            \
+       } while (0)
+
 /* a cg's worth of brand new squeaky-clean inodes */
 static struct ufs1_dinode *zinodes;
 
@@ -108,7 +120,12 @@
 static unsigned int *inomove;
 
 /* in-core copies of all inodes in the fs, indexed by inumber */
-static struct ufs1_dinode *inodes;
+union dinode *inodes;
+
+void *ibuf;    /* ptr to fs block-sized buffer for reading/writing inodes */
+
+/* byteswapped inodes */
+union dinode *sinodes;
 
 /* per-inode flags, indexed by inumber */
 static unsigned char *iflags;
@@ -119,17 +136,16 @@
 
 /* resize_ffs works directly on dinodes, adapt blksize() */
 #define dblksize(fs, dip, lbn) \
-    (((lbn) >= NDADDR || (dip)->di_size >= lblktosize(fs, (lbn) + 1)) \
-    ? (fs)->fs_bsize \
-    : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
+       (((lbn) >= NDADDR || DIP((dip), di_size) >= lblktosize(fs, (lbn) + 1)) \
+           ? (fs)->fs_bsize                                                   \
+           : (fragroundup(fs, blkoff(fs, DIP((dip), di_size)))))
 
 
 /*
- * Number of disk sectors per block/fragment; assumes DEV_BSIZE byte
- * sector size. 
+ * Number of disk sectors per block/fragment
  */ 
-#define NSPB(fs)       ((fs)->fs_old_nspf << (fs)->fs_fragshift)
-#define NSPF(fs)       ((fs)->fs_old_nspf)
+#define NSPB(fs)       (fsbtodb((fs),1) << (fs)->fs_fragshift)
+#define NSPF(fs)       (fsbtodb((fs),1))
 
 /* global flags */
 int is_ufs2 = 0;
@@ -198,7 +214,8 @@
                if (rv < 0)
                        err(EXIT_FAILURE, "read failed");
                if (rv != size)
-                       errx(EXIT_FAILURE, "read: wanted %d, got %d", size, rv);
+                       errx(EXIT_FAILURE, "read: wanted %d, got %d",
+                           size, rv);
        }
 }
 /*
@@ -310,10 +327,14 @@
        for (cg = 0; cg < oldsb->fs_ncg; cg++) {
                cgs[cg] = (struct cg *) cgp;
                readat(fsbtodb(oldsb, cgtod(oldsb, cg)), cgp, cgblksz);
+               if (needswap)
+                       ffs_cg_swap(cgs[cg],cgs[cg],oldsb);
                cgflags[cg] = 0;
                cgp += cgblksz;
        }
        readat(fsbtodb(oldsb, oldsb->fs_csaddr), csums, oldsb->fs_cssize);
+       if (needswap)
+               ffs_csum_swap(csums,csums,oldsb->fs_cssize);
 }
 /*
  * Set n bits, starting with bit #base, in the bitmap pointed to by
@@ -363,7 +384,7 @@
                base = (base & ~7) + 8;
        }
        if (n >= 8) {
-               bzero(bitvec + (base >> 3), n >> 3);
+               memset(bitvec + (base >> 3), 0, n >> 3);
                base += n & ~7;
                n &= 7;
        }
@@ -437,6 +458,7 @@
        int dmax;               /* Offset of end of post-inode data area */
        int i;                  /* Generic loop index */
        int n;                  /* Generic count */
+       int start;              /* start of cg maps */
 
        cg = cgs[cgn];
        /* Place the data areas */
@@ -446,49 +468,64 @@
        dmax = newsb->fs_size - base;
        if (dmax > newsb->fs_fpg)
                dmax = newsb->fs_fpg;
+       start = &cg->cg_space[0] - (unsigned char *) cg;
        /*
          * Clear out the cg - assumes all-0-bytes is the correct way
          * to initialize fields we don't otherwise touch, which is
          * perhaps not the right thing to do, but it's what fsck and
          * mkfs do.
          */
-       bzero(cg, newsb->fs_cgsize);
-       cg->cg_old_time = newsb->fs_time;
+       memset(cg, 0, newsb->fs_cgsize);
        if (newsb->fs_old_flags & FS_FLAGS_UPDATED)
                cg->cg_time = newsb->fs_time;
        cg->cg_magic = CG_MAGIC;
        cg->cg_cgx = cgn;
-       cg->cg_old_ncyl = newsb->fs_old_cpg;
-       /* Update the cg_old_ncyl value for the last cylinder. */
-       if (cgn == newsb->fs_ncg - 1) {
-               if ((newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0)
-                       cg->cg_old_ncyl = newsb->fs_old_ncyl % newsb->fs_old_cpg;
-       }
-       cg->cg_old_niblk = newsb->fs_ipg;
+       cg->cg_niblk = newsb->fs_ipg;



Home | Main Index | Thread Index | Old Index