| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: resize_ffs.c,v 1.31 2011/08/15 02:22:46 dholland Exp $ */ | | 1 | /* $NetBSD: resize_ffs.c,v 1.32 2011/08/27 16:34:57 christos Exp $ */ |
2 | /* From sources sent on February 17, 2003 */ | | 2 | /* From sources sent on February 17, 2003 */ |
3 | /*- | | 3 | /*- |
4 | * As its sole author, I explicitly place this code in the public | | 4 | * As its sole author, I explicitly place this code in the public |
5 | * domain. Anyone may use it for any purpose (though I would | | 5 | * domain. Anyone may use it for any purpose (though I would |
6 | * appreciate credit where it is due). | | 6 | * appreciate credit where it is due). |
7 | * | | 7 | * |
8 | * der Mouse | | 8 | * der Mouse |
9 | * | | 9 | * |
10 | * mouse@rodents.montreal.qc.ca | | 10 | * mouse@rodents.montreal.qc.ca |
11 | * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B | | 11 | * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B |
12 | */ | | 12 | */ |
13 | /* | | 13 | /* |
14 | * resize_ffs: | | 14 | * resize_ffs: |
| @@ -26,27 +26,27 @@ | | | @@ -26,27 +26,27 @@ |
26 | * depending on gcc-specific features, notably nested function | | 26 | * depending on gcc-specific features, notably nested function |
27 | * definitions (which in at least a few cases depend on the lexical | | 27 | * definitions (which in at least a few cases depend on the lexical |
28 | * scoping gcc provides, so they can't be trivially moved outside). | | 28 | * scoping gcc provides, so they can't be trivially moved outside). |
29 | * | | 29 | * |
30 | * Many thanks go to John Kohl <jtk@NetBSD.org> for finding bugs: the | | 30 | * Many thanks go to John Kohl <jtk@NetBSD.org> for finding bugs: the |
31 | * one responsible for the "realloccgblk: can't find blk in cyl" | | 31 | * one responsible for the "realloccgblk: can't find blk in cyl" |
32 | * problem and a more minor one which left fs_dsize wrong when | | 32 | * problem and a more minor one which left fs_dsize wrong when |
33 | * shrinking. (These actually indicate bugs in fsck too - it should | | 33 | * shrinking. (These actually indicate bugs in fsck too - it should |
34 | * have caught and fixed them.) | | 34 | * have caught and fixed them.) |
35 | * | | 35 | * |
36 | */ | | 36 | */ |
37 | | | 37 | |
38 | #include <sys/cdefs.h> | | 38 | #include <sys/cdefs.h> |
39 | __RCSID("$NetBSD: resize_ffs.c,v 1.31 2011/08/15 02:22:46 dholland Exp $"); | | 39 | __RCSID("$NetBSD: resize_ffs.c,v 1.32 2011/08/27 16:34:57 christos Exp $"); |
40 | | | 40 | |
41 | #include <sys/disk.h> | | 41 | #include <sys/disk.h> |
42 | #include <sys/disklabel.h> | | 42 | #include <sys/disklabel.h> |
43 | #include <sys/dkio.h> | | 43 | #include <sys/dkio.h> |
44 | #include <sys/ioctl.h> | | 44 | #include <sys/ioctl.h> |
45 | #include <sys/stat.h> | | 45 | #include <sys/stat.h> |
46 | #include <sys/mman.h> | | 46 | #include <sys/mman.h> |
47 | #include <sys/param.h> /* MAXFRAG */ | | 47 | #include <sys/param.h> /* MAXFRAG */ |
48 | #include <ufs/ffs/fs.h> | | 48 | #include <ufs/ffs/fs.h> |
49 | #include <ufs/ffs/ffs_extern.h> | | 49 | #include <ufs/ffs/ffs_extern.h> |
50 | #include <ufs/ufs/dir.h> | | 50 | #include <ufs/ufs/dir.h> |
51 | #include <ufs/ufs/dinode.h> | | 51 | #include <ufs/ufs/dinode.h> |
52 | #include <ufs/ufs/ufs_bswap.h> /* ufs_rw32 */ | | 52 | #include <ufs/ufs/ufs_bswap.h> /* ufs_rw32 */ |
| @@ -312,27 +312,27 @@ alloconce(size_t nb, const char *tag) | | | @@ -312,27 +312,27 @@ alloconce(size_t nb, const char *tag) |
312 | (unsigned long int) nb, tag); | | 312 | (unsigned long int) nb, tag); |
313 | } | | 313 | } |
314 | /* | | 314 | /* |
315 | * Load the cgs and csums off disk. Also allocates the space to load | | 315 | * Load the cgs and csums off disk. Also allocates the space to load |
316 | * them into and initializes the per-cg flags. | | 316 | * them into and initializes the per-cg flags. |
317 | */ | | 317 | */ |
318 | static void | | 318 | static void |
319 | loadcgs(void) | | 319 | loadcgs(void) |
320 | { | | 320 | { |
321 | int cg; | | 321 | int cg; |
322 | char *cgp; | | 322 | char *cgp; |
323 | | | 323 | |
324 | cgblksz = roundup(oldsb->fs_cgsize, oldsb->fs_fsize); | | 324 | cgblksz = roundup(oldsb->fs_cgsize, oldsb->fs_fsize); |
325 | cgs = nfmalloc(oldsb->fs_ncg * sizeof(struct cg *), "cg pointers"); | | 325 | cgs = nfmalloc(oldsb->fs_ncg * sizeof(*cgs), "cg pointers"); |
326 | cgp = alloconce(oldsb->fs_ncg * cgblksz, "cgs"); | | 326 | cgp = alloconce(oldsb->fs_ncg * cgblksz, "cgs"); |
327 | cgflags = nfmalloc(oldsb->fs_ncg, "cg flags"); | | 327 | cgflags = nfmalloc(oldsb->fs_ncg, "cg flags"); |
328 | csums = nfmalloc(oldsb->fs_cssize, "cg summary"); | | 328 | csums = nfmalloc(oldsb->fs_cssize, "cg summary"); |
329 | for (cg = 0; cg < oldsb->fs_ncg; cg++) { | | 329 | for (cg = 0; cg < oldsb->fs_ncg; cg++) { |
330 | cgs[cg] = (struct cg *) cgp; | | 330 | cgs[cg] = (struct cg *) cgp; |
331 | readat(fsbtodb(oldsb, cgtod(oldsb, cg)), cgp, cgblksz); | | 331 | readat(fsbtodb(oldsb, cgtod(oldsb, cg)), cgp, cgblksz); |
332 | if (needswap) | | 332 | if (needswap) |
333 | ffs_cg_swap(cgs[cg],cgs[cg],oldsb); | | 333 | ffs_cg_swap(cgs[cg],cgs[cg],oldsb); |
334 | cgflags[cg] = 0; | | 334 | cgflags[cg] = 0; |
335 | cgp += cgblksz; | | 335 | cgp += cgblksz; |
336 | } | | 336 | } |
337 | readat(fsbtodb(oldsb, oldsb->fs_csaddr), csums, oldsb->fs_cssize); | | 337 | readat(fsbtodb(oldsb, oldsb->fs_csaddr), csums, oldsb->fs_cssize); |
338 | if (needswap) | | 338 | if (needswap) |
| @@ -601,27 +601,27 @@ initcg(int cgn) | | | @@ -601,27 +601,27 @@ initcg(int cgn) |
601 | if (i) { | | 601 | if (i) { |
602 | cg->cg_frsum[i]++; | | 602 | cg->cg_frsum[i]++; |
603 | cg->cg_cs.cs_nffree += i; | | 603 | cg->cg_cs.cs_nffree += i; |
604 | } | | 604 | } |
605 | } | | 605 | } |
606 | /* Update the csum info. */ | | 606 | /* Update the csum info. */ |
607 | csums[cgn] = cg->cg_cs; | | 607 | csums[cgn] = cg->cg_cs; |
608 | newsb->fs_cstotal.cs_nffree += cg->cg_cs.cs_nffree; | | 608 | newsb->fs_cstotal.cs_nffree += cg->cg_cs.cs_nffree; |
609 | newsb->fs_cstotal.cs_nbfree += cg->cg_cs.cs_nbfree; | | 609 | newsb->fs_cstotal.cs_nbfree += cg->cg_cs.cs_nbfree; |
610 | newsb->fs_cstotal.cs_nifree += cg->cg_cs.cs_nifree; | | 610 | newsb->fs_cstotal.cs_nifree += cg->cg_cs.cs_nifree; |
611 | if (is_ufs2 == 0) | | 611 | if (is_ufs2 == 0) |
612 | /* Write out the cleared inodes. */ | | 612 | /* Write out the cleared inodes. */ |
613 | writeat(fsbtodb(newsb, cgimin(newsb, cgn)), zinodes, | | 613 | writeat(fsbtodb(newsb, cgimin(newsb, cgn)), zinodes, |
614 | newsb->fs_ipg * sizeof(struct ufs1_dinode)); | | 614 | newsb->fs_ipg * sizeof(*zinodes)); |
615 | /* Dirty the cg. */ | | 615 | /* Dirty the cg. */ |
616 | cgflags[cgn] |= CGF_DIRTY; | | 616 | cgflags[cgn] |= CGF_DIRTY; |
617 | } | | 617 | } |
618 | /* | | 618 | /* |
619 | * Find free space, at least nfrags consecutive frags of it. Pays no | | 619 | * Find free space, at least nfrags consecutive frags of it. Pays no |
620 | * attention to block boundaries, but refuses to straddle cg | | 620 | * attention to block boundaries, but refuses to straddle cg |
621 | * boundaries, even if the disk blocks involved are in fact | | 621 | * boundaries, even if the disk blocks involved are in fact |
622 | * consecutive. Return value is the frag number of the first frag of | | 622 | * consecutive. Return value is the frag number of the first frag of |
623 | * the block, or -1 if no space was found. Uses newsb for sb values, | | 623 | * the block, or -1 if no space was found. Uses newsb for sb values, |
624 | * and assumes the cgs[] structures correctly describe the area to be | | 624 | * and assumes the cgs[] structures correctly describe the area to be |
625 | * searched. | | 625 | * searched. |
626 | * | | 626 | * |
627 | * XXX is there a bug lurking in the ignoring of block boundaries by | | 627 | * XXX is there a bug lurking in the ignoring of block boundaries by |
| @@ -852,30 +852,28 @@ csum_fixup(void) | | | @@ -852,30 +852,28 @@ csum_fixup(void) |
852 | * 'em and we're all done. */ | | 852 | * 'em and we're all done. */ |
853 | for ((i = newsb->fs_csaddr + ntot - nnew), | | 853 | for ((i = newsb->fs_csaddr + ntot - nnew), |
854 | (j = nnew); j > 0; i++, j--) { | | 854 | (j = nnew); j > 0; i++, j--) { |
855 | alloc_frag(i); | | 855 | alloc_frag(i); |
856 | } | | 856 | } |
857 | return; | | 857 | return; |
858 | } | | 858 | } |
859 | } | | 859 | } |
860 | /* We have to move the csum info, sigh. Look for new space, free old | | 860 | /* We have to move the csum info, sigh. Look for new space, free old |
861 | * space, and allocate new. Update fs_csaddr. We don't copy anything | | 861 | * space, and allocate new. Update fs_csaddr. We don't copy anything |
862 | * on disk at this point; the csum info will be written to the | | 862 | * on disk at this point; the csum info will be written to the |
863 | * then-current fs_csaddr as part of the final flush. */ | | 863 | * then-current fs_csaddr as part of the final flush. */ |
864 | newloc = find_freespace(ntot); | | 864 | newloc = find_freespace(ntot); |
865 | if (newloc < 0) { | | 865 | if (newloc < 0) |
866 | printf("Sorry, no space available for new csums\n"); | | 866 | errx(EXIT_FAILURE, "Sorry, no space available for new csums"); |
867 | exit(EXIT_FAILURE); | | | |
868 | } | | | |
869 | for (i = 0, f = newsb->fs_csaddr, t = newloc; i < ntot; i++, f++, t++) { | | 867 | for (i = 0, f = newsb->fs_csaddr, t = newloc; i < ntot; i++, f++, t++) { |
870 | if (i < nold) { | | 868 | if (i < nold) { |
871 | free_frag(f); | | 869 | free_frag(f); |
872 | } | | 870 | } |
873 | alloc_frag(t); | | 871 | alloc_frag(t); |
874 | } | | 872 | } |
875 | newsb->fs_csaddr = newloc; | | 873 | newsb->fs_csaddr = newloc; |
876 | } | | 874 | } |
877 | /* | | 875 | /* |
878 | * Recompute newsb->fs_dsize. Just scans all cgs, adding the number of | | 876 | * Recompute newsb->fs_dsize. Just scans all cgs, adding the number of |
879 | * data blocks in that cg to the total. | | 877 | * data blocks in that cg to the total. |
880 | */ | | 878 | */ |
881 | static void | | 879 | static void |
| @@ -916,36 +914,35 @@ timestamp(void) | | | @@ -916,36 +914,35 @@ timestamp(void) |
916 | return (t); | | 914 | return (t); |
917 | } | | 915 | } |
918 | /* | | 916 | /* |
919 | * Grow the file system. | | 917 | * Grow the file system. |
920 | */ | | 918 | */ |
921 | static void | | 919 | static void |
922 | grow(void) | | 920 | grow(void) |
923 | { | | 921 | { |
924 | int i; | | 922 | int i; |
925 | | | 923 | |
926 | /* Update the timestamp. */ | | 924 | /* Update the timestamp. */ |
927 | newsb->fs_time = timestamp(); | | 925 | newsb->fs_time = timestamp(); |
928 | /* Allocate and clear the new-inode area, in case we add any cgs. */ | | 926 | /* Allocate and clear the new-inode area, in case we add any cgs. */ |
929 | zinodes = alloconce(newsb->fs_ipg * sizeof(struct ufs1_dinode), | | 927 | zinodes = alloconce(newsb->fs_ipg * sizeof(*zinodes), "zeroed inodes"); |
930 | "zeroed inodes"); | | 928 | memset(zinodes, 0, newsb->fs_ipg * sizeof(*zinodes)); |
931 | memset(zinodes, 0, newsb->fs_ipg * sizeof(struct ufs1_dinode)); | | | |
932 | /* Update the size. */ | | 929 | /* Update the size. */ |
933 | newsb->fs_size = dbtofsb(newsb, newsize); | | 930 | newsb->fs_size = dbtofsb(newsb, newsize); |
934 | /* Did we actually not grow? (This can happen if newsize is less than | | 931 | /* Did we actually not grow? (This can happen if newsize is less than |
935 | * a frag larger than the old size - unlikely, but no excuse to | | 932 | * a frag larger than the old size - unlikely, but no excuse to |
936 | * misbehave if it happens.) */ | | 933 | * misbehave if it happens.) */ |
937 | if (newsb->fs_size == oldsb->fs_size) { | | 934 | if (newsb->fs_size == oldsb->fs_size) { |
938 | printf("New fs size %"PRIu64" = odl fs size %"PRIu64 | | 935 | printf("New fs size %"PRIu64" = old fs size %"PRIu64 |
939 | ", not growing.\n", newsb->fs_size, oldsb->fs_size); | | 936 | ", not growing.\n", newsb->fs_size, oldsb->fs_size); |
940 | return; | | 937 | return; |
941 | } | | 938 | } |
942 | /* Check that the new last sector (frag, actually) is writable. Since | | 939 | /* Check that the new last sector (frag, actually) is writable. Since |
943 | * it's at least one frag larger than it used to be, we know we aren't | | 940 | * it's at least one frag larger than it used to be, we know we aren't |
944 | * overwriting anything important by this. (The choice of sbbuf as | | 941 | * overwriting anything important by this. (The choice of sbbuf as |
945 | * what to write is irrelevant; it's just something handy that's known | | 942 | * what to write is irrelevant; it's just something handy that's known |
946 | * to be at least one frag in size.) */ | | 943 | * to be at least one frag in size.) */ |
947 | writeat(fsbtodb(newsb,newsb->fs_size - 1), &sbbuf, newsb->fs_fsize); | | 944 | writeat(fsbtodb(newsb,newsb->fs_size - 1), &sbbuf, newsb->fs_fsize); |
948 | if (is_ufs2) | | 945 | if (is_ufs2) |
949 | newsb->fs_ncg = howmany(newsb->fs_size, newsb->fs_fpg); | | 946 | newsb->fs_ncg = howmany(newsb->fs_size, newsb->fs_fpg); |
950 | else { | | 947 | else { |
951 | /* Update fs_old_ncyl and fs_ncg. */ | | 948 | /* Update fs_old_ncyl and fs_ncg. */ |
| @@ -967,27 +964,27 @@ grow(void) | | | @@ -967,27 +964,27 @@ grow(void) |
967 | printf("Warning: last cylinder group is too small;\n"); | | 964 | printf("Warning: last cylinder group is too small;\n"); |
968 | printf(" dropping it. New size = %lu.\n", | | 965 | printf(" dropping it. New size = %lu.\n", |
969 | (unsigned long int) fsbtodb(newsb, newsb->fs_size)); | | 966 | (unsigned long int) fsbtodb(newsb, newsb->fs_size)); |
970 | } | | 967 | } |
971 | /* Find out how big the csum area is, and realloc csums if bigger. */ | | 968 | /* Find out how big the csum area is, and realloc csums if bigger. */ |
972 | newsb->fs_cssize = fragroundup(newsb, | | 969 | newsb->fs_cssize = fragroundup(newsb, |
973 | newsb->fs_ncg * sizeof(struct csum)); | | 970 | newsb->fs_ncg * sizeof(struct csum)); |
974 | if (newsb->fs_cssize > oldsb->fs_cssize) | | 971 | if (newsb->fs_cssize > oldsb->fs_cssize) |
975 | csums = nfrealloc(csums, newsb->fs_cssize, "new cg summary"); | | 972 | csums = nfrealloc(csums, newsb->fs_cssize, "new cg summary"); |
976 | /* If we're adding any cgs, realloc structures and set up the new | | 973 | /* If we're adding any cgs, realloc structures and set up the new |
977 | cgs. */ | | 974 | cgs. */ |
978 | if (newsb->fs_ncg > oldsb->fs_ncg) { | | 975 | if (newsb->fs_ncg > oldsb->fs_ncg) { |
979 | char *cgp; | | 976 | char *cgp; |
980 | cgs = nfrealloc(cgs, newsb->fs_ncg * sizeof(struct cg *), | | 977 | cgs = nfrealloc(cgs, newsb->fs_ncg * sizeof(*cgs), |
981 | "cg pointers"); | | 978 | "cg pointers"); |
982 | cgflags = nfrealloc(cgflags, newsb->fs_ncg, "cg flags"); | | 979 | cgflags = nfrealloc(cgflags, newsb->fs_ncg, "cg flags"); |
983 | memset(cgflags + oldsb->fs_ncg, 0, | | 980 | memset(cgflags + oldsb->fs_ncg, 0, |
984 | newsb->fs_ncg - oldsb->fs_ncg); | | 981 | newsb->fs_ncg - oldsb->fs_ncg); |
985 | cgp = alloconce((newsb->fs_ncg - oldsb->fs_ncg) * cgblksz, | | 982 | cgp = alloconce((newsb->fs_ncg - oldsb->fs_ncg) * cgblksz, |
986 | "cgs"); | | 983 | "cgs"); |
987 | for (i = oldsb->fs_ncg; i < newsb->fs_ncg; i++) { | | 984 | for (i = oldsb->fs_ncg; i < newsb->fs_ncg; i++) { |
988 | cgs[i] = (struct cg *) cgp; | | 985 | cgs[i] = (struct cg *) cgp; |
989 | initcg(i); | | 986 | initcg(i); |
990 | cgp += cgblksz; | | 987 | cgp += cgblksz; |
991 | } | | 988 | } |
992 | cgs[oldsb->fs_ncg - 1]->cg_old_ncyl = oldsb->fs_old_cpg; | | 989 | cgs[oldsb->fs_ncg - 1]->cg_old_ncyl = oldsb->fs_old_cpg; |
993 | cgflags[oldsb->fs_ncg - 1] |= CGF_DIRTY; | | 990 | cgflags[oldsb->fs_ncg - 1] |= CGF_DIRTY; |
| @@ -1218,52 +1215,51 @@ loadinodes(void) | | | @@ -1218,52 +1215,51 @@ loadinodes(void) |
1218 | for (ino = 0,imax = oldsb->fs_ipg * oldsb->fs_ncg; ino < imax; ) { | | 1215 | for (ino = 0,imax = oldsb->fs_ipg * oldsb->fs_ncg; ino < imax; ) { |
1219 | readat(fsbtodb(oldsb, ino_to_fsba(oldsb, ino)), ibuf, | | 1216 | readat(fsbtodb(oldsb, ino_to_fsba(oldsb, ino)), ibuf, |
1220 | oldsb->fs_bsize); | | 1217 | oldsb->fs_bsize); |
1221 | | | 1218 | |
1222 | for (i = 0; i < oldsb->fs_inopb; i++) { | | 1219 | for (i = 0; i < oldsb->fs_inopb; i++) { |
1223 | if (is_ufs2) { | | 1220 | if (is_ufs2) { |
1224 | if (needswap) { | | 1221 | if (needswap) { |
1225 | ffs_dinode2_swap(&(dp2[i]), &(dp2[i])); | | 1222 | ffs_dinode2_swap(&(dp2[i]), &(dp2[i])); |
1226 | for (j = 0; j < NDADDR + NIADDR; j++) | | 1223 | for (j = 0; j < NDADDR + NIADDR; j++) |
1227 | dp2[i].di_db[j] = | | 1224 | dp2[i].di_db[j] = |
1228 | bswap32(dp2[i].di_db[j]); | | 1225 | bswap32(dp2[i].di_db[j]); |
1229 | } | | 1226 | } |
1230 | memcpy(&inodes[ino].dp2, &dp2[i], | | 1227 | memcpy(&inodes[ino].dp2, &dp2[i], |
1231 | sizeof(struct ufs2_dinode)); | | 1228 | sizeof(inodes[ino].dp2)); |
1232 | } else { | | 1229 | } else { |
1233 | if (needswap) { | | 1230 | if (needswap) { |
1234 | ffs_dinode1_swap(&(dp1[i]), &(dp1[i])); | | 1231 | ffs_dinode1_swap(&(dp1[i]), &(dp1[i])); |
1235 | for (j = 0; j < NDADDR + NIADDR; j++) | | 1232 | for (j = 0; j < NDADDR + NIADDR; j++) |
1236 | dp1[i].di_db[j] = | | 1233 | dp1[i].di_db[j] = |
1237 | bswap32(dp1[i].di_db[j]); | | 1234 | bswap32(dp1[i].di_db[j]); |
1238 | } | | 1235 | } |
1239 | memcpy(&inodes[ino].dp1, &dp1[i], | | 1236 | memcpy(&inodes[ino].dp1, &dp1[i], |
1240 | sizeof(struct ufs1_dinode)); | | 1237 | sizeof(inodes[ino].dp1)); |
1241 | } | | 1238 | } |
1242 | if (++ino > imax) | | 1239 | if (++ino > imax) |
1243 | errx(EXIT_FAILURE, | | 1240 | errx(EXIT_FAILURE, |
1244 | "Exceeded number of inodes"); | | 1241 | "Exceeded number of inodes"); |
1245 | } | | 1242 | } |
1246 | | | 1243 | |
1247 | } | | 1244 | } |
1248 | } | | 1245 | } |
1249 | /* | | 1246 | /* |
1250 | * Report a file-system-too-full problem. | | 1247 | * Report a file-system-too-full problem. |
1251 | */ | | 1248 | */ |
1252 | static void | | 1249 | __dead static void |
1253 | toofull(void) | | 1250 | toofull(void) |
1254 | { | | 1251 | { |
1255 | printf("Sorry, would run out of data blocks\n"); | | 1252 | errx(EXIT_FAILURE, "Sorry, would run out of data blocks"); |
1256 | exit(EXIT_FAILURE); | | | |
1257 | } | | 1253 | } |
1258 | /* | | 1254 | /* |
1259 | * Record a desire to move "n" frags from "from" to "to". | | 1255 | * Record a desire to move "n" frags from "from" to "to". |
1260 | */ | | 1256 | */ |
1261 | static void | | 1257 | static void |
1262 | mark_move(unsigned int from, unsigned int to, unsigned int n) | | 1258 | mark_move(unsigned int from, unsigned int to, unsigned int n) |
1263 | { | | 1259 | { |
1264 | for (; n > 0; n--) | | 1260 | for (; n > 0; n--) |
1265 | blkmove[from++] = to++; | | 1261 | blkmove[from++] = to++; |
1266 | } | | 1262 | } |
1267 | /* Helper function - evict n frags, starting with start (cg-relative). | | 1263 | /* Helper function - evict n frags, starting with start (cg-relative). |
1268 | * The free bitmap is scanned, unallocated frags are ignored, and | | 1264 | * The free bitmap is scanned, unallocated frags are ignored, and |
1269 | * each block of consecutive allocated frags is moved as a unit. | | 1265 | * each block of consecutive allocated frags is moved as a unit. |
| @@ -1574,31 +1570,29 @@ flush_inodes(void) | | | @@ -1574,31 +1570,29 @@ flush_inodes(void) |
1574 | * for the considerations in question. | | 1570 | * for the considerations in question. |
1575 | */ | | 1571 | */ |
1576 | static void | | 1572 | static void |
1577 | evict_inodes(struct cg * cg) | | 1573 | evict_inodes(struct cg * cg) |
1578 | { | | 1574 | { |
1579 | int inum; | | 1575 | int inum; |
1580 | int i; | | 1576 | int i; |
1581 | int fi; | | 1577 | int fi; |
1582 | | | 1578 | |
1583 | inum = newsb->fs_ipg * cg->cg_cgx; | | 1579 | inum = newsb->fs_ipg * cg->cg_cgx; |
1584 | for (i = 0; i < newsb->fs_ipg; i++, inum++) { | | 1580 | for (i = 0; i < newsb->fs_ipg; i++, inum++) { |
1585 | if (DIP(inodes + inum,di_mode) != 0) { | | 1581 | if (DIP(inodes + inum,di_mode) != 0) { |
1586 | fi = find_freeinode(); | | 1582 | fi = find_freeinode(); |
1587 | if (fi < 0) { | | 1583 | if (fi < 0) |
1588 | printf("Sorry, inodes evaporated - " | | 1584 | errx(EXIT_FAILURE, "Sorry, inodes evaporated - " |
1589 | "file system probably needs fsck\n"); | | 1585 | "file system probably needs fsck"); |
1590 | exit(EXIT_FAILURE); | | | |
1591 | } | | | |
1592 | inomove[inum] = fi; | | 1586 | inomove[inum] = fi; |
1593 | clr_bits(cg_inosused(cg, 0), i, 1); | | 1587 | clr_bits(cg_inosused(cg, 0), i, 1); |
1594 | set_bits(cg_inosused(cgs[ino_to_cg(newsb, fi)], 0), | | 1588 | set_bits(cg_inosused(cgs[ino_to_cg(newsb, fi)], 0), |
1595 | fi % newsb->fs_ipg, 1); | | 1589 | fi % newsb->fs_ipg, 1); |
1596 | } | | 1590 | } |
1597 | } | | 1591 | } |
1598 | } | | 1592 | } |
1599 | /* | | 1593 | /* |
1600 | * Move inodes from old locations to new. Does not actually write | | 1594 | * Move inodes from old locations to new. Does not actually write |
1601 | * anything to disk; just copies in-core and sets dirty bits. | | 1595 | * anything to disk; just copies in-core and sets dirty bits. |
1602 | * | | 1596 | * |
1603 | * We have to be careful here for reasons similar to those mentioned in | | 1597 | * We have to be careful here for reasons similar to those mentioned in |
1604 | * the comment header on perform_data_move, above: for the sake of | | 1598 | * the comment header on perform_data_move, above: for the sake of |
| @@ -1710,31 +1704,29 @@ shrink(void) | | | @@ -1710,31 +1704,29 @@ shrink(void) |
1710 | newsb->fs_ncg--; | | 1704 | newsb->fs_ncg--; |
1711 | if (is_ufs2 == 0) { | | 1705 | if (is_ufs2 == 0) { |
1712 | newsb->fs_old_ncyl = newsb->fs_ncg * newsb->fs_old_cpg; | | 1706 | newsb->fs_old_ncyl = newsb->fs_ncg * newsb->fs_old_cpg; |
1713 | newsb->fs_size = (newsb->fs_old_ncyl * | | 1707 | newsb->fs_size = (newsb->fs_old_ncyl * |
1714 | newsb->fs_old_spc) / NSPF(newsb); | | 1708 | newsb->fs_old_spc) / NSPF(newsb); |
1715 | } else | | 1709 | } else |
1716 | newsb->fs_size = newsb->fs_ncg * newsb->fs_fpg; | | 1710 | newsb->fs_size = newsb->fs_ncg * newsb->fs_fpg; |
1717 | | | 1711 | |
1718 | printf("Warning: last cylinder group is too small;\n"); | | 1712 | printf("Warning: last cylinder group is too small;\n"); |
1719 | printf(" dropping it. New size = %lu.\n", | | 1713 | printf(" dropping it. New size = %lu.\n", |
1720 | (unsigned long int) fsbtodb(newsb, newsb->fs_size)); | | 1714 | (unsigned long int) fsbtodb(newsb, newsb->fs_size)); |
1721 | } | | 1715 | } |
1722 | /* Let's make sure we're not being shrunk into oblivion. */ | | 1716 | /* Let's make sure we're not being shrunk into oblivion. */ |
1723 | if (newsb->fs_ncg < 1) { | | 1717 | if (newsb->fs_ncg < 1) |
1724 | printf("Size too small - file system would " | | 1718 | errx(EXIT_FAILURE, "Size too small - file system would " |
1725 | "have no cylinders\n"); | | 1719 | "have no cylinders"); |
1726 | exit(EXIT_FAILURE); | | | |
1727 | } | | | |
1728 | /* Initialize for block motion. */ | | 1720 | /* Initialize for block motion. */ |
1729 | blkmove_init(); | | 1721 | blkmove_init(); |
1730 | /* Update csum size, then fix up for the new size */ | | 1722 | /* Update csum size, then fix up for the new size */ |
1731 | newsb->fs_cssize = fragroundup(newsb, | | 1723 | newsb->fs_cssize = fragroundup(newsb, |
1732 | newsb->fs_ncg * sizeof(struct csum)); | | 1724 | newsb->fs_ncg * sizeof(struct csum)); |
1733 | csum_fixup(); | | 1725 | csum_fixup(); |
1734 | /* Evict data from any cgs being wholly eliminated */ | | 1726 | /* Evict data from any cgs being wholly eliminated */ |
1735 | for (i = newsb->fs_ncg; i < oldsb->fs_ncg; i++) { | | 1727 | for (i = newsb->fs_ncg; i < oldsb->fs_ncg; i++) { |
1736 | int base; | | 1728 | int base; |
1737 | int dlow; | | 1729 | int dlow; |
1738 | int dhigh; | | 1730 | int dhigh; |
1739 | int dmax; | | 1731 | int dmax; |
1740 | base = cgbase(oldsb, i); | | 1732 | base = cgbase(oldsb, i); |
| @@ -1768,30 +1760,28 @@ shrink(void) | | | @@ -1768,30 +1760,28 @@ shrink(void) |
1768 | evict_data(cg, newcgsize, oldcgsize - newcgsize); | | 1760 | evict_data(cg, newcgsize, oldcgsize - newcgsize); |
1769 | clr_bits(cg_blksfree(cg, 0), newcgsize, oldcgsize - newcgsize); | | 1761 | clr_bits(cg_blksfree(cg, 0), newcgsize, oldcgsize - newcgsize); |
1770 | } | | 1762 | } |
1771 | /* Find out whether we would run out of inodes. (Note we | | 1763 | /* Find out whether we would run out of inodes. (Note we |
1772 | * haven't actually done anything to the file system yet; all | | 1764 | * haven't actually done anything to the file system yet; all |
1773 | * those evict_data calls just update blkmove.) */ | | 1765 | * those evict_data calls just update blkmove.) */ |
1774 | { | | 1766 | { |
1775 | int slop; | | 1767 | int slop; |
1776 | slop = 0; | | 1768 | slop = 0; |
1777 | for (i = 0; i < newsb->fs_ncg; i++) | | 1769 | for (i = 0; i < newsb->fs_ncg; i++) |
1778 | slop += cgs[i]->cg_cs.cs_nifree; | | 1770 | slop += cgs[i]->cg_cs.cs_nifree; |
1779 | for (; i < oldsb->fs_ncg; i++) | | 1771 | for (; i < oldsb->fs_ncg; i++) |
1780 | slop -= oldsb->fs_ipg - cgs[i]->cg_cs.cs_nifree; | | 1772 | slop -= oldsb->fs_ipg - cgs[i]->cg_cs.cs_nifree; |
1781 | if (slop < 0) { | | 1773 | if (slop < 0) |
1782 | printf("Sorry, would run out of inodes\n"); | | 1774 | errx(EXIT_FAILURE, "Sorry, would run out of inodes"); |
1783 | exit(EXIT_FAILURE); | | | |
1784 | } | | | |
1785 | } | | 1775 | } |
1786 | /* Copy data, then update pointers to data. See the comment | | 1776 | /* Copy data, then update pointers to data. See the comment |
1787 | * header on perform_data_move for ordering considerations. */ | | 1777 | * header on perform_data_move for ordering considerations. */ |
1788 | perform_data_move(); | | 1778 | perform_data_move(); |
1789 | update_for_data_move(); | | 1779 | update_for_data_move(); |
1790 | /* Now do inodes. Initialize, evict, move, update - see the | | 1780 | /* Now do inodes. Initialize, evict, move, update - see the |
1791 | * comment header on perform_inode_move. */ | | 1781 | * comment header on perform_inode_move. */ |
1792 | inomove_init(); | | 1782 | inomove_init(); |
1793 | for (i = newsb->fs_ncg; i < oldsb->fs_ncg; i++) | | 1783 | for (i = newsb->fs_ncg; i < oldsb->fs_ncg; i++) |
1794 | evict_inodes(cgs[i]); | | 1784 | evict_inodes(cgs[i]); |
1795 | perform_inode_move(); | | 1785 | perform_inode_move(); |
1796 | flush_inodes(); | | 1786 | flush_inodes(); |
1797 | update_for_inode_move(); | | 1787 | update_for_inode_move(); |
| @@ -2155,31 +2145,29 @@ main(int argc, char **argv) | | | @@ -2155,31 +2145,29 @@ main(int argc, char **argv) |
2155 | oldsb->fs_csaddr = oldsb->fs_old_csaddr; | | 2145 | oldsb->fs_csaddr = oldsb->fs_old_csaddr; |
2156 | oldsb->fs_size = oldsb->fs_old_size; | | 2146 | oldsb->fs_size = oldsb->fs_old_size; |
2157 | oldsb->fs_dsize = oldsb->fs_old_dsize; | | 2147 | oldsb->fs_dsize = oldsb->fs_old_dsize; |
2158 | oldsb->fs_cstotal.cs_ndir = oldsb->fs_old_cstotal.cs_ndir; | | 2148 | oldsb->fs_cstotal.cs_ndir = oldsb->fs_old_cstotal.cs_ndir; |
2159 | oldsb->fs_cstotal.cs_nbfree = oldsb->fs_old_cstotal.cs_nbfree; | | 2149 | oldsb->fs_cstotal.cs_nbfree = oldsb->fs_old_cstotal.cs_nbfree; |
2160 | oldsb->fs_cstotal.cs_nifree = oldsb->fs_old_cstotal.cs_nifree; | | 2150 | oldsb->fs_cstotal.cs_nifree = oldsb->fs_old_cstotal.cs_nifree; |
2161 | oldsb->fs_cstotal.cs_nffree = oldsb->fs_old_cstotal.cs_nffree; | | 2151 | oldsb->fs_cstotal.cs_nffree = oldsb->fs_old_cstotal.cs_nffree; |
2162 | /* any others? */ | | 2152 | /* any others? */ |
2163 | printf("Resizing with ffsv1 superblock\n"); | | 2153 | printf("Resizing with ffsv1 superblock\n"); |
2164 | } | | 2154 | } |
2165 | | | 2155 | |
2166 | oldsb->fs_qbmask = ~(int64_t) oldsb->fs_bmask; | | 2156 | oldsb->fs_qbmask = ~(int64_t) oldsb->fs_bmask; |
2167 | oldsb->fs_qfmask = ~(int64_t) oldsb->fs_fmask; | | 2157 | oldsb->fs_qfmask = ~(int64_t) oldsb->fs_fmask; |
2168 | if (oldsb->fs_ipg % INOPB(oldsb)) { | | 2158 | if (oldsb->fs_ipg % INOPB(oldsb)) |
2169 | (void)fprintf(stderr, "ipg[%d] %% INOPB[%d] != 0\n", | | 2159 | errx(EXIT_FAILURE, "ipg[%d] %% INOPB[%d] != 0", |
2170 | (int) oldsb->fs_ipg, (int) INOPB(oldsb)); | | 2160 | (int) oldsb->fs_ipg, (int) INOPB(oldsb)); |
2171 | exit(EXIT_FAILURE); | | | |
2172 | } | | | |
2173 | /* The superblock is bigger than struct fs (there are trailing | | 2161 | /* The superblock is bigger than struct fs (there are trailing |
2174 | * tables, of non-fixed size); make sure we copy the whole | | 2162 | * tables, of non-fixed size); make sure we copy the whole |
2175 | * thing. SBLOCKSIZE may be an over-estimate, but we do this | | 2163 | * thing. SBLOCKSIZE may be an over-estimate, but we do this |
2176 | * just once, so being generous is cheap. */ | | 2164 | * just once, so being generous is cheap. */ |
2177 | memcpy(newsb, oldsb, SBLOCKSIZE); | | 2165 | memcpy(newsb, oldsb, SBLOCKSIZE); |
2178 | loadcgs(); | | 2166 | loadcgs(); |
2179 | if (newsize > fsbtodb(oldsb, oldsb->fs_size)) { | | 2167 | if (newsize > fsbtodb(oldsb, oldsb->fs_size)) { |
2180 | grow(); | | 2168 | grow(); |
2181 | } else if (newsize < fsbtodb(oldsb, oldsb->fs_size)) { | | 2169 | } else if (newsize < fsbtodb(oldsb, oldsb->fs_size)) { |
2182 | if (is_ufs2) | | 2170 | if (is_ufs2) |
2183 | errx(EXIT_FAILURE,"shrinking not supported for ufs2"); | | 2171 | errx(EXIT_FAILURE,"shrinking not supported for ufs2"); |
2184 | shrink(); | | 2172 | shrink(); |
2185 | } | | 2173 | } |