Mon Sep 5 10:44:36 2016 UTC ()
Add a bit of swapping for values in CG descriptors (used to be done
wholesale in e2fs_cgsave, but now common code keeps them in FS byte
order). Seems to fix newfs_ext2fs on big endian hosts.


(martin)
diff -r1.24 -r1.25 src/sbin/newfs_ext2fs/mke2fs.c

cvs diff -r1.24 -r1.25 src/sbin/newfs_ext2fs/mke2fs.c (expand / switch to unified diff)

--- src/sbin/newfs_ext2fs/mke2fs.c 2016/08/04 17:43:47 1.24
+++ src/sbin/newfs_ext2fs/mke2fs.c 2016/09/05 10:44:36 1.25
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: mke2fs.c,v 1.24 2016/08/04 17:43:47 jdolecek Exp $ */ 1/* $NetBSD: mke2fs.c,v 1.25 2016/09/05 10:44:36 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Izumi Tsutsui. All rights reserved. 4 * Copyright (c) 2007 Izumi Tsutsui. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -90,27 +90,27 @@ @@ -90,27 +90,27 @@
90 * - Ext2fs Home Page 90 * - Ext2fs Home Page
91 * http://e2fsprogs.sourceforge.net/ext2.html 91 * http://e2fsprogs.sourceforge.net/ext2.html
92 * - Design and Implementation of the Second Extended Filesystem 92 * - Design and Implementation of the Second Extended Filesystem
93 * http://e2fsprogs.sourceforge.net/ext2intro.html 93 * http://e2fsprogs.sourceforge.net/ext2intro.html
94 * - Linux Documentation "The Second Extended Filesystem" 94 * - Linux Documentation "The Second Extended Filesystem"
95 * http://www.kernel.org/doc/Documentation/filesystems/ext2.txt 95 * http://www.kernel.org/doc/Documentation/filesystems/ext2.txt
96 */ 96 */
97 97
98#include <sys/cdefs.h> 98#include <sys/cdefs.h>
99#ifndef lint 99#ifndef lint
100#if 0 100#if 0
101static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95"; 101static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
102#else 102#else
103__RCSID("$NetBSD: mke2fs.c,v 1.24 2016/08/04 17:43:47 jdolecek Exp $"); 103__RCSID("$NetBSD: mke2fs.c,v 1.25 2016/09/05 10:44:36 martin Exp $");
104#endif 104#endif
105#endif /* not lint */ 105#endif /* not lint */
106 106
107#include <sys/param.h> 107#include <sys/param.h>
108#include <sys/mman.h> 108#include <sys/mman.h>
109#include <sys/time.h> 109#include <sys/time.h>
110#include <ufs/ext2fs/ext2fs_dinode.h> 110#include <ufs/ext2fs/ext2fs_dinode.h>
111#include <ufs/ext2fs/ext2fs_dir.h> 111#include <ufs/ext2fs/ext2fs_dir.h>
112#include <ufs/ext2fs/ext2fs.h> 112#include <ufs/ext2fs/ext2fs.h>
113#include <sys/ioctl.h> 113#include <sys/ioctl.h>
114 114
115#include <err.h> 115#include <err.h>
116#include <errno.h> 116#include <errno.h>
@@ -485,44 +485,47 @@ mke2fs(const char *fsys, int fi, int fo) @@ -485,44 +485,47 @@ mke2fs(const char *fsys, int fi, int fo)
485 uint boffset; 485 uint boffset;
486 486
487 boffset = cgbase(&sblock, cylno); 487 boffset = cgbase(&sblock, cylno);
488 if (sblock.e2fs.e2fs_rev == E2FS_REV0 || 488 if (sblock.e2fs.e2fs_rev == E2FS_REV0 ||
489 (sblock.e2fs.e2fs_features_rocompat & 489 (sblock.e2fs.e2fs_features_rocompat &
490 EXT2F_ROCOMPAT_SPARSESUPER) == 0 || 490 EXT2F_ROCOMPAT_SPARSESUPER) == 0 ||
491 cg_has_sb(cylno)) { 491 cg_has_sb(cylno)) {
492 boffset += NBLOCK_SUPERBLOCK + sblock.e2fs_ngdb; 492 boffset += NBLOCK_SUPERBLOCK + sblock.e2fs_ngdb;
493 if (sblock.e2fs.e2fs_rev > E2FS_REV0 && 493 if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
494 (sblock.e2fs.e2fs_features_compat & 494 (sblock.e2fs.e2fs_features_compat &
495 EXT2F_COMPAT_RESIZE) != 0) 495 EXT2F_COMPAT_RESIZE) != 0)
496 boffset += sblock.e2fs.e2fs_reserved_ngdb; 496 boffset += sblock.e2fs.e2fs_reserved_ngdb;
497 } 497 }
498 gd[cylno].ext2bgd_b_bitmap = boffset; 498 gd[cylno].ext2bgd_b_bitmap = h2fs32(boffset);
499 boffset += NBLOCK_BLOCK_BITMAP; 499 boffset += NBLOCK_BLOCK_BITMAP;
500 gd[cylno].ext2bgd_i_bitmap = boffset; 500 gd[cylno].ext2bgd_i_bitmap = h2fs32(boffset);
501 boffset += NBLOCK_INODE_BITMAP; 501 boffset += NBLOCK_INODE_BITMAP;
502 gd[cylno].ext2bgd_i_tables = boffset; 502 gd[cylno].ext2bgd_i_tables = h2fs32(boffset);
503 if (cylno == (ncg - 1)) 503 if (cylno == (ncg - 1))
504 gd[cylno].ext2bgd_nbfree = 504 gd[cylno].ext2bgd_nbfree = h2fs16(
505 blocks_lastcg - cgoverhead(cylno); 505 blocks_lastcg - cgoverhead(cylno));
506 else 506 else
507 gd[cylno].ext2bgd_nbfree = 507 gd[cylno].ext2bgd_nbfree = h2fs16(
508 sblock.e2fs.e2fs_bpg - cgoverhead(cylno); 508 sblock.e2fs.e2fs_bpg - cgoverhead(cylno));
509 fbcount += gd[cylno].ext2bgd_nbfree; 509 fbcount += fs2h16(gd[cylno].ext2bgd_nbfree);
510 gd[cylno].ext2bgd_nifree = sblock.e2fs.e2fs_ipg; 
511 if (cylno == 0) { 510 if (cylno == 0) {
512 /* take reserved inodes off nifree */ 511 /* take reserved inodes off nifree */
513 gd[cylno].ext2bgd_nifree -= EXT2_RESERVED_INODES; 512 gd[cylno].ext2bgd_nifree = h2fs16(
 513 sblock.e2fs.e2fs_ipg-EXT2_RESERVED_INODES);
 514 } else {
 515 gd[cylno].ext2bgd_nifree =
 516 h2fs16(sblock.e2fs.e2fs_ipg);
514 } 517 }
515 ficount += gd[cylno].ext2bgd_nifree; 518 ficount += fs2h16(gd[cylno].ext2bgd_nifree);
516 gd[cylno].ext2bgd_ndirs = 0; 519 gd[cylno].ext2bgd_ndirs = 0;
517 } 520 }
518 sblock.e2fs.e2fs_fbcount = fbcount; 521 sblock.e2fs.e2fs_fbcount = fbcount;
519 sblock.e2fs.e2fs_ficount = ficount; 522 sblock.e2fs.e2fs_ficount = ficount;
520 523
521 /* 524 /*
522 * Dump out summary information about file system. 525 * Dump out summary information about file system.
523 */ 526 */
524 if (verbosity > 0) { 527 if (verbosity > 0) {
525 printf("%s: %u.%1uMB (%" PRId64 " sectors) " 528 printf("%s: %u.%1uMB (%" PRId64 " sectors) "
526 "block size %u, fragment size %u\n", 529 "block size %u, fragment size %u\n",
527 fsys, 530 fsys,
528 (uint)(((uint64_t)bcount * bsize) / (1024 * 1024)), 531 (uint)(((uint64_t)bcount * bsize) / (1024 * 1024)),
@@ -719,62 +722,62 @@ initcg(uint cylno) @@ -719,62 +722,62 @@ initcg(uint cylno)
719 /* The last group could have less blocks than e2fs_bpg. */ 722 /* The last group could have less blocks than e2fs_bpg. */
720 nblcg = sblock.e2fs.e2fs_bcount - 723 nblcg = sblock.e2fs.e2fs_bcount -
721 cgbase(&sblock, sblock.e2fs_ncg - 1); 724 cgbase(&sblock, sblock.e2fs_ncg - 1);
722 for (i = nblcg; i < roundup(nblcg, NBBY); i++) 725 for (i = nblcg; i < roundup(nblcg, NBBY); i++)
723 setbit(buf, i); 726 setbit(buf, i);
724 memset(&buf[i / NBBY], ~0U, sblock.e2fs.e2fs_bpg - i); 727 memset(&buf[i / NBBY], ~0U, sblock.e2fs.e2fs_bpg - i);
725 } 728 }
726 /* set overhead (superblock, group descriptor etc.) blocks used */ 729 /* set overhead (superblock, group descriptor etc.) blocks used */
727 for (i = 0; i < cgoverhead(cylno) / NBBY; i++) 730 for (i = 0; i < cgoverhead(cylno) / NBBY; i++)
728 buf[i] = ~0; 731 buf[i] = ~0;
729 i = i * NBBY; 732 i = i * NBBY;
730 for (; i < cgoverhead(cylno); i++) 733 for (; i < cgoverhead(cylno); i++)
731 setbit(buf, i); 734 setbit(buf, i);
732 wtfs(EXT2_FSBTODB(&sblock, gd[cylno].ext2bgd_b_bitmap), 735 wtfs(EXT2_FSBTODB(&sblock, fs2h32(gd[cylno].ext2bgd_b_bitmap)),
733 sblock.e2fs_bsize, buf); 736 sblock.e2fs_bsize, buf);
734 737
735 /* 738 /*
736 * Initialize inode bitmap. 739 * Initialize inode bitmap.
737 * 740 *
738 * Assume e2fs_ipg is a multiple of NBBY since 741 * Assume e2fs_ipg is a multiple of NBBY since
739 * it's a multiple of e2fs_ipb (as we did above). 742 * it's a multiple of e2fs_ipb (as we did above).
740 * Note even (possibly smaller) the last group has the same e2fs_ipg. 743 * Note even (possibly smaller) the last group has the same e2fs_ipg.
741 */ 744 */
742 i = sblock.e2fs.e2fs_ipg / NBBY; 745 i = sblock.e2fs.e2fs_ipg / NBBY;
743 memset(buf, 0, i); 746 memset(buf, 0, i);
744 memset(buf + i, ~0U, sblock.e2fs_bsize - i); 747 memset(buf + i, ~0U, sblock.e2fs_bsize - i);
745 if (cylno == 0) { 748 if (cylno == 0) {
746 /* mark reserved inodes */ 749 /* mark reserved inodes */
747 for (i = 1; i < EXT2_FIRSTINO; i++) 750 for (i = 1; i < EXT2_FIRSTINO; i++)
748 setbit(buf, EXT2_INO_INDEX(i)); 751 setbit(buf, EXT2_INO_INDEX(i));
749 } 752 }
750 wtfs(EXT2_FSBTODB(&sblock, gd[cylno].ext2bgd_i_bitmap), 753 wtfs(EXT2_FSBTODB(&sblock, fs2h32(gd[cylno].ext2bgd_i_bitmap)),
751 sblock.e2fs_bsize, buf); 754 sblock.e2fs_bsize, buf);
752 755
753 /* 756 /*
754 * Initialize inode tables. 757 * Initialize inode tables.
755 * 758 *
756 * Just initialize generation numbers for NFS security. 759 * Just initialize generation numbers for NFS security.
757 * XXX: sys/ufs/ext2fs/ext2fs_alloc.c:ext2fs_valloc() seems 760 * XXX: sys/ufs/ext2fs/ext2fs_alloc.c:ext2fs_valloc() seems
758 * to override these generated numbers. 761 * to override these generated numbers.
759 */ 762 */
760 memset(buf, 0, sblock.e2fs_bsize); 763 memset(buf, 0, sblock.e2fs_bsize);
761 for (i = 0; i < sblock.e2fs_itpg; i++) { 764 for (i = 0; i < sblock.e2fs_itpg; i++) {
762 for (j = 0; j < sblock.e2fs_ipb; j++) { 765 for (j = 0; j < sblock.e2fs_ipb; j++) {
763 dp = (struct ext2fs_dinode *)(buf + inodesize * j); 766 dp = (struct ext2fs_dinode *)(buf + inodesize * j);
764 /* h2fs32() just for consistency */ 767 /* h2fs32() just for consistency */
765 dp->e2di_gen = h2fs32(arc4random()); 768 dp->e2di_gen = h2fs32(arc4random());
766 } 769 }
767 wtfs(EXT2_FSBTODB(&sblock, gd[cylno].ext2bgd_i_tables + i), 770 wtfs(EXT2_FSBTODB(&sblock, fs2h32(gd[cylno].ext2bgd_i_tables) + i),
768 sblock.e2fs_bsize, buf); 771 sblock.e2fs_bsize, buf);
769 } 772 }
770} 773}
771 774
772/* 775/*
773 * Zap possible lingering old superblock data 776 * Zap possible lingering old superblock data
774 */ 777 */
775static void 778static void
776zap_old_sblock(int sblkoff) 779zap_old_sblock(int sblkoff)
777{ 780{
778 static int cg0_data; 781 static int cg0_data;
779 uint32_t oldfs[SBSIZE / sizeof(uint32_t)]; 782 uint32_t oldfs[SBSIZE / sizeof(uint32_t)];
780 static const struct fsm { 783 static const struct fsm {
@@ -1254,27 +1257,27 @@ alloc(uint32_t size, uint16_t mode) @@ -1254,27 +1257,27 @@ alloc(uint32_t size, uint16_t mode)
1254 uint32_t loc, bno; 1257 uint32_t loc, bno;
1255 uint8_t *bbp; 1258 uint8_t *bbp;
1256 uint len, map, i; 1259 uint len, map, i;
1257 1260
1258 if (gd[0].ext2bgd_nbfree == 0) 1261 if (gd[0].ext2bgd_nbfree == 0)
1259 return 0; 1262 return 0;
1260 1263
1261 if (size > sblock.e2fs_bsize) 1264 if (size > sblock.e2fs_bsize)
1262 return 0; 1265 return 0;
1263 1266
1264 bbp = malloc(sblock.e2fs_bsize); 1267 bbp = malloc(sblock.e2fs_bsize);
1265 if (bbp == NULL) 1268 if (bbp == NULL)
1266 return 0; 1269 return 0;
1267 rdfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_b_bitmap), 1270 rdfs(EXT2_FSBTODB(&sblock, fs2h32(gd[0].ext2bgd_b_bitmap)),
1268 sblock.e2fs_bsize, bbp); 1271 sblock.e2fs_bsize, bbp);
1269 1272
1270 /* XXX: kernel uses e2fs_fpg here */ 1273 /* XXX: kernel uses e2fs_fpg here */
1271 len = sblock.e2fs.e2fs_bpg / NBBY; 1274 len = sblock.e2fs.e2fs_bpg / NBBY;
1272 1275
1273#if 0 /* no need block allocation for root or lost+found dir */ 1276#if 0 /* no need block allocation for root or lost+found dir */
1274 for (loc = 0; loc < len; loc++) { 1277 for (loc = 0; loc < len; loc++) {
1275 if (bbp[loc] == 0) { 1278 if (bbp[loc] == 0) {
1276 bno = loc * NBBY; 1279 bno = loc * NBBY;
1277 goto gotit; 1280 goto gotit;
1278 } 1281 }
1279 } 1282 }
1280#endif 1283#endif
@@ -1289,33 +1292,33 @@ alloc(uint32_t size, uint16_t mode) @@ -1289,33 +1292,33 @@ alloc(uint32_t size, uint16_t mode)
1289 bno = loc * NBBY; 1292 bno = loc * NBBY;
1290 for (i = 0; i < NBBY; i++, bno++) { 1293 for (i = 0; i < NBBY; i++, bno++) {
1291 if ((map & (1 << i)) == 0) 1294 if ((map & (1 << i)) == 0)
1292 goto gotit; 1295 goto gotit;
1293 } 1296 }
1294 free(bbp); 1297 free(bbp);
1295 return 0; 1298 return 0;
1296  1299
1297 gotit: 1300 gotit:
1298 if (isset(bbp, bno)) 1301 if (isset(bbp, bno))
1299 errx(EXIT_FAILURE, "%s: inconsistent bitmap", __func__); 1302 errx(EXIT_FAILURE, "%s: inconsistent bitmap", __func__);
1300 1303
1301 setbit(bbp, bno); 1304 setbit(bbp, bno);
1302 wtfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_b_bitmap), 1305 wtfs(EXT2_FSBTODB(&sblock, fs2h32(gd[0].ext2bgd_b_bitmap)),
1303 sblock.e2fs_bsize, bbp); 1306 sblock.e2fs_bsize, bbp);
1304 free(bbp); 1307 free(bbp);
1305 /* XXX: modified group descriptors won't be written into backups */ 1308 /* XXX: modified group descriptors won't be written into backups */
1306 gd[0].ext2bgd_nbfree--; 1309 gd[0].ext2bgd_nbfree = h2fs16(fs2h16(gd[0].ext2bgd_nbfree)-1);
1307 if ((mode & EXT2_IFDIR) != 0) 1310 if ((mode & EXT2_IFDIR) != 0)
1308 gd[0].ext2bgd_ndirs++; 1311 gd[0].ext2bgd_ndirs = h2fs16(fs2h16(gd[0].ext2bgd_ndirs)+1);
1309 sblock.e2fs.e2fs_fbcount--; 1312 sblock.e2fs.e2fs_fbcount--;
1310 1313
1311 return sblock.e2fs.e2fs_first_dblock + bno; 1314 return sblock.e2fs.e2fs_first_dblock + bno;
1312} 1315}
1313 1316
1314/* 1317/*
1315 * void iput(struct ext2fs_dinode *ip, ino_t ino) 1318 * void iput(struct ext2fs_dinode *ip, ino_t ino)
1316 * 1319 *
1317 * Put an inode entry into the corresponding table. 1320 * Put an inode entry into the corresponding table.
1318 */ 1321 */
1319static void 1322static void
1320iput(struct ext2fs_dinode *ip, ino_t ino) 1323iput(struct ext2fs_dinode *ip, ino_t ino)
1321{ 1324{
@@ -1333,37 +1336,37 @@ iput(struct ext2fs_dinode *ip, ino_t ino @@ -1333,37 +1336,37 @@ iput(struct ext2fs_dinode *ip, ino_t ino
1333 * Reserved inodes are allocated and accounted in initcg() 1336 * Reserved inodes are allocated and accounted in initcg()
1334 * so skip checks of the bitmap and allocation for them. 1337 * so skip checks of the bitmap and allocation for them.
1335 */ 1338 */
1336 if (ino >= EXT2_FIRSTINO) { 1339 if (ino >= EXT2_FIRSTINO) {
1337 c = ino_to_cg(&sblock, ino); 1340 c = ino_to_cg(&sblock, ino);
1338 1341
1339 /* sanity check */ 1342 /* sanity check */
1340 if (gd[c].ext2bgd_nifree == 0) 1343 if (gd[c].ext2bgd_nifree == 0)
1341 errx(EXIT_FAILURE, 1344 errx(EXIT_FAILURE,
1342 "%s: no free inode %" PRIu64 " in block group %u", 1345 "%s: no free inode %" PRIu64 " in block group %u",
1343 __func__, (uint64_t)ino, c); 1346 __func__, (uint64_t)ino, c);
1344 1347
1345 /* update inode bitmap */ 1348 /* update inode bitmap */
1346 rdfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_i_bitmap), 1349 rdfs(EXT2_FSBTODB(&sblock, fs2h32(gd[0].ext2bgd_i_bitmap)),
1347 sblock.e2fs_bsize, bp); 1350 sblock.e2fs_bsize, bp);
1348 1351
1349 /* more sanity */ 1352 /* more sanity */
1350 if (isset(bp, EXT2_INO_INDEX(ino))) 1353 if (isset(bp, EXT2_INO_INDEX(ino)))
1351 errx(EXIT_FAILURE, "%s: inode %" PRIu64 1354 errx(EXIT_FAILURE, "%s: inode %" PRIu64
1352 " already in use", __func__, (uint64_t)ino); 1355 " already in use", __func__, (uint64_t)ino);
1353 setbit(bp, EXT2_INO_INDEX(ino)); 1356 setbit(bp, EXT2_INO_INDEX(ino));
1354 wtfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_i_bitmap), 1357 wtfs(EXT2_FSBTODB(&sblock, fs2h32(gd[0].ext2bgd_i_bitmap)),
1355 sblock.e2fs_bsize, bp); 1358 sblock.e2fs_bsize, bp);
1356 gd[c].ext2bgd_nifree--; 1359 gd[c].ext2bgd_nifree = h2fs16(fs2h16(gd[c].ext2bgd_nifree)-1);
1357 sblock.e2fs.e2fs_ficount--; 1360 sblock.e2fs.e2fs_ficount--;
1358 } 1361 }
1359 1362
1360 if (ino >= sblock.e2fs.e2fs_ipg * sblock.e2fs_ncg) 1363 if (ino >= sblock.e2fs.e2fs_ipg * sblock.e2fs_ncg)
1361 errx(EXIT_FAILURE, "%s: inode value out of range (%" PRIu64 1364 errx(EXIT_FAILURE, "%s: inode value out of range (%" PRIu64
1362 ")", __func__, (uint64_t)ino); 1365 ")", __func__, (uint64_t)ino);
1363 1366
1364 /* update an inode entry in the table */ 1367 /* update an inode entry in the table */
1365 d = EXT2_FSBTODB(&sblock, ino_to_fsba(&sblock, ino)); 1368 d = EXT2_FSBTODB(&sblock, ino_to_fsba(&sblock, ino));
1366 rdfs(d, sblock.e2fs_bsize, bp); 1369 rdfs(d, sblock.e2fs_bsize, bp);
1367 1370
1368 dp = (struct ext2fs_dinode *)(bp + 1371 dp = (struct ext2fs_dinode *)(bp +
1369 inodesize * ino_to_fsbo(&sblock, ino)); 1372 inodesize * ino_to_fsbo(&sblock, ino));