Sat Aug 27 16:34:57 2011 UTC ()
PR/45301: Julian Fagir: make clear that the unit is sectors and fix a typo.
While there, use errx, and sizeof(*var) instead of sizeof(type)


(christos)
diff -r1.10 -r1.11 src/sbin/resize_ffs/resize_ffs.8
diff -r1.31 -r1.32 src/sbin/resize_ffs/resize_ffs.c

cvs diff -r1.10 -r1.11 src/sbin/resize_ffs/resize_ffs.8 (switch to unified diff)

--- src/sbin/resize_ffs/resize_ffs.8 2011/01/05 02:18:15 1.10
+++ src/sbin/resize_ffs/resize_ffs.8 2011/08/27 16:34:57 1.11
@@ -1,137 +1,138 @@ @@ -1,137 +1,138 @@
1.\" $NetBSD: resize_ffs.8,v 1.10 2011/01/05 02:18:15 riz Exp $ 1.\" $NetBSD: resize_ffs.8,v 1.11 2011/08/27 16:34:57 christos Exp $
2.\" 2.\"
3.\" As its sole author, I explicitly place this man page in the public 3.\" As its sole author, I explicitly place this man page in the public
4.\" domain. Anyone may use it in any way for any purpose (though I would 4.\" domain. Anyone may use it in any way for any purpose (though I would
5.\" appreciate credit where it is due). 5.\" appreciate credit where it is due).
6.\" 6.\"
7.\" /~\ The ASCII der Mouse 7.\" /~\ The ASCII der Mouse
8.\" \ / Ribbon Campaign 8.\" \ / Ribbon Campaign
9.\" X Against HTML mouse@rodents.montreal.qc.ca 9.\" X Against HTML mouse@rodents.montreal.qc.ca
10.\" / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B 10.\" / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
11.\" 11.\"
12.Dd January 4, 2011 12.Dd January 4, 2011
13.Dt RESIZE_FFS 8 13.Dt RESIZE_FFS 8
14.Os 14.Os
15.Sh NAME 15.Sh NAME
16.Nm resize_ffs 16.Nm resize_ffs
17.Nd resize a file system on disk or in a file 17.Nd resize a file system on disk or in a file
18.Sh SYNOPSIS 18.Sh SYNOPSIS
19.Nm 19.Nm
20.Op Fl y 20.Op Fl y
21.Op Fl s Ar size 21.Op Fl s Ar size
22.Ar special 22.Ar special
23.Sh DESCRIPTION 23.Sh DESCRIPTION
24.Nm 24.Nm
25resizes a file system. 25resizes a file system.
26.Ar special 26.Ar special
27is the name of the raw disk device or file where the file system resides; 27is the name of the raw disk device or file where the file system resides.
28(Sectors are almost always 512 bytes, and 
29.Nm 28.Nm
30can both grow and shrink file systems. 29can both grow and shrink file systems.
31When growing, the disk device 30When growing, the disk device
32must of course be large enough to contain the new file system; 31must of course be large enough to contain the new file system;
33.Nm 32.Nm
34simply extends the file system data structures into the new space. 33simply extends the file system data structures into the new space.
35When shrinking, 34When shrinking,
36.Nm 35.Nm
37assumes this. 36assumes this.
38It will not work correctly for file systems with other sector sizes.) 37It will not work correctly for file systems with other sector sizes.)
39.Nm 38.Nm
40has to copy anything that currently resides in the space being shrunk 39has to copy anything that currently resides in the space being shrunk
41away; there must be enough space free on the file system for this to 40away; there must be enough space free on the file system for this to
42succeed. 41succeed.
43If there isn't, 42If there isn't,
44.Nm 43.Nm
45will complain and exit; when this happens, it attempts to always leave 44will complain and exit; when this happens, it attempts to always leave
46the file system in a consistent state, but it is probably a good idea to 45the file system in a consistent state, but it is probably a good idea to
47check the file system with 46check the file system with
48.Xr fsck 8 . 47.Xr fsck 8 .
49.Pp 48.Pp
50If no 49If no
51.Fl s 50.Fl s
52option is provided, 51option is provided,
53.Nm 52.Nm
54will grow the file system to the underlying device size which is 53will grow the file system to the underlying device size which is
55determined from 54determined from
56.Ar special . 55.Ar special .
57.Pp 56.Pp
58The options are as follows: 57The options are as follows:
59.Bl -tag -width indent 58.Bl -tag -width indent
60.It Fl s 59.It Fl s
61Specify the file system size to which the file system should be 60Specify the file system size to which the file system should be
62resized. 61resized.
 62The size is given as the count of disk sectors, usually 512 bytes. To see the
 63exact value, have a look at the disk specification or the disklabel.
63Mostly used to shrink file systems. 64Mostly used to shrink file systems.
64.It Fl y 65.It Fl y
65Disable sanity questions made by 66Disable sanity questions made by
66.Nm . 67.Nm .
67.El 68.El
68.Sh WARNING 69.Sh WARNING
69.Em Interrupting 70.Em Interrupting
70.Nm 71.Nm
71.Em "may leave your file system in an inconsistent state and require a" 72.Em "may leave your file system in an inconsistent state and require a"
72.Em "restore from backup." 73.Em "restore from backup."
73It attempts to write in the proper order to avoid problems, but as it is 74It attempts to write in the proper order to avoid problems, but as it is
74still considered experimental, you should take great care when using it. 75still considered experimental, you should take great care when using it.
75.Pp 76.Pp
76When 77When
77.Nm 78.Nm
78is applied to a consistent file system, it should always produce a 79is applied to a consistent file system, it should always produce a
79consistent file system; if the file system is not consistent to start 80consistent file system; if the file system is not consistent to start
80with, 81with,
81.Nm 82.Nm
82may misbehave, anything from dumping core to completely curdling the 83may misbehave, anything from dumping core to completely curdling the
83data. 84data.
84It's probably wise to 85It's probably wise to
85.Xr fsck 8 86.Xr fsck 8
86the file system before and after, just to be safe. 87the file system before and after, just to be safe.
87You should be aware that just because 88You should be aware that just because
88.Xr fsck 8 89.Xr fsck 8
89is happy with the file system does not mean it is intact. 90is happy with the file system does not mean it is intact.
90.Sh EXIT STATUS 91.Sh EXIT STATUS
91.Nm 92.Nm
92exits with 0 on success. 93exits with 0 on success.
93Any major problems will cause 94Any major problems will cause
94.Nm 95.Nm
95to exit with the non-zero 96to exit with the non-zero
96.Xr exit 3 97.Xr exit 3
97codes, so as to alert any invoking program or script that human 98codes, so as to alert any invoking program or script that human
98intervention is required. 99intervention is required.
99.Sh EXAMPLES 100.Sh EXAMPLES
100.Dl resize_ffs Cm /dev/vg00/rlv1 101.Dl resize_ffs Cm /dev/vg00/rlv1
101.Pp 102.Pp
102will enlarge the file system on the Logical Volume 103will enlarge the file system on the Logical Volume
103.Pa /dev/vg00/lv1 104.Pa /dev/vg00/lv1
104from Volume Group vg00 to the current device size. 105from Volume Group vg00 to the current device size.
105.Sh SEE ALSO 106.Sh SEE ALSO
106.Xr fs 5 , 107.Xr fs 5 ,
107.Xr fsck 8 , 108.Xr fsck 8 ,
108.Xr newfs 8 109.Xr newfs 8
109.Sh HISTORY 110.Sh HISTORY
110The 111The
111.Nm 112.Nm
112command first appeared in 113command first appeared in
113.Nx 2.0 . 114.Nx 2.0 .
114.Sh AUTHORS 115.Sh AUTHORS
115.An der Mouse 116.An der Mouse
116.Aq mouse@rodents.montreal.qc.ca 117.Aq mouse@rodents.montreal.qc.ca
117(primary author) 118(primary author)
118.An Jeff Rizzo 119.An Jeff Rizzo
119.Aq riz@NetBSD.org 120.Aq riz@NetBSD.org
120(Byteswapped file system and UFS2 support) 121(Byteswapped file system and UFS2 support)
121.Pp 122.Pp
122A big bug-finding kudos goes to John Kohl for finding the rotational 123A big bug-finding kudos goes to John Kohl for finding the rotational
123layout bug referred to in the 124layout bug referred to in the
124.Sx WARNING 125.Sx WARNING
125section above. 126section above.
126.Sh BUGS 127.Sh BUGS
127Can fail to shrink a file system when there actually is enough space, 128Can fail to shrink a file system when there actually is enough space,
128because it does not distinguish between a block allocated as a block 129because it does not distinguish between a block allocated as a block
129and a block fully occupied by two or more frags. 130and a block fully occupied by two or more frags.
130This is unlikely to 131This is unlikely to
131occur in practice; except for pathological cases, it can happen only 132occur in practice; except for pathological cases, it can happen only
132when the new size is extremely close to the minimum possible. 133when the new size is extremely close to the minimum possible.
133.Pp 134.Pp
134Has no intelligence whatever when it comes to allocating blocks to copy 135Has no intelligence whatever when it comes to allocating blocks to copy
135data into when shrinking. 136data into when shrinking.
136.Pp 137.Pp
137Doesn't currently support shrinking FFSv2 file systems. 138Doesn't currently support shrinking FFSv2 file systems.

cvs diff -r1.31 -r1.32 src/sbin/resize_ffs/resize_ffs.c (switch to unified diff)

--- src/sbin/resize_ffs/resize_ffs.c 2011/08/15 02:22:46 1.31
+++ src/sbin/resize_ffs/resize_ffs.c 2011/08/27 16:34:57 1.32
@@ -1,2200 +1,2188 @@ @@ -1,2200 +1,2188 @@
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:
15 * 15 *
16 * Resize a file system. Is capable of both growing and shrinking. 16 * Resize a file system. Is capable of both growing and shrinking.
17 * 17 *
18 * Usage: resize_ffs [-s newsize] [-y] file_system 18 * Usage: resize_ffs [-s newsize] [-y] file_system
19 * 19 *
20 * Example: resize_ffs -s 29574 /dev/rsd1e 20 * Example: resize_ffs -s 29574 /dev/rsd1e
21 * 21 *
22 * newsize is in DEV_BSIZE units (ie, disk sectors, usually 512 bytes 22 * newsize is in DEV_BSIZE units (ie, disk sectors, usually 512 bytes
23 * each). 23 * each).
24 * 24 *
25 * Note: this currently requires gcc to build, since it is written 25 * Note: this currently requires gcc to build, since it is written
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 */
53 53
54#include <err.h> 54#include <err.h>
55#include <errno.h> 55#include <errno.h>
56#include <fcntl.h> 56#include <fcntl.h>
57#include <stdio.h> 57#include <stdio.h>
58#include <stdlib.h> 58#include <stdlib.h>
59#include <strings.h> 59#include <strings.h>
60#include <unistd.h> 60#include <unistd.h>
61 61
62/* new size of file system, in sectors */ 62/* new size of file system, in sectors */
63static int64_t newsize; 63static int64_t newsize;
64 64
65/* fd open onto disk device or file */ 65/* fd open onto disk device or file */
66static int fd; 66static int fd;
67 67
68/* must we break up big I/O operations - see checksmallio() */ 68/* must we break up big I/O operations - see checksmallio() */
69static int smallio; 69static int smallio;
70 70
71/* size of a cg, in bytes, rounded up to a frag boundary */ 71/* size of a cg, in bytes, rounded up to a frag boundary */
72static int cgblksz; 72static int cgblksz;
73 73
74/* possible superblock localtions */ 74/* possible superblock localtions */
75static int search[] = SBLOCKSEARCH; 75static int search[] = SBLOCKSEARCH;
76/* location of the superblock */ 76/* location of the superblock */
77static off_t where; 77static off_t where;
78 78
79/* Superblocks. */ 79/* Superblocks. */
80static struct fs *oldsb; /* before we started */ 80static struct fs *oldsb; /* before we started */
81static struct fs *newsb; /* copy to work with */ 81static struct fs *newsb; /* copy to work with */
82/* Buffer to hold the above. Make sure it's aligned correctly. */ 82/* Buffer to hold the above. Make sure it's aligned correctly. */
83static char sbbuf[2 * SBLOCKSIZE] 83static char sbbuf[2 * SBLOCKSIZE]
84 __attribute__((__aligned__(__alignof__(struct fs)))); 84 __attribute__((__aligned__(__alignof__(struct fs))));
85 85
86union dinode { 86union dinode {
87 struct ufs1_dinode dp1; 87 struct ufs1_dinode dp1;
88 struct ufs2_dinode dp2; 88 struct ufs2_dinode dp2;
89}; 89};
90#define DIP(dp, field) \ 90#define DIP(dp, field) \
91 ((is_ufs2) ? \ 91 ((is_ufs2) ? \
92 (dp)->dp2.field : (dp)->dp1.field) 92 (dp)->dp2.field : (dp)->dp1.field)
93 93
94#define DIP_ASSIGN(dp, field, value) \ 94#define DIP_ASSIGN(dp, field, value) \
95 do { \ 95 do { \
96 if (is_ufs2) \ 96 if (is_ufs2) \
97 (dp)->dp2.field = (value); \ 97 (dp)->dp2.field = (value); \
98 else \ 98 else \
99 (dp)->dp1.field = (value); \ 99 (dp)->dp1.field = (value); \
100 } while (0) 100 } while (0)
101 101
102/* a cg's worth of brand new squeaky-clean inodes */ 102/* a cg's worth of brand new squeaky-clean inodes */
103static struct ufs1_dinode *zinodes; 103static struct ufs1_dinode *zinodes;
104 104
105/* pointers to the in-core cgs, read off disk and possibly modified */ 105/* pointers to the in-core cgs, read off disk and possibly modified */
106static struct cg **cgs; 106static struct cg **cgs;
107 107
108/* pointer to csum array - the stuff pointed to on-disk by fs_csaddr */ 108/* pointer to csum array - the stuff pointed to on-disk by fs_csaddr */
109static struct csum *csums; 109static struct csum *csums;
110 110
111/* per-cg flags, indexed by cg number */ 111/* per-cg flags, indexed by cg number */
112static unsigned char *cgflags; 112static unsigned char *cgflags;
113#define CGF_DIRTY 0x01 /* needs to be written to disk */ 113#define CGF_DIRTY 0x01 /* needs to be written to disk */
114#define CGF_BLKMAPS 0x02 /* block bitmaps need rebuilding */ 114#define CGF_BLKMAPS 0x02 /* block bitmaps need rebuilding */
115#define CGF_INOMAPS 0x04 /* inode bitmaps need rebuilding */ 115#define CGF_INOMAPS 0x04 /* inode bitmaps need rebuilding */
116 116
117/* when shrinking, these two arrays record how we want blocks to move. */ 117/* when shrinking, these two arrays record how we want blocks to move. */
118/* if blkmove[i] is j, the frag that started out as frag #i should end */ 118/* if blkmove[i] is j, the frag that started out as frag #i should end */
119/* up as frag #j. inomove[i]=j means, similarly, that the inode that */ 119/* up as frag #j. inomove[i]=j means, similarly, that the inode that */
120/* started out as inode i should end up as inode j. */ 120/* started out as inode i should end up as inode j. */
121static unsigned int *blkmove; 121static unsigned int *blkmove;
122static unsigned int *inomove; 122static unsigned int *inomove;
123 123
124/* in-core copies of all inodes in the fs, indexed by inumber */ 124/* in-core copies of all inodes in the fs, indexed by inumber */
125union dinode *inodes; 125union dinode *inodes;
126 126
127void *ibuf; /* ptr to fs block-sized buffer for reading/writing inodes */ 127void *ibuf; /* ptr to fs block-sized buffer for reading/writing inodes */
128 128
129/* byteswapped inodes */ 129/* byteswapped inodes */
130union dinode *sinodes; 130union dinode *sinodes;
131 131
132/* per-inode flags, indexed by inumber */ 132/* per-inode flags, indexed by inumber */
133static unsigned char *iflags; 133static unsigned char *iflags;
134#define IF_DIRTY 0x01 /* needs to be written to disk */ 134#define IF_DIRTY 0x01 /* needs to be written to disk */
135#define IF_BDIRTY 0x02 /* like DIRTY, but is set on first inode in a 135#define IF_BDIRTY 0x02 /* like DIRTY, but is set on first inode in a
136 * block of inodes, and applies to the whole 136 * block of inodes, and applies to the whole
137 * block. */ 137 * block. */
138 138
139/* resize_ffs works directly on dinodes, adapt blksize() */ 139/* resize_ffs works directly on dinodes, adapt blksize() */
140#define dblksize(fs, dip, lbn, filesize) \ 140#define dblksize(fs, dip, lbn, filesize) \
141 (((lbn) >= NDADDR || (filesize) >= lblktosize(fs, (lbn) + 1)) \ 141 (((lbn) >= NDADDR || (filesize) >= lblktosize(fs, (lbn) + 1)) \
142 ? (fs)->fs_bsize \ 142 ? (fs)->fs_bsize \
143 : (fragroundup(fs, blkoff(fs, (filesize))))) 143 : (fragroundup(fs, blkoff(fs, (filesize)))))
144 144
145 145
146/* 146/*
147 * Number of disk sectors per block/fragment 147 * Number of disk sectors per block/fragment
148 */ 148 */
149#define NSPB(fs) (fsbtodb((fs),1) << (fs)->fs_fragshift) 149#define NSPB(fs) (fsbtodb((fs),1) << (fs)->fs_fragshift)
150#define NSPF(fs) (fsbtodb((fs),1)) 150#define NSPF(fs) (fsbtodb((fs),1))
151 151
152/* global flags */ 152/* global flags */
153int is_ufs2 = 0; 153int is_ufs2 = 0;
154int needswap = 0; 154int needswap = 0;
155 155
156static void usage(void) __dead; 156static void usage(void) __dead;
157 157
158/* 158/*
159 * See if we need to break up large I/O operations. This should never 159 * See if we need to break up large I/O operations. This should never
160 * be needed, but under at least one <version,platform> combination, 160 * be needed, but under at least one <version,platform> combination,
161 * large enough disk transfers to the raw device hang. So if we're 161 * large enough disk transfers to the raw device hang. So if we're
162 * talking to a character special device, play it safe; in this case, 162 * talking to a character special device, play it safe; in this case,
163 * readat() and writeat() break everything up into pieces no larger 163 * readat() and writeat() break everything up into pieces no larger
164 * than 8K, doing multiple syscalls for larger operations. 164 * than 8K, doing multiple syscalls for larger operations.
165 */ 165 */
166static void 166static void
167checksmallio(void) 167checksmallio(void)
168{ 168{
169 struct stat stb; 169 struct stat stb;
170 170
171 fstat(fd, &stb); 171 fstat(fd, &stb);
172 smallio = ((stb.st_mode & S_IFMT) == S_IFCHR); 172 smallio = ((stb.st_mode & S_IFMT) == S_IFCHR);
173} 173}
174 174
175static int 175static int
176isplainfile(void) 176isplainfile(void)
177{ 177{
178 struct stat stb; 178 struct stat stb;
179 179
180 fstat(fd, &stb); 180 fstat(fd, &stb);
181 return S_ISREG(stb.st_mode); 181 return S_ISREG(stb.st_mode);
182} 182}
183/* 183/*
184 * Read size bytes starting at blkno into buf. blkno is in DEV_BSIZE 184 * Read size bytes starting at blkno into buf. blkno is in DEV_BSIZE
185 * units, ie, after fsbtodb(); size is in bytes. 185 * units, ie, after fsbtodb(); size is in bytes.
186 */ 186 */
187static void 187static void
188readat(off_t blkno, void *buf, int size) 188readat(off_t blkno, void *buf, int size)
189{ 189{
190 /* Seek to the correct place. */ 190 /* Seek to the correct place. */
191 if (lseek(fd, blkno * DEV_BSIZE, L_SET) < 0) 191 if (lseek(fd, blkno * DEV_BSIZE, L_SET) < 0)
192 err(EXIT_FAILURE, "lseek failed"); 192 err(EXIT_FAILURE, "lseek failed");
193 193
194 /* See if we have to break up the transfer... */ 194 /* See if we have to break up the transfer... */
195 if (smallio) { 195 if (smallio) {
196 char *bp; /* pointer into buf */ 196 char *bp; /* pointer into buf */
197 int left; /* bytes left to go */ 197 int left; /* bytes left to go */
198 int n; /* number to do this time around */ 198 int n; /* number to do this time around */
199 int rv; /* syscall return value */ 199 int rv; /* syscall return value */
200 bp = buf; 200 bp = buf;
201 left = size; 201 left = size;
202 while (left > 0) { 202 while (left > 0) {
203 n = (left > 8192) ? 8192 : left; 203 n = (left > 8192) ? 8192 : left;
204 rv = read(fd, bp, n); 204 rv = read(fd, bp, n);
205 if (rv < 0) 205 if (rv < 0)
206 err(EXIT_FAILURE, "read failed"); 206 err(EXIT_FAILURE, "read failed");
207 if (rv != n) 207 if (rv != n)
208 errx(EXIT_FAILURE, 208 errx(EXIT_FAILURE,
209 "read: wanted %d, got %d", n, rv); 209 "read: wanted %d, got %d", n, rv);
210 bp += n; 210 bp += n;
211 left -= n; 211 left -= n;
212 } 212 }
213 } else { 213 } else {
214 int rv; 214 int rv;
215 rv = read(fd, buf, size); 215 rv = read(fd, buf, size);
216 if (rv < 0) 216 if (rv < 0)
217 err(EXIT_FAILURE, "read failed"); 217 err(EXIT_FAILURE, "read failed");
218 if (rv != size) 218 if (rv != size)
219 errx(EXIT_FAILURE, "read: wanted %d, got %d", 219 errx(EXIT_FAILURE, "read: wanted %d, got %d",
220 size, rv); 220 size, rv);
221 } 221 }
222} 222}
223/* 223/*
224 * Write size bytes from buf starting at blkno. blkno is in DEV_BSIZE 224 * Write size bytes from buf starting at blkno. blkno is in DEV_BSIZE
225 * units, ie, after fsbtodb(); size is in bytes. 225 * units, ie, after fsbtodb(); size is in bytes.
226 */ 226 */
227static void 227static void
228writeat(off_t blkno, const void *buf, int size) 228writeat(off_t blkno, const void *buf, int size)
229{ 229{
230 /* Seek to the correct place. */ 230 /* Seek to the correct place. */
231 if (lseek(fd, blkno * DEV_BSIZE, L_SET) < 0) 231 if (lseek(fd, blkno * DEV_BSIZE, L_SET) < 0)
232 err(EXIT_FAILURE, "lseek failed"); 232 err(EXIT_FAILURE, "lseek failed");
233 /* See if we have to break up the transfer... */ 233 /* See if we have to break up the transfer... */
234 if (smallio) { 234 if (smallio) {
235 const char *bp; /* pointer into buf */ 235 const char *bp; /* pointer into buf */
236 int left; /* bytes left to go */ 236 int left; /* bytes left to go */
237 int n; /* number to do this time around */ 237 int n; /* number to do this time around */
238 int rv; /* syscall return value */ 238 int rv; /* syscall return value */
239 bp = buf; 239 bp = buf;
240 left = size; 240 left = size;
241 while (left > 0) { 241 while (left > 0) {
242 n = (left > 8192) ? 8192 : left; 242 n = (left > 8192) ? 8192 : left;
243 rv = write(fd, bp, n); 243 rv = write(fd, bp, n);
244 if (rv < 0) 244 if (rv < 0)
245 err(EXIT_FAILURE, "write failed"); 245 err(EXIT_FAILURE, "write failed");
246 if (rv != n) 246 if (rv != n)
247 errx(EXIT_FAILURE, 247 errx(EXIT_FAILURE,
248 "write: wanted %d, got %d", n, rv); 248 "write: wanted %d, got %d", n, rv);
249 bp += n; 249 bp += n;
250 left -= n; 250 left -= n;
251 } 251 }
252 } else { 252 } else {
253 int rv; 253 int rv;
254 rv = write(fd, buf, size); 254 rv = write(fd, buf, size);
255 if (rv < 0) 255 if (rv < 0)
256 err(EXIT_FAILURE, "write failed"); 256 err(EXIT_FAILURE, "write failed");
257 if (rv != size) 257 if (rv != size)
258 errx(EXIT_FAILURE, 258 errx(EXIT_FAILURE,
259 "write: wanted %d, got %d", size, rv); 259 "write: wanted %d, got %d", size, rv);
260 } 260 }
261} 261}
262/* 262/*
263 * Never-fail versions of malloc() and realloc(), and an allocation 263 * Never-fail versions of malloc() and realloc(), and an allocation
264 * routine (which also never fails) for allocating memory that will 264 * routine (which also never fails) for allocating memory that will
265 * never be freed until exit. 265 * never be freed until exit.
266 */ 266 */
267 267
268/* 268/*
269 * Never-fail malloc. 269 * Never-fail malloc.
270 */ 270 */
271static void * 271static void *
272nfmalloc(size_t nb, const char *tag) 272nfmalloc(size_t nb, const char *tag)
273{ 273{
274 void *rv; 274 void *rv;
275 275
276 rv = malloc(nb); 276 rv = malloc(nb);
277 if (rv) 277 if (rv)
278 return (rv); 278 return (rv);
279 err(EXIT_FAILURE, "Can't allocate %lu bytes for %s", 279 err(EXIT_FAILURE, "Can't allocate %lu bytes for %s",
280 (unsigned long int) nb, tag); 280 (unsigned long int) nb, tag);
281} 281}
282/* 282/*
283 * Never-fail realloc. 283 * Never-fail realloc.
284 */ 284 */
285static void * 285static void *
286nfrealloc(void *blk, size_t nb, const char *tag) 286nfrealloc(void *blk, size_t nb, const char *tag)
287{ 287{
288 void *rv; 288 void *rv;
289 289
290 rv = realloc(blk, nb); 290 rv = realloc(blk, nb);
291 if (rv) 291 if (rv)
292 return (rv); 292 return (rv);
293 err(EXIT_FAILURE, "Can't re-allocate %lu bytes for %s", 293 err(EXIT_FAILURE, "Can't re-allocate %lu bytes for %s",
294 (unsigned long int) nb, tag); 294 (unsigned long int) nb, tag);
295} 295}
296/* 296/*
297 * Allocate memory that will never be freed or reallocated. Arguably 297 * Allocate memory that will never be freed or reallocated. Arguably
298 * this routine should handle small allocations by chopping up pages, 298 * this routine should handle small allocations by chopping up pages,
299 * but that's not worth the bother; it's not called more than a 299 * but that's not worth the bother; it's not called more than a
300 * handful of times per run, and if the allocations are that small the 300 * handful of times per run, and if the allocations are that small the
301 * waste in giving each one its own page is ignorable. 301 * waste in giving each one its own page is ignorable.
302 */ 302 */
303static void * 303static void *
304alloconce(size_t nb, const char *tag) 304alloconce(size_t nb, const char *tag)
305{ 305{
306 void *rv; 306 void *rv;
307 307
308 rv = mmap(0, nb, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 308 rv = mmap(0, nb, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
309 if (rv != MAP_FAILED) 309 if (rv != MAP_FAILED)
310 return (rv); 310 return (rv);
311 err(EXIT_FAILURE, "Can't map %lu bytes for %s", 311 err(EXIT_FAILURE, "Can't map %lu bytes for %s",
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 */
318static void 318static void
319loadcgs(void) 319loadcgs(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)
339 ffs_csum_swap(csums,csums,oldsb->fs_cssize); 339 ffs_csum_swap(csums,csums,oldsb->fs_cssize);
340} 340}
341/* 341/*
342 * Set n bits, starting with bit #base, in the bitmap pointed to by 342 * Set n bits, starting with bit #base, in the bitmap pointed to by
343 * bitvec (which is assumed to be large enough to include bits base 343 * bitvec (which is assumed to be large enough to include bits base
344 * through base+n-1). 344 * through base+n-1).
345 */ 345 */
346static void 346static void
347set_bits(unsigned char *bitvec, unsigned int base, unsigned int n) 347set_bits(unsigned char *bitvec, unsigned int base, unsigned int n)
348{ 348{
349 if (n < 1) 349 if (n < 1)
350 return; /* nothing to do */ 350 return; /* nothing to do */
351 if (base & 7) { /* partial byte at beginning */ 351 if (base & 7) { /* partial byte at beginning */
352 if (n <= 8 - (base & 7)) { /* entirely within one byte */ 352 if (n <= 8 - (base & 7)) { /* entirely within one byte */
353 bitvec[base >> 3] |= (~((~0U) << n)) << (base & 7); 353 bitvec[base >> 3] |= (~((~0U) << n)) << (base & 7);
354 return; 354 return;
355 } 355 }
356 bitvec[base >> 3] |= (~0U) << (base & 7); 356 bitvec[base >> 3] |= (~0U) << (base & 7);
357 n -= 8 - (base & 7); 357 n -= 8 - (base & 7);
358 base = (base & ~7) + 8; 358 base = (base & ~7) + 8;
359 } 359 }
360 if (n >= 8) { /* do full bytes */ 360 if (n >= 8) { /* do full bytes */
361 memset(bitvec + (base >> 3), 0xff, n >> 3); 361 memset(bitvec + (base >> 3), 0xff, n >> 3);
362 base += n & ~7; 362 base += n & ~7;
363 n &= 7; 363 n &= 7;
364 } 364 }
365 if (n) { /* partial byte at end */ 365 if (n) { /* partial byte at end */
366 bitvec[base >> 3] |= ~((~0U) << n); 366 bitvec[base >> 3] |= ~((~0U) << n);
367 } 367 }
368} 368}
369/* 369/*
370 * Clear n bits, starting with bit #base, in the bitmap pointed to by 370 * Clear n bits, starting with bit #base, in the bitmap pointed to by
371 * bitvec (which is assumed to be large enough to include bits base 371 * bitvec (which is assumed to be large enough to include bits base
372 * through base+n-1). Code parallels set_bits(). 372 * through base+n-1). Code parallels set_bits().
373 */ 373 */
374static void 374static void
375clr_bits(unsigned char *bitvec, int base, int n) 375clr_bits(unsigned char *bitvec, int base, int n)
376{ 376{
377 if (n < 1) 377 if (n < 1)
378 return; 378 return;
379 if (base & 7) { 379 if (base & 7) {
380 if (n <= 8 - (base & 7)) { 380 if (n <= 8 - (base & 7)) {
381 bitvec[base >> 3] &= ~((~((~0U) << n)) << (base & 7)); 381 bitvec[base >> 3] &= ~((~((~0U) << n)) << (base & 7));
382 return; 382 return;
383 } 383 }
384 bitvec[base >> 3] &= ~((~0U) << (base & 7)); 384 bitvec[base >> 3] &= ~((~0U) << (base & 7));
385 n -= 8 - (base & 7); 385 n -= 8 - (base & 7);
386 base = (base & ~7) + 8; 386 base = (base & ~7) + 8;
387 } 387 }
388 if (n >= 8) { 388 if (n >= 8) {
389 memset(bitvec + (base >> 3), 0, n >> 3); 389 memset(bitvec + (base >> 3), 0, n >> 3);
390 base += n & ~7; 390 base += n & ~7;
391 n &= 7; 391 n &= 7;
392 } 392 }
393 if (n) { 393 if (n) {
394 bitvec[base >> 3] &= (~0U) << n; 394 bitvec[base >> 3] &= (~0U) << n;
395 } 395 }
396} 396}
397/* 397/*
398 * Test whether bit #bit is set in the bitmap pointed to by bitvec. 398 * Test whether bit #bit is set in the bitmap pointed to by bitvec.
399 */ 399 */
400static int 400static int
401bit_is_set(unsigned char *bitvec, int bit) 401bit_is_set(unsigned char *bitvec, int bit)
402{ 402{
403 return (bitvec[bit >> 3] & (1 << (bit & 7))); 403 return (bitvec[bit >> 3] & (1 << (bit & 7)));
404} 404}
405/* 405/*
406 * Test whether bit #bit is clear in the bitmap pointed to by bitvec. 406 * Test whether bit #bit is clear in the bitmap pointed to by bitvec.
407 */ 407 */
408static int 408static int
409bit_is_clr(unsigned char *bitvec, int bit) 409bit_is_clr(unsigned char *bitvec, int bit)
410{ 410{
411 return (!bit_is_set(bitvec, bit)); 411 return (!bit_is_set(bitvec, bit));
412} 412}
413/* 413/*
414 * Test whether a whole block of bits is set in a bitmap. This is 414 * Test whether a whole block of bits is set in a bitmap. This is
415 * designed for testing (aligned) disk blocks in a bit-per-frag 415 * designed for testing (aligned) disk blocks in a bit-per-frag
416 * bitmap; it has assumptions wired into it based on that, essentially 416 * bitmap; it has assumptions wired into it based on that, essentially
417 * that the entire block fits into a single byte. This returns true 417 * that the entire block fits into a single byte. This returns true
418 * iff _all_ the bits are set; it is not just the complement of 418 * iff _all_ the bits are set; it is not just the complement of
419 * blk_is_clr on the same arguments (unless blkfrags==1). 419 * blk_is_clr on the same arguments (unless blkfrags==1).
420 */ 420 */
421static int 421static int
422blk_is_set(unsigned char *bitvec, int blkbase, int blkfrags) 422blk_is_set(unsigned char *bitvec, int blkbase, int blkfrags)
423{ 423{
424 unsigned int mask; 424 unsigned int mask;
425 425
426 mask = (~((~0U) << blkfrags)) << (blkbase & 7); 426 mask = (~((~0U) << blkfrags)) << (blkbase & 7);
427 return ((bitvec[blkbase >> 3] & mask) == mask); 427 return ((bitvec[blkbase >> 3] & mask) == mask);
428} 428}
429/* 429/*
430 * Test whether a whole block of bits is clear in a bitmap. See 430 * Test whether a whole block of bits is clear in a bitmap. See
431 * blk_is_set (above) for assumptions. This returns true iff _all_ 431 * blk_is_set (above) for assumptions. This returns true iff _all_
432 * the bits are clear; it is not just the complement of blk_is_set on 432 * the bits are clear; it is not just the complement of blk_is_set on
433 * the same arguments (unless blkfrags==1). 433 * the same arguments (unless blkfrags==1).
434 */ 434 */
435static int 435static int
436blk_is_clr(unsigned char *bitvec, int blkbase, int blkfrags) 436blk_is_clr(unsigned char *bitvec, int blkbase, int blkfrags)
437{ 437{
438 unsigned int mask; 438 unsigned int mask;
439 439
440 mask = (~((~0U) << blkfrags)) << (blkbase & 7); 440 mask = (~((~0U) << blkfrags)) << (blkbase & 7);
441 return ((bitvec[blkbase >> 3] & mask) == 0); 441 return ((bitvec[blkbase >> 3] & mask) == 0);
442} 442}
443/* 443/*
444 * Initialize a new cg. Called when growing. Assumes memory has been 444 * Initialize a new cg. Called when growing. Assumes memory has been
445 * allocated but not otherwise set up. This code sets the fields of 445 * allocated but not otherwise set up. This code sets the fields of
446 * the cg, initializes the bitmaps (and cluster summaries, if 446 * the cg, initializes the bitmaps (and cluster summaries, if
447 * applicable), updates both per-cylinder summary info and the global 447 * applicable), updates both per-cylinder summary info and the global
448 * summary info in newsb; it also writes out new inodes for the cg. 448 * summary info in newsb; it also writes out new inodes for the cg.
449 * 449 *
450 * This code knows it can never be called for cg 0, which makes it a 450 * This code knows it can never be called for cg 0, which makes it a
451 * bit simpler than it would otherwise be. 451 * bit simpler than it would otherwise be.
452 */ 452 */
453static void 453static void
454initcg(int cgn) 454initcg(int cgn)
455{ 455{
456 struct cg *cg; /* The in-core cg, of course */ 456 struct cg *cg; /* The in-core cg, of course */
457 int base; /* Disk address of cg base */ 457 int base; /* Disk address of cg base */
458 int dlow; /* Size of pre-cg data area */ 458 int dlow; /* Size of pre-cg data area */
459 int dhigh; /* Offset of post-inode data area, from base */ 459 int dhigh; /* Offset of post-inode data area, from base */
460 int dmax; /* Offset of end of post-inode data area */ 460 int dmax; /* Offset of end of post-inode data area */
461 int i; /* Generic loop index */ 461 int i; /* Generic loop index */
462 int n; /* Generic count */ 462 int n; /* Generic count */
463 int start; /* start of cg maps */ 463 int start; /* start of cg maps */
464 464
465 cg = cgs[cgn]; 465 cg = cgs[cgn];
466 /* Place the data areas */ 466 /* Place the data areas */
467 base = cgbase(newsb, cgn); 467 base = cgbase(newsb, cgn);
468 dlow = cgsblock(newsb, cgn) - base; 468 dlow = cgsblock(newsb, cgn) - base;
469 dhigh = cgdmin(newsb, cgn) - base; 469 dhigh = cgdmin(newsb, cgn) - base;
470 dmax = newsb->fs_size - base; 470 dmax = newsb->fs_size - base;
471 if (dmax > newsb->fs_fpg) 471 if (dmax > newsb->fs_fpg)
472 dmax = newsb->fs_fpg; 472 dmax = newsb->fs_fpg;
473 start = &cg->cg_space[0] - (unsigned char *) cg; 473 start = &cg->cg_space[0] - (unsigned char *) cg;
474 /* 474 /*
475 * Clear out the cg - assumes all-0-bytes is the correct way 475 * Clear out the cg - assumes all-0-bytes is the correct way
476 * to initialize fields we don't otherwise touch, which is 476 * to initialize fields we don't otherwise touch, which is
477 * perhaps not the right thing to do, but it's what fsck and 477 * perhaps not the right thing to do, but it's what fsck and
478 * mkfs do. 478 * mkfs do.
479 */ 479 */
480 memset(cg, 0, newsb->fs_cgsize); 480 memset(cg, 0, newsb->fs_cgsize);
481 if (newsb->fs_old_flags & FS_FLAGS_UPDATED) 481 if (newsb->fs_old_flags & FS_FLAGS_UPDATED)
482 cg->cg_time = newsb->fs_time; 482 cg->cg_time = newsb->fs_time;
483 cg->cg_magic = CG_MAGIC; 483 cg->cg_magic = CG_MAGIC;
484 cg->cg_cgx = cgn; 484 cg->cg_cgx = cgn;
485 cg->cg_niblk = newsb->fs_ipg; 485 cg->cg_niblk = newsb->fs_ipg;
486 cg->cg_ndblk = dmax; 486 cg->cg_ndblk = dmax;
487 487
488 if (is_ufs2) { 488 if (is_ufs2) {
489 cg->cg_time = newsb->fs_time; 489 cg->cg_time = newsb->fs_time;
490 cg->cg_initediblk = newsb->fs_ipg < 2 * INOPB(newsb) ? 490 cg->cg_initediblk = newsb->fs_ipg < 2 * INOPB(newsb) ?
491 newsb->fs_ipg : 2 * INOPB(newsb); 491 newsb->fs_ipg : 2 * INOPB(newsb);
492 cg->cg_iusedoff = start; 492 cg->cg_iusedoff = start;
493 } else { 493 } else {
494 cg->cg_old_time = newsb->fs_time; 494 cg->cg_old_time = newsb->fs_time;
495 cg->cg_old_niblk = cg->cg_niblk; 495 cg->cg_old_niblk = cg->cg_niblk;
496 cg->cg_niblk = 0; 496 cg->cg_niblk = 0;
497 cg->cg_initediblk = 0; 497 cg->cg_initediblk = 0;
498 498
499 499
500 cg->cg_old_ncyl = newsb->fs_old_cpg; 500 cg->cg_old_ncyl = newsb->fs_old_cpg;
501 /* Update the cg_old_ncyl value for the last cylinder. */ 501 /* Update the cg_old_ncyl value for the last cylinder. */
502 if (cgn == newsb->fs_ncg - 1) { 502 if (cgn == newsb->fs_ncg - 1) {
503 if ((newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0) 503 if ((newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0)
504 cg->cg_old_ncyl = newsb->fs_old_ncyl % 504 cg->cg_old_ncyl = newsb->fs_old_ncyl %
505 newsb->fs_old_cpg; 505 newsb->fs_old_cpg;
506 } 506 }
507 507
508 /* Set up the bitmap pointers. We have to be careful 508 /* Set up the bitmap pointers. We have to be careful
509 * to lay out the cg _exactly_ the way mkfs and fsck 509 * to lay out the cg _exactly_ the way mkfs and fsck
510 * do it, since fsck compares the _entire_ cg against 510 * do it, since fsck compares the _entire_ cg against
511 * a recomputed cg, and whines if there is any 511 * a recomputed cg, and whines if there is any
512 * mismatch, including the bitmap offsets. */ 512 * mismatch, including the bitmap offsets. */
513 /* XXX update this comment when fsck is fixed */ 513 /* XXX update this comment when fsck is fixed */
514 cg->cg_old_btotoff = start; 514 cg->cg_old_btotoff = start;
515 cg->cg_old_boff = cg->cg_old_btotoff 515 cg->cg_old_boff = cg->cg_old_btotoff
516 + (newsb->fs_old_cpg * sizeof(int32_t)); 516 + (newsb->fs_old_cpg * sizeof(int32_t));
517 cg->cg_iusedoff = cg->cg_old_boff + 517 cg->cg_iusedoff = cg->cg_old_boff +
518 (newsb->fs_old_cpg * newsb->fs_old_nrpos * sizeof(int16_t)); 518 (newsb->fs_old_cpg * newsb->fs_old_nrpos * sizeof(int16_t));
519 } 519 }
520 cg->cg_freeoff = cg->cg_iusedoff + howmany(newsb->fs_ipg, NBBY); 520 cg->cg_freeoff = cg->cg_iusedoff + howmany(newsb->fs_ipg, NBBY);
521 if (newsb->fs_contigsumsize > 0) { 521 if (newsb->fs_contigsumsize > 0) {
522 cg->cg_nclusterblks = cg->cg_ndblk / newsb->fs_frag; 522 cg->cg_nclusterblks = cg->cg_ndblk / newsb->fs_frag;
523 cg->cg_clustersumoff = cg->cg_freeoff + 523 cg->cg_clustersumoff = cg->cg_freeoff +
524 howmany(newsb->fs_fpg, NBBY) - sizeof(int32_t); 524 howmany(newsb->fs_fpg, NBBY) - sizeof(int32_t);
525 cg->cg_clustersumoff = 525 cg->cg_clustersumoff =
526 roundup(cg->cg_clustersumoff, sizeof(int32_t)); 526 roundup(cg->cg_clustersumoff, sizeof(int32_t));
527 cg->cg_clusteroff = cg->cg_clustersumoff + 527 cg->cg_clusteroff = cg->cg_clustersumoff +
528 ((newsb->fs_contigsumsize + 1) * sizeof(int32_t)); 528 ((newsb->fs_contigsumsize + 1) * sizeof(int32_t));
529 cg->cg_nextfreeoff = cg->cg_clusteroff + 529 cg->cg_nextfreeoff = cg->cg_clusteroff +
530 howmany(fragstoblks(newsb,newsb->fs_fpg), NBBY); 530 howmany(fragstoblks(newsb,newsb->fs_fpg), NBBY);
531 n = dlow / newsb->fs_frag; 531 n = dlow / newsb->fs_frag;
532 if (n > 0) { 532 if (n > 0) {
533 set_bits(cg_clustersfree(cg, 0), 0, n); 533 set_bits(cg_clustersfree(cg, 0), 0, n);
534 cg_clustersum(cg, 0)[(n > newsb->fs_contigsumsize) ? 534 cg_clustersum(cg, 0)[(n > newsb->fs_contigsumsize) ?
535 newsb->fs_contigsumsize : n]++; 535 newsb->fs_contigsumsize : n]++;
536 } 536 }
537 } else { 537 } else {
538 cg->cg_nextfreeoff = cg->cg_freeoff + 538 cg->cg_nextfreeoff = cg->cg_freeoff +
539 howmany(newsb->fs_fpg, NBBY); 539 howmany(newsb->fs_fpg, NBBY);
540 } 540 }
541 /* Mark the data areas as free; everything else is marked busy by the 541 /* Mark the data areas as free; everything else is marked busy by the
542 * memset() up at the top. */ 542 * memset() up at the top. */
543 set_bits(cg_blksfree(cg, 0), 0, dlow); 543 set_bits(cg_blksfree(cg, 0), 0, dlow);
544 set_bits(cg_blksfree(cg, 0), dhigh, dmax - dhigh); 544 set_bits(cg_blksfree(cg, 0), dhigh, dmax - dhigh);
545 /* Initialize summary info */ 545 /* Initialize summary info */
546 cg->cg_cs.cs_ndir = 0; 546 cg->cg_cs.cs_ndir = 0;
547 cg->cg_cs.cs_nifree = newsb->fs_ipg; 547 cg->cg_cs.cs_nifree = newsb->fs_ipg;
548 cg->cg_cs.cs_nbfree = dlow / newsb->fs_frag; 548 cg->cg_cs.cs_nbfree = dlow / newsb->fs_frag;
549 cg->cg_cs.cs_nffree = 0; 549 cg->cg_cs.cs_nffree = 0;
550 550
551 /* This is the simplest way of doing this; we perhaps could 551 /* This is the simplest way of doing this; we perhaps could
552 * compute the correct cg_blktot()[] and cg_blks()[] values 552 * compute the correct cg_blktot()[] and cg_blks()[] values
553 * other ways, but it would be complicated and hardly seems 553 * other ways, but it would be complicated and hardly seems
554 * worth the effort. (The reason there isn't 554 * worth the effort. (The reason there isn't
555 * frag-at-beginning and frag-at-end code here, like the code 555 * frag-at-beginning and frag-at-end code here, like the code
556 * below for the post-inode data area, is that the pre-sb data 556 * below for the post-inode data area, is that the pre-sb data
557 * area always starts at 0, and thus is block-aligned, and 557 * area always starts at 0, and thus is block-aligned, and
558 * always ends at the sb, which is block-aligned.) */ 558 * always ends at the sb, which is block-aligned.) */
559 if ((newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0) 559 if ((newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0)
560 for (i = 0; i < dlow; i += newsb->fs_frag) { 560 for (i = 0; i < dlow; i += newsb->fs_frag) {
561 old_cg_blktot(cg, 0)[old_cbtocylno(newsb, i)]++; 561 old_cg_blktot(cg, 0)[old_cbtocylno(newsb, i)]++;
562 old_cg_blks(newsb, cg, 562 old_cg_blks(newsb, cg,
563 old_cbtocylno(newsb, i), 563 old_cbtocylno(newsb, i),
564 0)[old_cbtorpos(newsb, i)]++; 564 0)[old_cbtorpos(newsb, i)]++;
565 } 565 }
566 566
567 /* Deal with a partial block at the beginning of the post-inode area. 567 /* Deal with a partial block at the beginning of the post-inode area.
568 * I'm not convinced this can happen - I think the inodes are always 568 * I'm not convinced this can happen - I think the inodes are always
569 * block-aligned and always an integral number of blocks - but it's 569 * block-aligned and always an integral number of blocks - but it's
570 * cheap to do the right thing just in case. */ 570 * cheap to do the right thing just in case. */
571 if (dhigh % newsb->fs_frag) { 571 if (dhigh % newsb->fs_frag) {
572 n = newsb->fs_frag - (dhigh % newsb->fs_frag); 572 n = newsb->fs_frag - (dhigh % newsb->fs_frag);
573 cg->cg_frsum[n]++; 573 cg->cg_frsum[n]++;
574 cg->cg_cs.cs_nffree += n; 574 cg->cg_cs.cs_nffree += n;
575 dhigh += n; 575 dhigh += n;
576 } 576 }
577 n = (dmax - dhigh) / newsb->fs_frag; 577 n = (dmax - dhigh) / newsb->fs_frag;
578 /* We have n full-size blocks in the post-inode data area. */ 578 /* We have n full-size blocks in the post-inode data area. */
579 if (n > 0) { 579 if (n > 0) {
580 cg->cg_cs.cs_nbfree += n; 580 cg->cg_cs.cs_nbfree += n;
581 if (newsb->fs_contigsumsize > 0) { 581 if (newsb->fs_contigsumsize > 0) {
582 i = dhigh / newsb->fs_frag; 582 i = dhigh / newsb->fs_frag;
583 set_bits(cg_clustersfree(cg, 0), i, n); 583 set_bits(cg_clustersfree(cg, 0), i, n);
584 cg_clustersum(cg, 0)[(n > newsb->fs_contigsumsize) ? 584 cg_clustersum(cg, 0)[(n > newsb->fs_contigsumsize) ?
585 newsb->fs_contigsumsize : n]++; 585 newsb->fs_contigsumsize : n]++;
586 } 586 }
587 if (is_ufs2 == 0) 587 if (is_ufs2 == 0)
588 for (i = n; i > 0; i--) { 588 for (i = n; i > 0; i--) {
589 old_cg_blktot(cg, 0)[old_cbtocylno(newsb, 589 old_cg_blktot(cg, 0)[old_cbtocylno(newsb,
590 dhigh)]++; 590 dhigh)]++;
591 old_cg_blks(newsb, cg, 591 old_cg_blks(newsb, cg,
592 old_cbtocylno(newsb, dhigh), 592 old_cbtocylno(newsb, dhigh),
593 0)[old_cbtorpos(newsb, 593 0)[old_cbtorpos(newsb,
594 dhigh)]++; 594 dhigh)]++;
595 dhigh += newsb->fs_frag; 595 dhigh += newsb->fs_frag;
596 } 596 }
597 } 597 }
598 if (is_ufs2 == 0) { 598 if (is_ufs2 == 0) {
599 /* Deal with any leftover frag at the end of the cg. */ 599 /* Deal with any leftover frag at the end of the cg. */
600 i = dmax - dhigh; 600 i = dmax - dhigh;
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
628 * the routine used by fragmove() in evict_data()? Can an end-of-file 628 * the routine used by fragmove() in evict_data()? Can an end-of-file
629 * frag legally straddle a block boundary? If not, this should be 629 * frag legally straddle a block boundary? If not, this should be
630 * cloned and fixed to stop at block boundaries for that use. The 630 * cloned and fixed to stop at block boundaries for that use. The
631 * current one may still be needed for csum info motion, in case that 631 * current one may still be needed for csum info motion, in case that
632 * takes up more than a whole block (is the csum info allowed to begin 632 * takes up more than a whole block (is the csum info allowed to begin
633 * partway through a block and continue into the following block?). 633 * partway through a block and continue into the following block?).
634 * 634 *
635 * If we wrap off the end of the file system back to the beginning, we 635 * If we wrap off the end of the file system back to the beginning, we
636 * can end up searching the end of the file system twice. I ignore 636 * can end up searching the end of the file system twice. I ignore
637 * this inefficiency, since if that happens we're going to croak with 637 * this inefficiency, since if that happens we're going to croak with
638 * a no-space error anyway, so it happens at most once. 638 * a no-space error anyway, so it happens at most once.
639 */ 639 */
640static int 640static int
641find_freespace(unsigned int nfrags) 641find_freespace(unsigned int nfrags)
642{ 642{
643 static int hand = 0; /* hand rotates through all frags in the fs */ 643 static int hand = 0; /* hand rotates through all frags in the fs */
644 int cgsize; /* size of the cg hand currently points into */ 644 int cgsize; /* size of the cg hand currently points into */
645 int cgn; /* number of cg hand currently points into */ 645 int cgn; /* number of cg hand currently points into */
646 int fwc; /* frag-within-cg number of frag hand points 646 int fwc; /* frag-within-cg number of frag hand points
647 * to */ 647 * to */
648 unsigned int run; /* length of run of free frags seen so far */ 648 unsigned int run; /* length of run of free frags seen so far */
649 int secondpass; /* have we wrapped from end of fs to 649 int secondpass; /* have we wrapped from end of fs to
650 * beginning? */ 650 * beginning? */
651 unsigned char *bits; /* cg_blksfree()[] for cg hand points into */ 651 unsigned char *bits; /* cg_blksfree()[] for cg hand points into */
652 652
653 cgn = dtog(newsb, hand); 653 cgn = dtog(newsb, hand);
654 fwc = dtogd(newsb, hand); 654 fwc = dtogd(newsb, hand);
655 secondpass = (hand == 0); 655 secondpass = (hand == 0);
656 run = 0; 656 run = 0;
657 bits = cg_blksfree(cgs[cgn], 0); 657 bits = cg_blksfree(cgs[cgn], 0);
658 cgsize = cgs[cgn]->cg_ndblk; 658 cgsize = cgs[cgn]->cg_ndblk;
659 while (1) { 659 while (1) {
660 if (bit_is_set(bits, fwc)) { 660 if (bit_is_set(bits, fwc)) {
661 run++; 661 run++;
662 if (run >= nfrags) 662 if (run >= nfrags)
663 return (hand + 1 - run); 663 return (hand + 1 - run);
664 } else { 664 } else {
665 run = 0; 665 run = 0;
666 } 666 }
667 hand++; 667 hand++;
668 fwc++; 668 fwc++;
669 if (fwc >= cgsize) { 669 if (fwc >= cgsize) {
670 fwc = 0; 670 fwc = 0;
671 cgn++; 671 cgn++;
672 if (cgn >= newsb->fs_ncg) { 672 if (cgn >= newsb->fs_ncg) {
673 hand = 0; 673 hand = 0;
674 if (secondpass) 674 if (secondpass)
675 return (-1); 675 return (-1);
676 secondpass = 1; 676 secondpass = 1;
677 cgn = 0; 677 cgn = 0;
678 } 678 }
679 bits = cg_blksfree(cgs[cgn], 0); 679 bits = cg_blksfree(cgs[cgn], 0);
680 cgsize = cgs[cgn]->cg_ndblk; 680 cgsize = cgs[cgn]->cg_ndblk;
681 run = 0; 681 run = 0;
682 } 682 }
683 } 683 }
684} 684}
685/* 685/*
686 * Find a free block of disk space. Finds an entire block of frags, 686 * Find a free block of disk space. Finds an entire block of frags,
687 * all of which are free. Return value is the frag number of the 687 * all of which are free. Return value is the frag number of the
688 * first frag of the block, or -1 if no space was found. Uses newsb 688 * first frag of the block, or -1 if no space was found. Uses newsb
689 * for sb values, and assumes the cgs[] structures correctly describe 689 * for sb values, and assumes the cgs[] structures correctly describe
690 * the area to be searched. 690 * the area to be searched.
691 * 691 *
692 * See find_freespace(), above, for remarks about hand wrapping around. 692 * See find_freespace(), above, for remarks about hand wrapping around.
693 */ 693 */
694static int 694static int
695find_freeblock(void) 695find_freeblock(void)
696{ 696{
697 static int hand = 0; /* hand rotates through all frags in fs */ 697 static int hand = 0; /* hand rotates through all frags in fs */
698 int cgn; /* cg number of cg hand points into */ 698 int cgn; /* cg number of cg hand points into */
699 int fwc; /* frag-within-cg number of frag hand points 699 int fwc; /* frag-within-cg number of frag hand points
700 * to */ 700 * to */
701 int cgsize; /* size of cg hand points into */ 701 int cgsize; /* size of cg hand points into */
702 int secondpass; /* have we wrapped from end to beginning? */ 702 int secondpass; /* have we wrapped from end to beginning? */
703 unsigned char *bits; /* cg_blksfree()[] for cg hand points into */ 703 unsigned char *bits; /* cg_blksfree()[] for cg hand points into */
704 704
705 cgn = dtog(newsb, hand); 705 cgn = dtog(newsb, hand);
706 fwc = dtogd(newsb, hand); 706 fwc = dtogd(newsb, hand);
707 secondpass = (hand == 0); 707 secondpass = (hand == 0);
708 bits = cg_blksfree(cgs[cgn], 0); 708 bits = cg_blksfree(cgs[cgn], 0);
709 cgsize = blknum(newsb, cgs[cgn]->cg_ndblk); 709 cgsize = blknum(newsb, cgs[cgn]->cg_ndblk);
710 while (1) { 710 while (1) {
711 if (blk_is_set(bits, fwc, newsb->fs_frag)) 711 if (blk_is_set(bits, fwc, newsb->fs_frag))
712 return (hand); 712 return (hand);
713 fwc += newsb->fs_frag; 713 fwc += newsb->fs_frag;
714 hand += newsb->fs_frag; 714 hand += newsb->fs_frag;
715 if (fwc >= cgsize) { 715 if (fwc >= cgsize) {
716 fwc = 0; 716 fwc = 0;
717 cgn++; 717 cgn++;
718 if (cgn >= newsb->fs_ncg) { 718 if (cgn >= newsb->fs_ncg) {
719 hand = 0; 719 hand = 0;
720 if (secondpass) 720 if (secondpass)
721 return (-1); 721 return (-1);
722 secondpass = 1; 722 secondpass = 1;
723 cgn = 0; 723 cgn = 0;
724 } 724 }
725 bits = cg_blksfree(cgs[cgn], 0); 725 bits = cg_blksfree(cgs[cgn], 0);
726 cgsize = blknum(newsb, cgs[cgn]->cg_ndblk); 726 cgsize = blknum(newsb, cgs[cgn]->cg_ndblk);
727 } 727 }
728 } 728 }
729} 729}
730/* 730/*
731 * Find a free inode, returning its inumber or -1 if none was found. 731 * Find a free inode, returning its inumber or -1 if none was found.
732 * Uses newsb for sb values, and assumes the cgs[] structures 732 * Uses newsb for sb values, and assumes the cgs[] structures
733 * correctly describe the area to be searched. 733 * correctly describe the area to be searched.
734 * 734 *
735 * See find_freespace(), above, for remarks about hand wrapping around. 735 * See find_freespace(), above, for remarks about hand wrapping around.
736 */ 736 */
737static int 737static int
738find_freeinode(void) 738find_freeinode(void)
739{ 739{
740 static int hand = 0; /* hand rotates through all inodes in fs */ 740 static int hand = 0; /* hand rotates through all inodes in fs */
741 int cgn; /* cg number of cg hand points into */ 741 int cgn; /* cg number of cg hand points into */
742 int iwc; /* inode-within-cg number of inode hand points 742 int iwc; /* inode-within-cg number of inode hand points
743 * to */ 743 * to */
744 int secondpass; /* have we wrapped from end to beginning? */ 744 int secondpass; /* have we wrapped from end to beginning? */
745 unsigned char *bits; /* cg_inosused()[] for cg hand points into */ 745 unsigned char *bits; /* cg_inosused()[] for cg hand points into */
746 746
747 cgn = hand / newsb->fs_ipg; 747 cgn = hand / newsb->fs_ipg;
748 iwc = hand % newsb->fs_ipg; 748 iwc = hand % newsb->fs_ipg;
749 secondpass = (hand == 0); 749 secondpass = (hand == 0);
750 bits = cg_inosused(cgs[cgn], 0); 750 bits = cg_inosused(cgs[cgn], 0);
751 while (1) { 751 while (1) {
752 if (bit_is_clr(bits, iwc)) 752 if (bit_is_clr(bits, iwc))
753 return (hand); 753 return (hand);
754 hand++; 754 hand++;
755 iwc++; 755 iwc++;
756 if (iwc >= newsb->fs_ipg) { 756 if (iwc >= newsb->fs_ipg) {
757 iwc = 0; 757 iwc = 0;
758 cgn++; 758 cgn++;
759 if (cgn >= newsb->fs_ncg) { 759 if (cgn >= newsb->fs_ncg) {
760 hand = 0; 760 hand = 0;
761 if (secondpass) 761 if (secondpass)
762 return (-1); 762 return (-1);
763 secondpass = 1; 763 secondpass = 1;
764 cgn = 0; 764 cgn = 0;
765 } 765 }
766 bits = cg_inosused(cgs[cgn], 0); 766 bits = cg_inosused(cgs[cgn], 0);
767 } 767 }
768 } 768 }
769} 769}
770/* 770/*
771 * Mark a frag as free. Sets the frag's bit in the cg_blksfree bitmap 771 * Mark a frag as free. Sets the frag's bit in the cg_blksfree bitmap
772 * for the appropriate cg, and marks the cg as dirty. 772 * for the appropriate cg, and marks the cg as dirty.
773 */ 773 */
774static void 774static void
775free_frag(int fno) 775free_frag(int fno)
776{ 776{
777 int cgn; 777 int cgn;
778 778
779 cgn = dtog(newsb, fno); 779 cgn = dtog(newsb, fno);
780 set_bits(cg_blksfree(cgs[cgn], 0), dtogd(newsb, fno), 1); 780 set_bits(cg_blksfree(cgs[cgn], 0), dtogd(newsb, fno), 1);
781 cgflags[cgn] |= CGF_DIRTY | CGF_BLKMAPS; 781 cgflags[cgn] |= CGF_DIRTY | CGF_BLKMAPS;
782} 782}
783/* 783/*
784 * Allocate a frag. Clears the frag's bit in the cg_blksfree bitmap 784 * Allocate a frag. Clears the frag's bit in the cg_blksfree bitmap
785 * for the appropriate cg, and marks the cg as dirty. 785 * for the appropriate cg, and marks the cg as dirty.
786 */ 786 */
787static void 787static void
788alloc_frag(int fno) 788alloc_frag(int fno)
789{ 789{
790 int cgn; 790 int cgn;
791 791
792 cgn = dtog(newsb, fno); 792 cgn = dtog(newsb, fno);
793 clr_bits(cg_blksfree(cgs[cgn], 0), dtogd(newsb, fno), 1); 793 clr_bits(cg_blksfree(cgs[cgn], 0), dtogd(newsb, fno), 1);
794 cgflags[cgn] |= CGF_DIRTY | CGF_BLKMAPS; 794 cgflags[cgn] |= CGF_DIRTY | CGF_BLKMAPS;
795} 795}
796/* 796/*
797 * Fix up the csum array. If shrinking, this involves freeing zero or 797 * Fix up the csum array. If shrinking, this involves freeing zero or
798 * more frags; if growing, it involves allocating them, or if the 798 * more frags; if growing, it involves allocating them, or if the
799 * frags being grown into aren't free, finding space elsewhere for the 799 * frags being grown into aren't free, finding space elsewhere for the
800 * csum info. (If the number of occupied frags doesn't change, 800 * csum info. (If the number of occupied frags doesn't change,
801 * nothing happens here.) 801 * nothing happens here.)
802 */ 802 */
803static void 803static void
804csum_fixup(void) 804csum_fixup(void)
805{ 805{
806 int nold; /* # frags in old csum info */ 806 int nold; /* # frags in old csum info */
807 int ntot; /* # frags in new csum info */ 807 int ntot; /* # frags in new csum info */
808 int nnew; /* ntot-nold */ 808 int nnew; /* ntot-nold */
809 int newloc; /* new location for csum info, if necessary */ 809 int newloc; /* new location for csum info, if necessary */
810 int i; /* generic loop index */ 810 int i; /* generic loop index */
811 int j; /* generic loop index */ 811 int j; /* generic loop index */
812 int f; /* "from" frag number, if moving */ 812 int f; /* "from" frag number, if moving */
813 int t; /* "to" frag number, if moving */ 813 int t; /* "to" frag number, if moving */
814 int cgn; /* cg number, used when shrinking */ 814 int cgn; /* cg number, used when shrinking */
815 815
816 ntot = howmany(newsb->fs_cssize, newsb->fs_fsize); 816 ntot = howmany(newsb->fs_cssize, newsb->fs_fsize);
817 nold = howmany(oldsb->fs_cssize, newsb->fs_fsize); 817 nold = howmany(oldsb->fs_cssize, newsb->fs_fsize);
818 nnew = ntot - nold; 818 nnew = ntot - nold;
819 /* First, if there's no change in frag counts, it's easy. */ 819 /* First, if there's no change in frag counts, it's easy. */
820 if (nnew == 0) 820 if (nnew == 0)
821 return; 821 return;
822 /* Next, if we're shrinking, it's almost as easy. Just free up any 822 /* Next, if we're shrinking, it's almost as easy. Just free up any
823 * frags in the old area we no longer need. */ 823 * frags in the old area we no longer need. */
824 if (nnew < 0) { 824 if (nnew < 0) {
825 for ((i = newsb->fs_csaddr + ntot - 1), (j = nnew); 825 for ((i = newsb->fs_csaddr + ntot - 1), (j = nnew);
826 j < 0; 826 j < 0;
827 i--, j++) { 827 i--, j++) {
828 free_frag(i); 828 free_frag(i);
829 } 829 }
830 return; 830 return;
831 } 831 }
832 /* We must be growing. Check to see that the new csum area fits 832 /* We must be growing. Check to see that the new csum area fits
833 * within the file system. I think this can never happen, since for 833 * within the file system. I think this can never happen, since for
834 * the csum area to grow, we must be adding at least one cg, so the 834 * the csum area to grow, we must be adding at least one cg, so the
835 * old csum area can't be this close to the end of the new file system. 835 * old csum area can't be this close to the end of the new file system.
836 * But it's a cheap check. */ 836 * But it's a cheap check. */
837 /* XXX what if csum info is at end of cg and grows into next cg, what 837 /* XXX what if csum info is at end of cg and grows into next cg, what
838 * if it spills over onto the next cg's backup superblock? Can this 838 * if it spills over onto the next cg's backup superblock? Can this
839 * happen? */ 839 * happen? */
840 if (newsb->fs_csaddr + ntot <= newsb->fs_size) { 840 if (newsb->fs_csaddr + ntot <= newsb->fs_size) {
841 /* Okay, it fits - now, see if the space we want is free. */ 841 /* Okay, it fits - now, see if the space we want is free. */
842 for ((i = newsb->fs_csaddr + nold), (j = nnew); 842 for ((i = newsb->fs_csaddr + nold), (j = nnew);
843 j > 0; 843 j > 0;
844 i++, j--) { 844 i++, j--) {
845 cgn = dtog(newsb, i); 845 cgn = dtog(newsb, i);
846 if (bit_is_clr(cg_blksfree(cgs[cgn], 0), 846 if (bit_is_clr(cg_blksfree(cgs[cgn], 0),
847 dtogd(newsb, i))) 847 dtogd(newsb, i)))
848 break; 848 break;
849 } 849 }
850 if (j <= 0) { 850 if (j <= 0) {
851 /* Win win - all the frags we want are free. Allocate 851 /* Win win - all the frags we want are free. Allocate
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 */
881static void 879static void
882recompute_fs_dsize(void) 880recompute_fs_dsize(void)
883{ 881{
884 int i; 882 int i;
885 883
886 newsb->fs_dsize = 0; 884 newsb->fs_dsize = 0;
887 for (i = 0; i < newsb->fs_ncg; i++) { 885 for (i = 0; i < newsb->fs_ncg; i++) {
888 int dlow; /* size of before-sb data area */ 886 int dlow; /* size of before-sb data area */
889 int dhigh; /* offset of post-inode data area */ 887 int dhigh; /* offset of post-inode data area */
890 int dmax; /* total size of cg */ 888 int dmax; /* total size of cg */
891 int base; /* base of cg, since cgsblock() etc add it in */ 889 int base; /* base of cg, since cgsblock() etc add it in */
892 base = cgbase(newsb, i); 890 base = cgbase(newsb, i);
893 dlow = cgsblock(newsb, i) - base; 891 dlow = cgsblock(newsb, i) - base;
894 dhigh = cgdmin(newsb, i) - base; 892 dhigh = cgdmin(newsb, i) - base;
895 dmax = newsb->fs_size - base; 893 dmax = newsb->fs_size - base;
896 if (dmax > newsb->fs_fpg) 894 if (dmax > newsb->fs_fpg)
897 dmax = newsb->fs_fpg; 895 dmax = newsb->fs_fpg;
898 newsb->fs_dsize += dlow + dmax - dhigh; 896 newsb->fs_dsize += dlow + dmax - dhigh;
899 } 897 }
900 /* Space in cg 0 before cgsblock is boot area, not free space! */ 898 /* Space in cg 0 before cgsblock is boot area, not free space! */
901 newsb->fs_dsize -= cgsblock(newsb, 0) - cgbase(newsb, 0); 899 newsb->fs_dsize -= cgsblock(newsb, 0) - cgbase(newsb, 0);
902 /* And of course the csum info takes up space. */ 900 /* And of course the csum info takes up space. */
903 newsb->fs_dsize -= howmany(newsb->fs_cssize, newsb->fs_fsize); 901 newsb->fs_dsize -= howmany(newsb->fs_cssize, newsb->fs_fsize);
904} 902}
905/* 903/*
906 * Return the current time. We call this and assign, rather than 904 * Return the current time. We call this and assign, rather than
907 * calling time() directly, as insulation against OSes where fs_time 905 * calling time() directly, as insulation against OSes where fs_time
908 * is not a time_t. 906 * is not a time_t.
909 */ 907 */
910static time_t 908static time_t
911timestamp(void) 909timestamp(void)
912{ 910{
913 time_t t; 911 time_t t;
914 912
915 time(&t); 913 time(&t);
916 return (t); 914 return (t);
917} 915}
918/* 916/*
919 * Grow the file system. 917 * Grow the file system.
920 */ 918 */
921static void 919static void
922grow(void) 920grow(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. */
952 newsb->fs_old_ncyl = howmany(newsb->fs_size * NSPF(newsb), 949 newsb->fs_old_ncyl = howmany(newsb->fs_size * NSPF(newsb),
953 newsb->fs_old_spc); 950 newsb->fs_old_spc);
954 newsb->fs_ncg = howmany(newsb->fs_old_ncyl, newsb->fs_old_cpg); 951 newsb->fs_ncg = howmany(newsb->fs_old_ncyl, newsb->fs_old_cpg);
955 } 952 }
956 953
957 /* Does the last cg end before the end of its inode area? There is no 954 /* Does the last cg end before the end of its inode area? There is no
958 * reason why this couldn't be handled, but it would complicate a lot 955 * reason why this couldn't be handled, but it would complicate a lot
959 * of code (in all file system code - fsck, kernel, etc) because of the 956 * of code (in all file system code - fsck, kernel, etc) because of the
960 * potential partial inode area, and the gain in space would be 957 * potential partial inode area, and the gain in space would be
961 * minimal, at most the pre-sb data area. */ 958 * minimal, at most the pre-sb data area. */
962 if (cgdmin(newsb, newsb->fs_ncg - 1) > newsb->fs_size) { 959 if (cgdmin(newsb, newsb->fs_ncg - 1) > newsb->fs_size) {
963 newsb->fs_ncg--; 960 newsb->fs_ncg--;
964 newsb->fs_old_ncyl = newsb->fs_ncg * newsb->fs_old_cpg; 961 newsb->fs_old_ncyl = newsb->fs_ncg * newsb->fs_old_cpg;
965 newsb->fs_size = (newsb->fs_old_ncyl * newsb->fs_old_spc) 962 newsb->fs_size = (newsb->fs_old_ncyl * newsb->fs_old_spc)
966 / NSPF(newsb); 963 / NSPF(newsb);
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;
994 } 991 }
995 /* If the old fs ended partway through a cg, we have to update the old 992 /* If the old fs ended partway through a cg, we have to update the old
996 * last cg (though possibly not to a full cg!). */ 993 * last cg (though possibly not to a full cg!). */
997 if (oldsb->fs_size % oldsb->fs_fpg) { 994 if (oldsb->fs_size % oldsb->fs_fpg) {
998 struct cg *cg; 995 struct cg *cg;
999 int newcgsize; 996 int newcgsize;
1000 int prevcgtop; 997 int prevcgtop;
1001 int oldcgsize; 998 int oldcgsize;
1002 cg = cgs[oldsb->fs_ncg - 1]; 999 cg = cgs[oldsb->fs_ncg - 1];
1003 cgflags[oldsb->fs_ncg - 1] |= CGF_DIRTY | CGF_BLKMAPS; 1000 cgflags[oldsb->fs_ncg - 1] |= CGF_DIRTY | CGF_BLKMAPS;
1004 prevcgtop = oldsb->fs_fpg * (oldsb->fs_ncg - 1); 1001 prevcgtop = oldsb->fs_fpg * (oldsb->fs_ncg - 1);
1005 newcgsize = newsb->fs_size - prevcgtop; 1002 newcgsize = newsb->fs_size - prevcgtop;
1006 if (newcgsize > newsb->fs_fpg) 1003 if (newcgsize > newsb->fs_fpg)
1007 newcgsize = newsb->fs_fpg; 1004 newcgsize = newsb->fs_fpg;
1008 oldcgsize = oldsb->fs_size % oldsb->fs_fpg; 1005 oldcgsize = oldsb->fs_size % oldsb->fs_fpg;
1009 set_bits(cg_blksfree(cg, 0), oldcgsize, newcgsize - oldcgsize); 1006 set_bits(cg_blksfree(cg, 0), oldcgsize, newcgsize - oldcgsize);
1010 cg->cg_old_ncyl = oldsb->fs_old_cpg; 1007 cg->cg_old_ncyl = oldsb->fs_old_cpg;
1011 cg->cg_ndblk = newcgsize; 1008 cg->cg_ndblk = newcgsize;
1012 } 1009 }
1013 /* Fix up the csum info, if necessary. */ 1010 /* Fix up the csum info, if necessary. */
1014 csum_fixup(); 1011 csum_fixup();
1015 /* Make fs_dsize match the new reality. */ 1012 /* Make fs_dsize match the new reality. */
1016 recompute_fs_dsize(); 1013 recompute_fs_dsize();
1017} 1014}
1018/* 1015/*
1019 * Call (*fn)() for each inode, passing the inode and its inumber. The 1016 * Call (*fn)() for each inode, passing the inode and its inumber. The
1020 * number of cylinder groups is pased in, so this can be used to map 1017 * number of cylinder groups is pased in, so this can be used to map
1021 * over either the old or the new file system's set of inodes. 1018 * over either the old or the new file system's set of inodes.
1022 */ 1019 */
1023static void 1020static void
1024map_inodes(void (*fn) (union dinode * di, unsigned int, void *arg), 1021map_inodes(void (*fn) (union dinode * di, unsigned int, void *arg),
1025 int ncg, void *cbarg) { 1022 int ncg, void *cbarg) {
1026 int i; 1023 int i;
1027 int ni; 1024 int ni;
1028 1025
1029 ni = oldsb->fs_ipg * ncg; 1026 ni = oldsb->fs_ipg * ncg;
1030 for (i = 0; i < ni; i++) 1027 for (i = 0; i < ni; i++)
1031 (*fn) (inodes + i, i, cbarg); 1028 (*fn) (inodes + i, i, cbarg);
1032} 1029}
1033/* Values for the third argument to the map function for 1030/* Values for the third argument to the map function for
1034 * map_inode_data_blocks. MDB_DATA indicates the block is contains 1031 * map_inode_data_blocks. MDB_DATA indicates the block is contains
1035 * file data; MDB_INDIR_PRE and MDB_INDIR_POST indicate that it's an 1032 * file data; MDB_INDIR_PRE and MDB_INDIR_POST indicate that it's an
1036 * indirect block. The MDB_INDIR_PRE call is made before the indirect 1033 * indirect block. The MDB_INDIR_PRE call is made before the indirect
1037 * block pointers are followed and the pointed-to blocks scanned, 1034 * block pointers are followed and the pointed-to blocks scanned,
1038 * MDB_INDIR_POST after. 1035 * MDB_INDIR_POST after.
1039 */ 1036 */
1040#define MDB_DATA 1 1037#define MDB_DATA 1
1041#define MDB_INDIR_PRE 2 1038#define MDB_INDIR_PRE 2
1042#define MDB_INDIR_POST 3 1039#define MDB_INDIR_POST 3
1043 1040
1044typedef void (*mark_callback_t) (off_t blocknum, unsigned int nfrags, 1041typedef void (*mark_callback_t) (off_t blocknum, unsigned int nfrags,
1045 unsigned int blksize, int opcode); 1042 unsigned int blksize, int opcode);
1046 1043
1047/* Helper function - handles a data block. Calls the callback 1044/* Helper function - handles a data block. Calls the callback
1048 * function and returns number of bytes occupied in file (actually, 1045 * function and returns number of bytes occupied in file (actually,
1049 * rounded up to a frag boundary). The name is historical. */ 1046 * rounded up to a frag boundary). The name is historical. */
1050static int 1047static int
1051markblk(mark_callback_t fn, union dinode * di, off_t bn, off_t o) 1048markblk(mark_callback_t fn, union dinode * di, off_t bn, off_t o)
1052{ 1049{
1053 int sz; 1050 int sz;
1054 int nb; 1051 int nb;
1055 off_t filesize; 1052 off_t filesize;
1056 1053
1057 filesize = DIP(di,di_size); 1054 filesize = DIP(di,di_size);
1058 if (o >= filesize) 1055 if (o >= filesize)
1059 return (0); 1056 return (0);
1060 sz = dblksize(newsb, di, lblkno(newsb, o), filesize); 1057 sz = dblksize(newsb, di, lblkno(newsb, o), filesize);
1061 nb = (sz > filesize - o) ? filesize - o : sz; 1058 nb = (sz > filesize - o) ? filesize - o : sz;
1062 if (bn) 1059 if (bn)
1063 (*fn) (bn, numfrags(newsb, sz), nb, MDB_DATA); 1060 (*fn) (bn, numfrags(newsb, sz), nb, MDB_DATA);
1064 return (sz); 1061 return (sz);
1065} 1062}
1066/* Helper function - handles an indirect block. Makes the 1063/* Helper function - handles an indirect block. Makes the
1067 * MDB_INDIR_PRE callback for the indirect block, loops over the 1064 * MDB_INDIR_PRE callback for the indirect block, loops over the
1068 * pointers and recurses, and makes the MDB_INDIR_POST callback. 1065 * pointers and recurses, and makes the MDB_INDIR_POST callback.
1069 * Returns the number of bytes occupied in file, as does markblk(). 1066 * Returns the number of bytes occupied in file, as does markblk().
1070 * For the sake of update_for_data_move(), we read the indirect block 1067 * For the sake of update_for_data_move(), we read the indirect block
1071 * _after_ making the _PRE callback. The name is historical. */ 1068 * _after_ making the _PRE callback. The name is historical. */
1072static int 1069static int
1073markiblk(mark_callback_t fn, union dinode * di, off_t bn, off_t o, int lev) 1070markiblk(mark_callback_t fn, union dinode * di, off_t bn, off_t o, int lev)
1074{ 1071{
1075 int i; 1072 int i;
1076 int j; 1073 int j;
1077 unsigned k; 1074 unsigned k;
1078 int tot; 1075 int tot;
1079 static int32_t indirblk1[howmany(MAXBSIZE, sizeof(int32_t))]; 1076 static int32_t indirblk1[howmany(MAXBSIZE, sizeof(int32_t))];
1080 static int32_t indirblk2[howmany(MAXBSIZE, sizeof(int32_t))]; 1077 static int32_t indirblk2[howmany(MAXBSIZE, sizeof(int32_t))];
1081 static int32_t indirblk3[howmany(MAXBSIZE, sizeof(int32_t))]; 1078 static int32_t indirblk3[howmany(MAXBSIZE, sizeof(int32_t))];
1082 static int32_t *indirblks[3] = { 1079 static int32_t *indirblks[3] = {
1083 &indirblk1[0], &indirblk2[0], &indirblk3[0] 1080 &indirblk1[0], &indirblk2[0], &indirblk3[0]
1084 }; 1081 };
1085 1082
1086 if (lev < 0) 1083 if (lev < 0)
1087 return (markblk(fn, di, bn, o)); 1084 return (markblk(fn, di, bn, o));
1088 if (bn == 0) { 1085 if (bn == 0) {
1089 for (i = newsb->fs_bsize; 1086 for (i = newsb->fs_bsize;
1090 lev >= 0; 1087 lev >= 0;
1091 i *= NINDIR(newsb), lev--); 1088 i *= NINDIR(newsb), lev--);
1092 return (i); 1089 return (i);
1093 } 1090 }
1094 (*fn) (bn, newsb->fs_frag, newsb->fs_bsize, MDB_INDIR_PRE); 1091 (*fn) (bn, newsb->fs_frag, newsb->fs_bsize, MDB_INDIR_PRE);
1095 readat(fsbtodb(newsb, bn), indirblks[lev], newsb->fs_bsize); 1092 readat(fsbtodb(newsb, bn), indirblks[lev], newsb->fs_bsize);
1096 if (needswap) 1093 if (needswap)
1097 for (k = 0; k < howmany(MAXBSIZE, sizeof(int32_t)); k++) 1094 for (k = 0; k < howmany(MAXBSIZE, sizeof(int32_t)); k++)
1098 indirblks[lev][k] = bswap32(indirblks[lev][k]); 1095 indirblks[lev][k] = bswap32(indirblks[lev][k]);
1099 tot = 0; 1096 tot = 0;
1100 for (i = 0; i < NINDIR(newsb); i++) { 1097 for (i = 0; i < NINDIR(newsb); i++) {
1101 j = markiblk(fn, di, indirblks[lev][i], o, lev - 1); 1098 j = markiblk(fn, di, indirblks[lev][i], o, lev - 1);
1102 if (j == 0) 1099 if (j == 0)
1103 break; 1100 break;
1104 o += j; 1101 o += j;
1105 tot += j; 1102 tot += j;
1106 } 1103 }
1107 (*fn) (bn, newsb->fs_frag, newsb->fs_bsize, MDB_INDIR_POST); 1104 (*fn) (bn, newsb->fs_frag, newsb->fs_bsize, MDB_INDIR_POST);
1108 return (tot); 1105 return (tot);
1109} 1106}
1110 1107
1111 1108
1112/* 1109/*
1113 * Call (*fn)() for each data block for an inode. This routine assumes 1110 * Call (*fn)() for each data block for an inode. This routine assumes
1114 * the inode is known to be of a type that has data blocks (file, 1111 * the inode is known to be of a type that has data blocks (file,
1115 * directory, or non-fast symlink). The called function is: 1112 * directory, or non-fast symlink). The called function is:
1116 * 1113 *
1117 * (*fn)(unsigned int blkno, unsigned int nf, unsigned int nb, int op) 1114 * (*fn)(unsigned int blkno, unsigned int nf, unsigned int nb, int op)
1118 * 1115 *
1119 * where blkno is the frag number, nf is the number of frags starting 1116 * where blkno is the frag number, nf is the number of frags starting
1120 * at blkno (always <= fs_frag), nb is the number of bytes that belong 1117 * at blkno (always <= fs_frag), nb is the number of bytes that belong
1121 * to the file (usually nf*fs_frag, often less for the last block/frag 1118 * to the file (usually nf*fs_frag, often less for the last block/frag
1122 * of a file). 1119 * of a file).
1123 */ 1120 */
1124static void 1121static void
1125map_inode_data_blocks(union dinode * di, mark_callback_t fn) 1122map_inode_data_blocks(union dinode * di, mark_callback_t fn)
1126{ 1123{
1127 off_t o; /* offset within inode */ 1124 off_t o; /* offset within inode */
1128 int inc; /* increment for o - maybe should be off_t? */ 1125 int inc; /* increment for o - maybe should be off_t? */
1129 int b; /* index within di_db[] and di_ib[] arrays */ 1126 int b; /* index within di_db[] and di_ib[] arrays */
1130 1127
1131 /* Scan the direct blocks... */ 1128 /* Scan the direct blocks... */
1132 o = 0; 1129 o = 0;
1133 for (b = 0; b < NDADDR; b++) { 1130 for (b = 0; b < NDADDR; b++) {
1134 inc = markblk(fn, di, DIP(di,di_db[b]), o); 1131 inc = markblk(fn, di, DIP(di,di_db[b]), o);
1135 if (inc == 0) 1132 if (inc == 0)
1136 break; 1133 break;
1137 o += inc; 1134 o += inc;
1138 } 1135 }
1139 /* ...and the indirect blocks. */ 1136 /* ...and the indirect blocks. */
1140 if (inc) { 1137 if (inc) {
1141 for (b = 0; b < NIADDR; b++) { 1138 for (b = 0; b < NIADDR; b++) {
1142 inc = markiblk(fn, di, DIP(di,di_ib[b]), o, b); 1139 inc = markiblk(fn, di, DIP(di,di_ib[b]), o, b);
1143 if (inc == 0) 1140 if (inc == 0)
1144 return; 1141 return;
1145 o += inc; 1142 o += inc;
1146 } 1143 }
1147 } 1144 }
1148} 1145}
1149 1146
1150static void 1147static void
1151dblk_callback(union dinode * di, unsigned int inum, void *arg) 1148dblk_callback(union dinode * di, unsigned int inum, void *arg)
1152{ 1149{
1153 mark_callback_t fn; 1150 mark_callback_t fn;
1154 off_t filesize; 1151 off_t filesize;
1155 1152
1156 filesize = DIP(di,di_size); 1153 filesize = DIP(di,di_size);
1157 fn = (mark_callback_t) arg; 1154 fn = (mark_callback_t) arg;
1158 switch (DIP(di,di_mode) & IFMT) { 1155 switch (DIP(di,di_mode) & IFMT) {
1159 case IFLNK: 1156 case IFLNK:
1160 if (filesize <= newsb->fs_maxsymlinklen) { 1157 if (filesize <= newsb->fs_maxsymlinklen) {
1161 break; 1158 break;
1162 } 1159 }
1163 /* FALLTHROUGH */ 1160 /* FALLTHROUGH */
1164 case IFDIR: 1161 case IFDIR:
1165 case IFREG: 1162 case IFREG:
1166 map_inode_data_blocks(di, fn); 1163 map_inode_data_blocks(di, fn);
1167 break; 1164 break;
1168 } 1165 }
1169} 1166}
1170/* 1167/*
1171 * Make a callback call, a la map_inode_data_blocks, for all data 1168 * Make a callback call, a la map_inode_data_blocks, for all data
1172 * blocks in the entire fs. This is used only once, in 1169 * blocks in the entire fs. This is used only once, in
1173 * update_for_data_move, but it's out at top level because the complex 1170 * update_for_data_move, but it's out at top level because the complex
1174 * downward-funarg nesting that would otherwise result seems to give 1171 * downward-funarg nesting that would otherwise result seems to give
1175 * gcc gastric distress. 1172 * gcc gastric distress.
1176 */ 1173 */
1177static void 1174static void
1178map_data_blocks(mark_callback_t fn, int ncg) 1175map_data_blocks(mark_callback_t fn, int ncg)
1179{ 1176{
1180 map_inodes(&dblk_callback, ncg, (void *) fn); 1177 map_inodes(&dblk_callback, ncg, (void *) fn);
1181} 1178}
1182/* 1179/*
1183 * Initialize the blkmove array. 1180 * Initialize the blkmove array.
1184 */ 1181 */
1185static void 1182static void
1186blkmove_init(void) 1183blkmove_init(void)
1187{ 1184{
1188 int i; 1185 int i;
1189 1186
1190 blkmove = alloconce(oldsb->fs_size * sizeof(*blkmove), "blkmove"); 1187 blkmove = alloconce(oldsb->fs_size * sizeof(*blkmove), "blkmove");
1191 for (i = 0; i < oldsb->fs_size; i++) 1188 for (i = 0; i < oldsb->fs_size; i++)
1192 blkmove[i] = i; 1189 blkmove[i] = i;
1193} 1190}
1194/* 1191/*
1195 * Load the inodes off disk. Allocates the structures and initializes 1192 * Load the inodes off disk. Allocates the structures and initializes
1196 * them - the inodes from disk, the flags to zero. 1193 * them - the inodes from disk, the flags to zero.
1197 */ 1194 */
1198static void 1195static void
1199loadinodes(void) 1196loadinodes(void)
1200{ 1197{
1201 int imax, ino, i, j; 1198 int imax, ino, i, j;
1202 struct ufs1_dinode *dp1 = NULL; 1199 struct ufs1_dinode *dp1 = NULL;
1203 struct ufs2_dinode *dp2 = NULL; 1200 struct ufs2_dinode *dp2 = NULL;
1204 1201
1205 /* read inodes one fs block at a time and copy them */ 1202 /* read inodes one fs block at a time and copy them */
1206 1203
1207 inodes = alloconce(oldsb->fs_ncg * oldsb->fs_ipg * 1204 inodes = alloconce(oldsb->fs_ncg * oldsb->fs_ipg *
1208 sizeof(union dinode), "inodes"); 1205 sizeof(union dinode), "inodes");
1209 iflags = alloconce(oldsb->fs_ncg * oldsb->fs_ipg, "inode flags"); 1206 iflags = alloconce(oldsb->fs_ncg * oldsb->fs_ipg, "inode flags");
1210 memset(iflags, 0, oldsb->fs_ncg * oldsb->fs_ipg); 1207 memset(iflags, 0, oldsb->fs_ncg * oldsb->fs_ipg);
1211 1208
1212 ibuf = nfmalloc(oldsb->fs_bsize,"inode block buf"); 1209 ibuf = nfmalloc(oldsb->fs_bsize,"inode block buf");
1213 if (is_ufs2) 1210 if (is_ufs2)
1214 dp2 = (struct ufs2_dinode *)ibuf; 1211 dp2 = (struct ufs2_dinode *)ibuf;
1215 else 1212 else
1216 dp1 = (struct ufs1_dinode *)ibuf; 1213 dp1 = (struct ufs1_dinode *)ibuf;
1217 1214
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 */
1252static void 1249__dead static void
1253toofull(void) 1250toofull(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 */
1261static void 1257static void
1262mark_move(unsigned int from, unsigned int to, unsigned int n) 1258mark_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.
1270 */ 1266 */
1271static void 1267static void
1272fragmove(struct cg * cg, int base, unsigned int start, unsigned int n) 1268fragmove(struct cg * cg, int base, unsigned int start, unsigned int n)
1273{ 1269{
1274 unsigned int i; 1270 unsigned int i;
1275 int run; 1271 int run;
1276 1272
1277 run = 0; 1273 run = 0;
1278 for (i = 0; i <= n; i++) { 1274 for (i = 0; i <= n; i++) {
1279 if ((i < n) && bit_is_clr(cg_blksfree(cg, 0), start + i)) { 1275 if ((i < n) && bit_is_clr(cg_blksfree(cg, 0), start + i)) {
1280 run++; 1276 run++;
1281 } else { 1277 } else {
1282 if (run > 0) { 1278 if (run > 0) {
1283 int off; 1279 int off;
1284 off = find_freespace(run); 1280 off = find_freespace(run);
1285 if (off < 0) 1281 if (off < 0)
1286 toofull(); 1282 toofull();
1287 mark_move(base + start + i - run, off, run); 1283 mark_move(base + start + i - run, off, run);
1288 set_bits(cg_blksfree(cg, 0), start + i - run, 1284 set_bits(cg_blksfree(cg, 0), start + i - run,
1289 run); 1285 run);
1290 clr_bits(cg_blksfree(cgs[dtog(oldsb, off)], 0), 1286 clr_bits(cg_blksfree(cgs[dtog(oldsb, off)], 0),
1291 dtogd(oldsb, off), run); 1287 dtogd(oldsb, off), run);
1292 } 1288 }
1293 run = 0; 1289 run = 0;
1294 } 1290 }
1295 } 1291 }
1296} 1292}
1297/* 1293/*
1298 * Evict all data blocks from the given cg, starting at minfrag (based 1294 * Evict all data blocks from the given cg, starting at minfrag (based
1299 * at the beginning of the cg), for length nfrag. The eviction is 1295 * at the beginning of the cg), for length nfrag. The eviction is
1300 * assumed to be entirely data-area; this should not be called with a 1296 * assumed to be entirely data-area; this should not be called with a
1301 * range overlapping the metadata structures in the cg. It also 1297 * range overlapping the metadata structures in the cg. It also
1302 * assumes minfrag points into the given cg; it will misbehave if this 1298 * assumes minfrag points into the given cg; it will misbehave if this
1303 * is not true. 1299 * is not true.
1304 * 1300 *
1305 * See the comment header on find_freespace() for one possible bug 1301 * See the comment header on find_freespace() for one possible bug
1306 * lurking here. 1302 * lurking here.
1307 */ 1303 */
1308static void 1304static void
1309evict_data(struct cg * cg, unsigned int minfrag, int nfrag) 1305evict_data(struct cg * cg, unsigned int minfrag, int nfrag)
1310{ 1306{
1311 int base; /* base of cg (in frags from beginning of fs) */ 1307 int base; /* base of cg (in frags from beginning of fs) */
1312 1308
1313 base = cgbase(oldsb, cg->cg_cgx); 1309 base = cgbase(oldsb, cg->cg_cgx);
1314 /* Does the boundary fall in the middle of a block? To avoid 1310 /* Does the boundary fall in the middle of a block? To avoid
1315 * breaking between frags allocated as consecutive, we always 1311 * breaking between frags allocated as consecutive, we always
1316 * evict the whole block in this case, though one could argue 1312 * evict the whole block in this case, though one could argue
1317 * we should check to see if the frag before or after the 1313 * we should check to see if the frag before or after the
1318 * break is unallocated. */ 1314 * break is unallocated. */
1319 if (minfrag % oldsb->fs_frag) { 1315 if (minfrag % oldsb->fs_frag) {
1320 int n; 1316 int n;
1321 n = minfrag % oldsb->fs_frag; 1317 n = minfrag % oldsb->fs_frag;
1322 minfrag -= n; 1318 minfrag -= n;
1323 nfrag += n; 1319 nfrag += n;
1324 } 1320 }
1325 /* Do whole blocks. If a block is wholly free, skip it; if 1321 /* Do whole blocks. If a block is wholly free, skip it; if
1326 * wholly allocated, move it in toto. If neither, call 1322 * wholly allocated, move it in toto. If neither, call
1327 * fragmove() to move the frags to new locations. */ 1323 * fragmove() to move the frags to new locations. */
1328 while (nfrag >= oldsb->fs_frag) { 1324 while (nfrag >= oldsb->fs_frag) {
1329 if (!blk_is_set(cg_blksfree(cg, 0), minfrag, oldsb->fs_frag)) { 1325 if (!blk_is_set(cg_blksfree(cg, 0), minfrag, oldsb->fs_frag)) {
1330 if (blk_is_clr(cg_blksfree(cg, 0), minfrag, 1326 if (blk_is_clr(cg_blksfree(cg, 0), minfrag,
1331 oldsb->fs_frag)) { 1327 oldsb->fs_frag)) {
1332 int off; 1328 int off;
1333 off = find_freeblock(); 1329 off = find_freeblock();
1334 if (off < 0) 1330 if (off < 0)
1335 toofull(); 1331 toofull();
1336 mark_move(base + minfrag, off, oldsb->fs_frag); 1332 mark_move(base + minfrag, off, oldsb->fs_frag);
1337 set_bits(cg_blksfree(cg, 0), minfrag, 1333 set_bits(cg_blksfree(cg, 0), minfrag,
1338 oldsb->fs_frag); 1334 oldsb->fs_frag);
1339 clr_bits(cg_blksfree(cgs[dtog(oldsb, off)], 0), 1335 clr_bits(cg_blksfree(cgs[dtog(oldsb, off)], 0),
1340 dtogd(oldsb, off), oldsb->fs_frag); 1336 dtogd(oldsb, off), oldsb->fs_frag);
1341 } else { 1337 } else {
1342 fragmove(cg, base, minfrag, oldsb->fs_frag); 1338 fragmove(cg, base, minfrag, oldsb->fs_frag);
1343 } 1339 }
1344 } 1340 }
1345 minfrag += oldsb->fs_frag; 1341 minfrag += oldsb->fs_frag;
1346 nfrag -= oldsb->fs_frag; 1342 nfrag -= oldsb->fs_frag;
1347 } 1343 }
1348 /* Clean up any sub-block amount left over. */ 1344 /* Clean up any sub-block amount left over. */
1349 if (nfrag) { 1345 if (nfrag) {
1350 fragmove(cg, base, minfrag, nfrag); 1346 fragmove(cg, base, minfrag, nfrag);
1351 } 1347 }
1352} 1348}
1353/* 1349/*
1354 * Move all data blocks according to blkmove. We have to be careful, 1350 * Move all data blocks according to blkmove. We have to be careful,
1355 * because we may be updating indirect blocks that will themselves be 1351 * because we may be updating indirect blocks that will themselves be
1356 * getting moved, or inode int32_t arrays that point to indirect 1352 * getting moved, or inode int32_t arrays that point to indirect
1357 * blocks that will be moved. We call this before 1353 * blocks that will be moved. We call this before
1358 * update_for_data_move, and update_for_data_move does inodes first, 1354 * update_for_data_move, and update_for_data_move does inodes first,
1359 * then indirect blocks in preorder, so as to make sure that the 1355 * then indirect blocks in preorder, so as to make sure that the
1360 * file system is self-consistent at all points, for better crash 1356 * file system is self-consistent at all points, for better crash
1361 * tolerance. (We can get away with this only because all the writes 1357 * tolerance. (We can get away with this only because all the writes
1362 * done by perform_data_move() are writing into space that's not used 1358 * done by perform_data_move() are writing into space that's not used
1363 * by the old file system.) If we crash, some things may point to the 1359 * by the old file system.) If we crash, some things may point to the
1364 * old data and some to the new, but both copies are the same. The 1360 * old data and some to the new, but both copies are the same. The
1365 * only wrong things should be csum info and free bitmaps, which fsck 1361 * only wrong things should be csum info and free bitmaps, which fsck
1366 * is entirely capable of cleaning up. 1362 * is entirely capable of cleaning up.
1367 * 1363 *
1368 * Since blkmove_init() initializes all blocks to move to their current 1364 * Since blkmove_init() initializes all blocks to move to their current
1369 * locations, we can have two blocks marked as wanting to move to the 1365 * locations, we can have two blocks marked as wanting to move to the
1370 * same location, but only two and only when one of them is the one 1366 * same location, but only two and only when one of them is the one
1371 * that was already there. So if blkmove[i]==i, we ignore that entry 1367 * that was already there. So if blkmove[i]==i, we ignore that entry
1372 * entirely - for unallocated blocks, we don't want it (and may be 1368 * entirely - for unallocated blocks, we don't want it (and may be
1373 * putting something else there), and for allocated blocks, we don't 1369 * putting something else there), and for allocated blocks, we don't
1374 * want to copy it anywhere. 1370 * want to copy it anywhere.
1375 */ 1371 */
1376static void 1372static void
1377perform_data_move(void) 1373perform_data_move(void)
1378{ 1374{
1379 int i; 1375 int i;
1380 int run; 1376 int run;
1381 int maxrun; 1377 int maxrun;
1382 char buf[65536]; 1378 char buf[65536];
1383 1379
1384 maxrun = sizeof(buf) / newsb->fs_fsize; 1380 maxrun = sizeof(buf) / newsb->fs_fsize;
1385 run = 0; 1381 run = 0;
1386 for (i = 0; i < oldsb->fs_size; i++) { 1382 for (i = 0; i < oldsb->fs_size; i++) {
1387 if ((blkmove[i] == (unsigned)i /*XXX cast*/) || 1383 if ((blkmove[i] == (unsigned)i /*XXX cast*/) ||
1388 (run >= maxrun) || 1384 (run >= maxrun) ||
1389 ((run > 0) && 1385 ((run > 0) &&
1390 (blkmove[i] != blkmove[i - 1] + 1))) { 1386 (blkmove[i] != blkmove[i - 1] + 1))) {
1391 if (run > 0) { 1387 if (run > 0) {
1392 readat(fsbtodb(oldsb, i - run), &buf[0], 1388 readat(fsbtodb(oldsb, i - run), &buf[0],
1393 run << oldsb->fs_fshift); 1389 run << oldsb->fs_fshift);
1394 writeat(fsbtodb(oldsb, blkmove[i - run]), 1390 writeat(fsbtodb(oldsb, blkmove[i - run]),
1395 &buf[0], run << oldsb->fs_fshift); 1391 &buf[0], run << oldsb->fs_fshift);
1396 } 1392 }
1397 run = 0; 1393 run = 0;
1398 } 1394 }
1399 if (blkmove[i] != (unsigned)i /*XXX cast*/) 1395 if (blkmove[i] != (unsigned)i /*XXX cast*/)
1400 run++; 1396 run++;
1401 } 1397 }
1402 if (run > 0) { 1398 if (run > 0) {
1403 readat(fsbtodb(oldsb, i - run), &buf[0], 1399 readat(fsbtodb(oldsb, i - run), &buf[0],
1404 run << oldsb->fs_fshift); 1400 run << oldsb->fs_fshift);
1405 writeat(fsbtodb(oldsb, blkmove[i - run]), &buf[0], 1401 writeat(fsbtodb(oldsb, blkmove[i - run]), &buf[0],
1406 run << oldsb->fs_fshift); 1402 run << oldsb->fs_fshift);
1407 } 1403 }
1408} 1404}
1409/* 1405/*
1410 * This modifies an array of int32_t, according to blkmove. This is 1406 * This modifies an array of int32_t, according to blkmove. This is
1411 * used to update inode block arrays and indirect blocks to point to 1407 * used to update inode block arrays and indirect blocks to point to
1412 * the new locations of data blocks. 1408 * the new locations of data blocks.
1413 * 1409 *
1414 * Return value is the number of int32_ts that needed updating; in 1410 * Return value is the number of int32_ts that needed updating; in
1415 * particular, the return value is zero iff nothing was modified. 1411 * particular, the return value is zero iff nothing was modified.
1416 */ 1412 */
1417static int 1413static int
1418movemap_blocks(int32_t * vec, int n) 1414movemap_blocks(int32_t * vec, int n)
1419{ 1415{
1420 int rv; 1416 int rv;
1421 1417
1422 rv = 0; 1418 rv = 0;
1423 for (; n > 0; n--, vec++) { 1419 for (; n > 0; n--, vec++) {
1424 if (blkmove[*vec] != (unsigned)*vec /*XXX cast*/) { 1420 if (blkmove[*vec] != (unsigned)*vec /*XXX cast*/) {
1425 *vec = blkmove[*vec]; 1421 *vec = blkmove[*vec];
1426 rv++; 1422 rv++;
1427 } 1423 }
1428 } 1424 }
1429 return (rv); 1425 return (rv);
1430} 1426}
1431static void 1427static void
1432moveblocks_callback(union dinode * di, unsigned int inum, void *arg) 1428moveblocks_callback(union dinode * di, unsigned int inum, void *arg)
1433{ 1429{
1434 int32_t *dblkptr, *iblkptr; 1430 int32_t *dblkptr, *iblkptr;
1435 1431
1436 switch (DIP(di,di_mode) & IFMT) { 1432 switch (DIP(di,di_mode) & IFMT) {
1437 case IFLNK: 1433 case IFLNK:
1438 if ((off_t)DIP(di,di_size) <= oldsb->fs_maxsymlinklen) { 1434 if ((off_t)DIP(di,di_size) <= oldsb->fs_maxsymlinklen) {
1439 break; 1435 break;
1440 } 1436 }
1441 /* FALLTHROUGH */ 1437 /* FALLTHROUGH */
1442 case IFDIR: 1438 case IFDIR:
1443 case IFREG: 1439 case IFREG:
1444 if (is_ufs2) { 1440 if (is_ufs2) {
1445 /* XXX these are not int32_t and this is WRONG! */ 1441 /* XXX these are not int32_t and this is WRONG! */
1446 dblkptr = (void *) &(di->dp2.di_db[0]); 1442 dblkptr = (void *) &(di->dp2.di_db[0]);
1447 iblkptr = (void *) &(di->dp2.di_ib[0]); 1443 iblkptr = (void *) &(di->dp2.di_ib[0]);
1448 } else { 1444 } else {
1449 dblkptr = &(di->dp1.di_db[0]); 1445 dblkptr = &(di->dp1.di_db[0]);
1450 iblkptr = &(di->dp1.di_ib[0]); 1446 iblkptr = &(di->dp1.di_ib[0]);
1451 } 1447 }
1452 /* 1448 /*
1453 * Don't || these two calls; we need their 1449 * Don't || these two calls; we need their
1454 * side-effects. 1450 * side-effects.
1455 */ 1451 */
1456 if (movemap_blocks(dblkptr, NDADDR)) { 1452 if (movemap_blocks(dblkptr, NDADDR)) {
1457 iflags[inum] |= IF_DIRTY; 1453 iflags[inum] |= IF_DIRTY;
1458 } 1454 }
1459 if (movemap_blocks(iblkptr, NIADDR)) { 1455 if (movemap_blocks(iblkptr, NIADDR)) {
1460 iflags[inum] |= IF_DIRTY; 1456 iflags[inum] |= IF_DIRTY;
1461 } 1457 }
1462 break; 1458 break;
1463 } 1459 }
1464} 1460}
1465 1461
1466static void 1462static void
1467moveindir_callback(off_t off, unsigned int nfrag, unsigned int nbytes, 1463moveindir_callback(off_t off, unsigned int nfrag, unsigned int nbytes,
1468 int kind) 1464 int kind)
1469{ 1465{
1470 unsigned int i; 1466 unsigned int i;
1471 1467
1472 if (kind == MDB_INDIR_PRE) { 1468 if (kind == MDB_INDIR_PRE) {
1473 int32_t blk[howmany(MAXBSIZE, sizeof(int32_t))]; 1469 int32_t blk[howmany(MAXBSIZE, sizeof(int32_t))];
1474 readat(fsbtodb(oldsb, off), &blk[0], oldsb->fs_bsize); 1470 readat(fsbtodb(oldsb, off), &blk[0], oldsb->fs_bsize);
1475 if (needswap) 1471 if (needswap)
1476 for (i = 0; i < howmany(MAXBSIZE, sizeof(int32_t)); i++) 1472 for (i = 0; i < howmany(MAXBSIZE, sizeof(int32_t)); i++)
1477 blk[i] = bswap32(blk[i]); 1473 blk[i] = bswap32(blk[i]);
1478 if (movemap_blocks(&blk[0], NINDIR(oldsb))) { 1474 if (movemap_blocks(&blk[0], NINDIR(oldsb))) {
1479 if (needswap) 1475 if (needswap)
1480 for (i = 0; i < howmany(MAXBSIZE, 1476 for (i = 0; i < howmany(MAXBSIZE,
1481 sizeof(int32_t)); i++) 1477 sizeof(int32_t)); i++)
1482 blk[i] = bswap32(blk[i]); 1478 blk[i] = bswap32(blk[i]);
1483 writeat(fsbtodb(oldsb, off), &blk[0], oldsb->fs_bsize); 1479 writeat(fsbtodb(oldsb, off), &blk[0], oldsb->fs_bsize);
1484 } 1480 }
1485 } 1481 }
1486} 1482}
1487/* 1483/*
1488 * Update all inode data arrays and indirect blocks to point to the new 1484 * Update all inode data arrays and indirect blocks to point to the new
1489 * locations of data blocks. See the comment header on 1485 * locations of data blocks. See the comment header on
1490 * perform_data_move for some ordering considerations. 1486 * perform_data_move for some ordering considerations.
1491 */ 1487 */
1492static void 1488static void
1493update_for_data_move(void) 1489update_for_data_move(void)
1494{ 1490{
1495 map_inodes(&moveblocks_callback, oldsb->fs_ncg, NULL); 1491 map_inodes(&moveblocks_callback, oldsb->fs_ncg, NULL);
1496 map_data_blocks(&moveindir_callback, oldsb->fs_ncg); 1492 map_data_blocks(&moveindir_callback, oldsb->fs_ncg);
1497} 1493}
1498/* 1494/*
1499 * Initialize the inomove array. 1495 * Initialize the inomove array.
1500 */ 1496 */
1501static void 1497static void
1502inomove_init(void) 1498inomove_init(void)
1503{ 1499{
1504 int i; 1500 int i;
1505 1501
1506 inomove = alloconce(oldsb->fs_ipg * oldsb->fs_ncg * sizeof(*inomove), 1502 inomove = alloconce(oldsb->fs_ipg * oldsb->fs_ncg * sizeof(*inomove),
1507 "inomove"); 1503 "inomove");
1508 for (i = (oldsb->fs_ipg * oldsb->fs_ncg) - 1; i >= 0; i--) 1504 for (i = (oldsb->fs_ipg * oldsb->fs_ncg) - 1; i >= 0; i--)
1509 inomove[i] = i; 1505 inomove[i] = i;
1510} 1506}
1511/* 1507/*
1512 * Flush all dirtied inodes to disk. Scans the inode flags array; for 1508 * Flush all dirtied inodes to disk. Scans the inode flags array; for
1513 * each dirty inode, it sets the BDIRTY bit on the first inode in the 1509 * each dirty inode, it sets the BDIRTY bit on the first inode in the
1514 * block containing the dirty inode. Then it scans by blocks, and for 1510 * block containing the dirty inode. Then it scans by blocks, and for
1515 * each marked block, writes it. 1511 * each marked block, writes it.
1516 */ 1512 */
1517static void 1513static void
1518flush_inodes(void) 1514flush_inodes(void)
1519{ 1515{
1520 int i, j, k, na, ni, m; 1516 int i, j, k, na, ni, m;
1521 struct ufs1_dinode *dp1 = NULL; 1517 struct ufs1_dinode *dp1 = NULL;
1522 struct ufs2_dinode *dp2 = NULL; 1518 struct ufs2_dinode *dp2 = NULL;
1523 1519
1524 na = NDADDR + NIADDR; 1520 na = NDADDR + NIADDR;
1525 ni = newsb->fs_ipg * newsb->fs_ncg; 1521 ni = newsb->fs_ipg * newsb->fs_ncg;
1526 m = INOPB(newsb) - 1; 1522 m = INOPB(newsb) - 1;
1527 for (i = 0; i < ni; i++) { 1523 for (i = 0; i < ni; i++) {
1528 if (iflags[i] & IF_DIRTY) { 1524 if (iflags[i] & IF_DIRTY) {
1529 iflags[i & ~m] |= IF_BDIRTY; 1525 iflags[i & ~m] |= IF_BDIRTY;
1530 } 1526 }
1531 } 1527 }
1532 m++; 1528 m++;
1533 1529
1534 if (is_ufs2) 1530 if (is_ufs2)
1535 dp2 = (struct ufs2_dinode *)ibuf; 1531 dp2 = (struct ufs2_dinode *)ibuf;
1536 else 1532 else
1537 dp1 = (struct ufs1_dinode *)ibuf; 1533 dp1 = (struct ufs1_dinode *)ibuf;
1538 1534
1539 for (i = 0; i < ni; i += m) { 1535 for (i = 0; i < ni; i += m) {
1540 if (iflags[i] & IF_BDIRTY) { 1536 if (iflags[i] & IF_BDIRTY) {
1541 if (is_ufs2) 1537 if (is_ufs2)
1542 for (j = 0; j < m; j++) { 1538 for (j = 0; j < m; j++) {
1543 dp2[j] = inodes[i + j].dp2; 1539 dp2[j] = inodes[i + j].dp2;
1544 if (needswap) { 1540 if (needswap) {
1545 for (k = 0; k < na; k++) 1541 for (k = 0; k < na; k++)
1546 dp2[j].di_db[k]= 1542 dp2[j].di_db[k]=
1547 bswap32(dp2[j].di_db[k]); 1543 bswap32(dp2[j].di_db[k]);
1548 ffs_dinode2_swap(&dp2[j], 1544 ffs_dinode2_swap(&dp2[j],
1549 &dp2[j]); 1545 &dp2[j]);
1550 } 1546 }
1551 } 1547 }
1552 else 1548 else
1553 for (j = 0; j < m; j++) { 1549 for (j = 0; j < m; j++) {
1554 dp1[j] = inodes[i + j].dp1; 1550 dp1[j] = inodes[i + j].dp1;
1555 if (needswap) { 1551 if (needswap) {
1556 for (k = 0; k < na; k++) 1552 for (k = 0; k < na; k++)
1557 dp1[j].di_db[k]= 1553 dp1[j].di_db[k]=
1558 bswap32(dp1[j].di_db[k]); 1554 bswap32(dp1[j].di_db[k]);
1559 ffs_dinode1_swap(&dp1[j], 1555 ffs_dinode1_swap(&dp1[j],
1560 &dp1[j]); 1556 &dp1[j]);
1561 } 1557 }
1562 } 1558 }
1563 1559
1564 writeat(fsbtodb(newsb, ino_to_fsba(newsb, i)), 1560 writeat(fsbtodb(newsb, ino_to_fsba(newsb, i)),
1565 ibuf, newsb->fs_bsize); 1561 ibuf, newsb->fs_bsize);
1566 } 1562 }
1567 } 1563 }
1568} 1564}
1569/* 1565/*
1570 * Evict all inodes from the specified cg. shrink() already checked 1566 * Evict all inodes from the specified cg. shrink() already checked
1571 * that there were enough free inodes, so the no-free-inodes check is 1567 * that there were enough free inodes, so the no-free-inodes check is
1572 * a can't-happen. If it does trip, the file system should be in good 1568 * a can't-happen. If it does trip, the file system should be in good
1573 * enough shape for fsck to fix; see the comment on perform_data_move 1569 * enough shape for fsck to fix; see the comment on perform_data_move
1574 * for the considerations in question. 1570 * for the considerations in question.
1575 */ 1571 */
1576static void 1572static void
1577evict_inodes(struct cg * cg) 1573evict_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
1605 * crash tolerance, we want to make sure everything is present at both 1599 * crash tolerance, we want to make sure everything is present at both
1606 * old and new locations before we update pointers. So we call this 1600 * old and new locations before we update pointers. So we call this
1607 * first, then flush_inodes() to get them out on disk, then update 1601 * first, then flush_inodes() to get them out on disk, then update
1608 * directories to match. 1602 * directories to match.
1609 */ 1603 */
1610static void 1604static void
1611perform_inode_move(void) 1605perform_inode_move(void)
1612{ 1606{
1613 unsigned int i; 1607 unsigned int i;
1614 unsigned int ni; 1608 unsigned int ni;
1615 1609
1616 ni = oldsb->fs_ipg * oldsb->fs_ncg; 1610 ni = oldsb->fs_ipg * oldsb->fs_ncg;
1617 for (i = 0; i < ni; i++) { 1611 for (i = 0; i < ni; i++) {
1618 if (inomove[i] != i) { 1612 if (inomove[i] != i) {
1619 inodes[inomove[i]] = inodes[i]; 1613 inodes[inomove[i]] = inodes[i];
1620 iflags[inomove[i]] = iflags[i] | IF_DIRTY; 1614 iflags[inomove[i]] = iflags[i] | IF_DIRTY;
1621 } 1615 }
1622 } 1616 }
1623} 1617}
1624/* 1618/*
1625 * Update the directory contained in the nb bytes at buf, to point to 1619 * Update the directory contained in the nb bytes at buf, to point to
1626 * inodes' new locations. 1620 * inodes' new locations.
1627 */ 1621 */
1628static int 1622static int
1629update_dirents(char *buf, int nb) 1623update_dirents(char *buf, int nb)
1630{ 1624{
1631 int rv; 1625 int rv;
1632#define d ((struct direct *)buf) 1626#define d ((struct direct *)buf)
1633#define s32(x) (needswap?bswap32((x)):(x)) 1627#define s32(x) (needswap?bswap32((x)):(x))
1634#define s16(x) (needswap?bswap16((x)):(x)) 1628#define s16(x) (needswap?bswap16((x)):(x))
1635 1629
1636 rv = 0; 1630 rv = 0;
1637 while (nb > 0) { 1631 while (nb > 0) {
1638 if (inomove[s32(d->d_ino)] != s32(d->d_ino)) { 1632 if (inomove[s32(d->d_ino)] != s32(d->d_ino)) {
1639 rv++; 1633 rv++;
1640 d->d_ino = s32(inomove[s32(d->d_ino)]); 1634 d->d_ino = s32(inomove[s32(d->d_ino)]);
1641 } 1635 }
1642 nb -= s16(d->d_reclen); 1636 nb -= s16(d->d_reclen);
1643 buf += s16(d->d_reclen); 1637 buf += s16(d->d_reclen);
1644 } 1638 }
1645 return (rv); 1639 return (rv);
1646#undef d 1640#undef d
1647#undef s32 1641#undef s32
1648#undef s16 1642#undef s16
1649} 1643}
1650/* 1644/*
1651 * Callback function for map_inode_data_blocks, for updating a 1645 * Callback function for map_inode_data_blocks, for updating a
1652 * directory to point to new inode locations. 1646 * directory to point to new inode locations.
1653 */ 1647 */
1654static void 1648static void
1655update_dir_data(off_t bn, unsigned int size, unsigned int nb, int kind) 1649update_dir_data(off_t bn, unsigned int size, unsigned int nb, int kind)
1656{ 1650{
1657 if (kind == MDB_DATA) { 1651 if (kind == MDB_DATA) {
1658 union { 1652 union {
1659 struct direct d; 1653 struct direct d;
1660 char ch[MAXBSIZE]; 1654 char ch[MAXBSIZE];
1661 } buf; 1655 } buf;
1662 readat(fsbtodb(oldsb, bn), &buf, size << oldsb->fs_fshift); 1656 readat(fsbtodb(oldsb, bn), &buf, size << oldsb->fs_fshift);
1663 if (update_dirents((char *) &buf, nb)) { 1657 if (update_dirents((char *) &buf, nb)) {
1664 writeat(fsbtodb(oldsb, bn), &buf, 1658 writeat(fsbtodb(oldsb, bn), &buf,
1665 size << oldsb->fs_fshift); 1659 size << oldsb->fs_fshift);
1666 } 1660 }
1667 } 1661 }
1668} 1662}
1669static void 1663static void
1670dirmove_callback(union dinode * di, unsigned int inum, void *arg) 1664dirmove_callback(union dinode * di, unsigned int inum, void *arg)
1671{ 1665{
1672 switch (DIP(di,di_mode) & IFMT) { 1666 switch (DIP(di,di_mode) & IFMT) {
1673 case IFDIR: 1667 case IFDIR:
1674 map_inode_data_blocks(di, &update_dir_data); 1668 map_inode_data_blocks(di, &update_dir_data);
1675 break; 1669 break;
1676 } 1670 }
1677} 1671}
1678/* 1672/*
1679 * Update directory entries to point to new inode locations. 1673 * Update directory entries to point to new inode locations.
1680 */ 1674 */
1681static void 1675static void
1682update_for_inode_move(void) 1676update_for_inode_move(void)
1683{ 1677{
1684 map_inodes(&dirmove_callback, newsb->fs_ncg, NULL); 1678 map_inodes(&dirmove_callback, newsb->fs_ncg, NULL);
1685} 1679}
1686/* 1680/*
1687 * Shrink the file system. 1681 * Shrink the file system.
1688 */ 1682 */
1689static void 1683static void
1690shrink(void) 1684shrink(void)
1691{ 1685{
1692 int i; 1686 int i;
1693 1687
1694 /* Load the inodes off disk - we'll need 'em. */ 1688 /* Load the inodes off disk - we'll need 'em. */
1695 loadinodes(); 1689 loadinodes();
1696 /* Update the timestamp. */ 1690 /* Update the timestamp. */
1697 newsb->fs_time = timestamp(); 1691 newsb->fs_time = timestamp();
1698 /* Update the size figures. */ 1692 /* Update the size figures. */
1699 newsb->fs_size = dbtofsb(newsb, newsize); 1693 newsb->fs_size = dbtofsb(newsb, newsize);
1700 if (is_ufs2) 1694 if (is_ufs2)
1701 newsb->fs_ncg = howmany(newsb->fs_size, newsb->fs_fpg); 1695 newsb->fs_ncg = howmany(newsb->fs_size, newsb->fs_fpg);
1702 else { 1696 else {
1703 newsb->fs_old_ncyl = howmany(newsb->fs_size * NSPF(newsb), 1697 newsb->fs_old_ncyl = howmany(newsb->fs_size * NSPF(newsb),
1704 newsb->fs_old_spc); 1698 newsb->fs_old_spc);
1705 newsb->fs_ncg = howmany(newsb->fs_old_ncyl, newsb->fs_old_cpg); 1699 newsb->fs_ncg = howmany(newsb->fs_old_ncyl, newsb->fs_old_cpg);
1706 } 1700 }
1707 /* Does the (new) last cg end before the end of its inode area? See 1701 /* Does the (new) last cg end before the end of its inode area? See
1708 * the similar code in grow() for more on this. */ 1702 * the similar code in grow() for more on this. */
1709 if (cgdmin(newsb, newsb->fs_ncg - 1) > newsb->fs_size) { 1703 if (cgdmin(newsb, newsb->fs_ncg - 1) > newsb->fs_size) {
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);
1741 dlow = cgsblock(oldsb, i) - base; 1733 dlow = cgsblock(oldsb, i) - base;
1742 dhigh = cgdmin(oldsb, i) - base; 1734 dhigh = cgdmin(oldsb, i) - base;
1743 dmax = oldsb->fs_size - base; 1735 dmax = oldsb->fs_size - base;
1744 if (dmax > cgs[i]->cg_ndblk) 1736 if (dmax > cgs[i]->cg_ndblk)
1745 dmax = cgs[i]->cg_ndblk; 1737 dmax = cgs[i]->cg_ndblk;
1746 evict_data(cgs[i], 0, dlow); 1738 evict_data(cgs[i], 0, dlow);
1747 evict_data(cgs[i], dhigh, dmax - dhigh); 1739 evict_data(cgs[i], dhigh, dmax - dhigh);
1748 newsb->fs_cstotal.cs_ndir -= cgs[i]->cg_cs.cs_ndir; 1740 newsb->fs_cstotal.cs_ndir -= cgs[i]->cg_cs.cs_ndir;
1749 newsb->fs_cstotal.cs_nifree -= cgs[i]->cg_cs.cs_nifree; 1741 newsb->fs_cstotal.cs_nifree -= cgs[i]->cg_cs.cs_nifree;
1750 newsb->fs_cstotal.cs_nffree -= cgs[i]->cg_cs.cs_nffree; 1742 newsb->fs_cstotal.cs_nffree -= cgs[i]->cg_cs.cs_nffree;
1751 newsb->fs_cstotal.cs_nbfree -= cgs[i]->cg_cs.cs_nbfree; 1743 newsb->fs_cstotal.cs_nbfree -= cgs[i]->cg_cs.cs_nbfree;
1752 } 1744 }
1753 /* Update the new last cg. */ 1745 /* Update the new last cg. */
1754 cgs[newsb->fs_ncg - 1]->cg_ndblk = newsb->fs_size - 1746 cgs[newsb->fs_ncg - 1]->cg_ndblk = newsb->fs_size -
1755 ((newsb->fs_ncg - 1) * newsb->fs_fpg); 1747 ((newsb->fs_ncg - 1) * newsb->fs_fpg);
1756 /* Is the new last cg partial? If so, evict any data from the part 1748 /* Is the new last cg partial? If so, evict any data from the part
1757 * being shrunken away. */ 1749 * being shrunken away. */
1758 if (newsb->fs_size % newsb->fs_fpg) { 1750 if (newsb->fs_size % newsb->fs_fpg) {
1759 struct cg *cg; 1751 struct cg *cg;
1760 int oldcgsize; 1752 int oldcgsize;
1761 int newcgsize; 1753 int newcgsize;
1762 cg = cgs[newsb->fs_ncg - 1]; 1754 cg = cgs[newsb->fs_ncg - 1];
1763 newcgsize = newsb->fs_size % newsb->fs_fpg; 1755 newcgsize = newsb->fs_size % newsb->fs_fpg;
1764 oldcgsize = oldsb->fs_size - ((newsb->fs_ncg - 1) & 1756 oldcgsize = oldsb->fs_size - ((newsb->fs_ncg - 1) &
1765 oldsb->fs_fpg); 1757 oldsb->fs_fpg);
1766 if (oldcgsize > oldsb->fs_fpg) 1758 if (oldcgsize > oldsb->fs_fpg)
1767 oldcgsize = oldsb->fs_fpg; 1759 oldcgsize = oldsb->fs_fpg;
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();
1798 /* Recompute all the bitmaps; most of them probably need it anyway, 1788 /* Recompute all the bitmaps; most of them probably need it anyway,
1799 * the rest are just paranoia and not wanting to have to bother 1789 * the rest are just paranoia and not wanting to have to bother
1800 * keeping track of exactly which ones require it. */ 1790 * keeping track of exactly which ones require it. */
1801 for (i = 0; i < newsb->fs_ncg; i++) 1791 for (i = 0; i < newsb->fs_ncg; i++)
1802 cgflags[i] |= CGF_DIRTY | CGF_BLKMAPS | CGF_INOMAPS; 1792 cgflags[i] |= CGF_DIRTY | CGF_BLKMAPS | CGF_INOMAPS;
1803 /* Update the cg_old_ncyl value for the last cylinder. */ 1793 /* Update the cg_old_ncyl value for the last cylinder. */
1804 if ((newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0) 1794 if ((newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0)
1805 cgs[newsb->fs_ncg - 1]->cg_old_ncyl = 1795 cgs[newsb->fs_ncg - 1]->cg_old_ncyl =
1806 newsb->fs_old_ncyl % newsb->fs_old_cpg; 1796 newsb->fs_old_ncyl % newsb->fs_old_cpg;
1807 /* Make fs_dsize match the new reality. */ 1797 /* Make fs_dsize match the new reality. */
1808 recompute_fs_dsize(); 1798 recompute_fs_dsize();
1809} 1799}
1810/* 1800/*
1811 * Recompute the block totals, block cluster summaries, and rotational 1801 * Recompute the block totals, block cluster summaries, and rotational
1812 * position summaries, for a given cg (specified by number), based on 1802 * position summaries, for a given cg (specified by number), based on
1813 * its free-frag bitmap (cg_blksfree()[]). 1803 * its free-frag bitmap (cg_blksfree()[]).
1814 */ 1804 */
1815static void 1805static void
1816rescan_blkmaps(int cgn) 1806rescan_blkmaps(int cgn)
1817{ 1807{
1818 struct cg *cg; 1808 struct cg *cg;
1819 int f; 1809 int f;
1820 int b; 1810 int b;
1821 int blkfree; 1811 int blkfree;
1822 int blkrun; 1812 int blkrun;
1823 int fragrun; 1813 int fragrun;
1824 int fwb; 1814 int fwb;
1825 1815
1826 cg = cgs[cgn]; 1816 cg = cgs[cgn];
1827 /* Subtract off the current totals from the sb's summary info */ 1817 /* Subtract off the current totals from the sb's summary info */
1828 newsb->fs_cstotal.cs_nffree -= cg->cg_cs.cs_nffree; 1818 newsb->fs_cstotal.cs_nffree -= cg->cg_cs.cs_nffree;
1829 newsb->fs_cstotal.cs_nbfree -= cg->cg_cs.cs_nbfree; 1819 newsb->fs_cstotal.cs_nbfree -= cg->cg_cs.cs_nbfree;
1830 /* Clear counters and bitmaps. */ 1820 /* Clear counters and bitmaps. */
1831 cg->cg_cs.cs_nffree = 0; 1821 cg->cg_cs.cs_nffree = 0;
1832 cg->cg_cs.cs_nbfree = 0; 1822 cg->cg_cs.cs_nbfree = 0;
1833 memset(&cg->cg_frsum[0], 0, MAXFRAG * sizeof(cg->cg_frsum[0])); 1823 memset(&cg->cg_frsum[0], 0, MAXFRAG * sizeof(cg->cg_frsum[0]));
1834 memset(&old_cg_blktot(cg, 0)[0], 0, 1824 memset(&old_cg_blktot(cg, 0)[0], 0,
1835 newsb->fs_old_cpg * sizeof(old_cg_blktot(cg, 0)[0])); 1825 newsb->fs_old_cpg * sizeof(old_cg_blktot(cg, 0)[0]));
1836 memset(&old_cg_blks(newsb, cg, 0, 0)[0], 0, 1826 memset(&old_cg_blks(newsb, cg, 0, 0)[0], 0,
1837 newsb->fs_old_cpg * newsb->fs_old_nrpos * 1827 newsb->fs_old_cpg * newsb->fs_old_nrpos *
1838 sizeof(old_cg_blks(newsb, cg, 0, 0)[0])); 1828 sizeof(old_cg_blks(newsb, cg, 0, 0)[0]));
1839 if (newsb->fs_contigsumsize > 0) { 1829 if (newsb->fs_contigsumsize > 0) {
1840 cg->cg_nclusterblks = cg->cg_ndblk / newsb->fs_frag; 1830 cg->cg_nclusterblks = cg->cg_ndblk / newsb->fs_frag;
1841 memset(&cg_clustersum(cg, 0)[1], 0, 1831 memset(&cg_clustersum(cg, 0)[1], 0,
1842 newsb->fs_contigsumsize * 1832 newsb->fs_contigsumsize *
1843 sizeof(cg_clustersum(cg, 0)[1])); 1833 sizeof(cg_clustersum(cg, 0)[1]));
1844 if (is_ufs2) 1834 if (is_ufs2)
1845 memset(&cg_clustersfree(cg, 0)[0], 0, 1835 memset(&cg_clustersfree(cg, 0)[0], 0,
1846 howmany(newsb->fs_fpg / NSPB(newsb), NBBY)); 1836 howmany(newsb->fs_fpg / NSPB(newsb), NBBY));
1847 else 1837 else
1848 memset(&cg_clustersfree(cg, 0)[0], 0, 1838 memset(&cg_clustersfree(cg, 0)[0], 0,
1849 howmany((newsb->fs_old_cpg * newsb->fs_old_spc) / 1839 howmany((newsb->fs_old_cpg * newsb->fs_old_spc) /
1850 NSPB(newsb), NBBY)); 1840 NSPB(newsb), NBBY));
1851 } 1841 }
1852 /* Scan the free-frag bitmap. Runs of free frags are kept 1842 /* Scan the free-frag bitmap. Runs of free frags are kept
1853 * track of with fragrun, and recorded into cg_frsum[] and 1843 * track of with fragrun, and recorded into cg_frsum[] and
1854 * cg_cs.cs_nffree; on each block boundary, entire free blocks 1844 * cg_cs.cs_nffree; on each block boundary, entire free blocks
1855 * are recorded as well. */ 1845 * are recorded as well. */
1856 blkfree = 1; 1846 blkfree = 1;
1857 blkrun = 0; 1847 blkrun = 0;
1858 fragrun = 0; 1848 fragrun = 0;
1859 f = 0; 1849 f = 0;
1860 b = 0; 1850 b = 0;
1861 fwb = 0; 1851 fwb = 0;
1862 while (f < cg->cg_ndblk) { 1852 while (f < cg->cg_ndblk) {
1863 if (bit_is_set(cg_blksfree(cg, 0), f)) { 1853 if (bit_is_set(cg_blksfree(cg, 0), f)) {
1864 fragrun++; 1854 fragrun++;
1865 } else { 1855 } else {
1866 blkfree = 0; 1856 blkfree = 0;
1867 if (fragrun > 0) { 1857 if (fragrun > 0) {
1868 cg->cg_frsum[fragrun]++; 1858 cg->cg_frsum[fragrun]++;
1869 cg->cg_cs.cs_nffree += fragrun; 1859 cg->cg_cs.cs_nffree += fragrun;
1870 } 1860 }
1871 fragrun = 0; 1861 fragrun = 0;
1872 } 1862 }
1873 f++; 1863 f++;
1874 fwb++; 1864 fwb++;
1875 if (fwb >= newsb->fs_frag) { 1865 if (fwb >= newsb->fs_frag) {
1876 if (blkfree) { 1866 if (blkfree) {
1877 cg->cg_cs.cs_nbfree++; 1867 cg->cg_cs.cs_nbfree++;
1878 if (newsb->fs_contigsumsize > 0) 1868 if (newsb->fs_contigsumsize > 0)
1879 set_bits(cg_clustersfree(cg, 0), b, 1); 1869 set_bits(cg_clustersfree(cg, 0), b, 1);
1880 if (is_ufs2 == 0) { 1870 if (is_ufs2 == 0) {
1881 old_cg_blktot(cg, 0)[ 1871 old_cg_blktot(cg, 0)[
1882 old_cbtocylno(newsb, 1872 old_cbtocylno(newsb,
1883 f - newsb->fs_frag)]++; 1873 f - newsb->fs_frag)]++;
1884 old_cg_blks(newsb, cg, 1874 old_cg_blks(newsb, cg,
1885 old_cbtocylno(newsb, 1875 old_cbtocylno(newsb,
1886 f - newsb->fs_frag), 1876 f - newsb->fs_frag),
1887 0)[old_cbtorpos(newsb, 1877 0)[old_cbtorpos(newsb,
1888 f - newsb->fs_frag)]++; 1878 f - newsb->fs_frag)]++;
1889 } 1879 }
1890 blkrun++; 1880 blkrun++;
1891 } else { 1881 } else {
1892 if (fragrun > 0) { 1882 if (fragrun > 0) {
1893 cg->cg_frsum[fragrun]++; 1883 cg->cg_frsum[fragrun]++;
1894 cg->cg_cs.cs_nffree += fragrun; 1884 cg->cg_cs.cs_nffree += fragrun;
1895 } 1885 }
1896 if (newsb->fs_contigsumsize > 0) { 1886 if (newsb->fs_contigsumsize > 0) {
1897 if (blkrun > 0) { 1887 if (blkrun > 0) {
1898 cg_clustersum(cg, 0)[(blkrun 1888 cg_clustersum(cg, 0)[(blkrun
1899 > newsb->fs_contigsumsize) 1889 > newsb->fs_contigsumsize)
1900 ? newsb->fs_contigsumsize 1890 ? newsb->fs_contigsumsize
1901 : blkrun]++; 1891 : blkrun]++;
1902 } 1892 }
1903 } 1893 }
1904 blkrun = 0; 1894 blkrun = 0;
1905 } 1895 }
1906 fwb = 0; 1896 fwb = 0;
1907 b++; 1897 b++;
1908 blkfree = 1; 1898 blkfree = 1;
1909 fragrun = 0; 1899 fragrun = 0;
1910 } 1900 }
1911 } 1901 }
1912 if (fragrun > 0) { 1902 if (fragrun > 0) {
1913 cg->cg_frsum[fragrun]++; 1903 cg->cg_frsum[fragrun]++;
1914 cg->cg_cs.cs_nffree += fragrun; 1904 cg->cg_cs.cs_nffree += fragrun;
1915 } 1905 }
1916 if ((blkrun > 0) && (newsb->fs_contigsumsize > 0)) { 1906 if ((blkrun > 0) && (newsb->fs_contigsumsize > 0)) {
1917 cg_clustersum(cg, 0)[(blkrun > newsb->fs_contigsumsize) ? 1907 cg_clustersum(cg, 0)[(blkrun > newsb->fs_contigsumsize) ?
1918 newsb->fs_contigsumsize : blkrun]++; 1908 newsb->fs_contigsumsize : blkrun]++;
1919 } 1909 }
1920 /* 1910 /*
1921 * Put the updated summary info back into csums, and add it 1911 * Put the updated summary info back into csums, and add it
1922 * back into the sb's summary info. Then mark the cg dirty. 1912 * back into the sb's summary info. Then mark the cg dirty.
1923 */ 1913 */
1924 csums[cgn] = cg->cg_cs; 1914 csums[cgn] = cg->cg_cs;
1925 newsb->fs_cstotal.cs_nffree += cg->cg_cs.cs_nffree; 1915 newsb->fs_cstotal.cs_nffree += cg->cg_cs.cs_nffree;
1926 newsb->fs_cstotal.cs_nbfree += cg->cg_cs.cs_nbfree; 1916 newsb->fs_cstotal.cs_nbfree += cg->cg_cs.cs_nbfree;
1927 cgflags[cgn] |= CGF_DIRTY; 1917 cgflags[cgn] |= CGF_DIRTY;
1928} 1918}
1929/* 1919/*
1930 * Recompute the cg_inosused()[] bitmap, and the cs_nifree and cs_ndir 1920 * Recompute the cg_inosused()[] bitmap, and the cs_nifree and cs_ndir
1931 * values, for a cg, based on the in-core inodes for that cg. 1921 * values, for a cg, based on the in-core inodes for that cg.
1932 */ 1922 */
1933static void 1923static void
1934rescan_inomaps(int cgn) 1924rescan_inomaps(int cgn)
1935{ 1925{
1936 struct cg *cg; 1926 struct cg *cg;
1937 int inum; 1927 int inum;
1938 int iwc; 1928 int iwc;
1939 1929
1940 cg = cgs[cgn]; 1930 cg = cgs[cgn];
1941 newsb->fs_cstotal.cs_ndir -= cg->cg_cs.cs_ndir; 1931 newsb->fs_cstotal.cs_ndir -= cg->cg_cs.cs_ndir;
1942 newsb->fs_cstotal.cs_nifree -= cg->cg_cs.cs_nifree; 1932 newsb->fs_cstotal.cs_nifree -= cg->cg_cs.cs_nifree;
1943 cg->cg_cs.cs_ndir = 0; 1933 cg->cg_cs.cs_ndir = 0;
1944 cg->cg_cs.cs_nifree = 0; 1934 cg->cg_cs.cs_nifree = 0;
1945 memset(&cg_inosused(cg, 0)[0], 0, howmany(newsb->fs_ipg, NBBY)); 1935 memset(&cg_inosused(cg, 0)[0], 0, howmany(newsb->fs_ipg, NBBY));
1946 inum = cgn * newsb->fs_ipg; 1936 inum = cgn * newsb->fs_ipg;
1947 if (cgn == 0) { 1937 if (cgn == 0) {
1948 set_bits(cg_inosused(cg, 0), 0, 2); 1938 set_bits(cg_inosused(cg, 0), 0, 2);
1949 iwc = 2; 1939 iwc = 2;
1950 inum += 2; 1940 inum += 2;
1951 } else { 1941 } else {
1952 iwc = 0; 1942 iwc = 0;
1953 } 1943 }
1954 for (; iwc < newsb->fs_ipg; iwc++, inum++) { 1944 for (; iwc < newsb->fs_ipg; iwc++, inum++) {
1955 switch (DIP(inodes + inum, di_mode) & IFMT) { 1945 switch (DIP(inodes + inum, di_mode) & IFMT) {
1956 case 0: 1946 case 0:
1957 cg->cg_cs.cs_nifree++; 1947 cg->cg_cs.cs_nifree++;
1958 break; 1948 break;
1959 case IFDIR: 1949 case IFDIR:
1960 cg->cg_cs.cs_ndir++; 1950 cg->cg_cs.cs_ndir++;
1961 /* FALLTHROUGH */ 1951 /* FALLTHROUGH */
1962 default: 1952 default:
1963 set_bits(cg_inosused(cg, 0), iwc, 1); 1953 set_bits(cg_inosused(cg, 0), iwc, 1);
1964 break; 1954 break;
1965 } 1955 }
1966 } 1956 }
1967 csums[cgn] = cg->cg_cs; 1957 csums[cgn] = cg->cg_cs;
1968 newsb->fs_cstotal.cs_ndir += cg->cg_cs.cs_ndir; 1958 newsb->fs_cstotal.cs_ndir += cg->cg_cs.cs_ndir;
1969 newsb->fs_cstotal.cs_nifree += cg->cg_cs.cs_nifree; 1959 newsb->fs_cstotal.cs_nifree += cg->cg_cs.cs_nifree;
1970 cgflags[cgn] |= CGF_DIRTY; 1960 cgflags[cgn] |= CGF_DIRTY;
1971} 1961}
1972/* 1962/*
1973 * Flush cgs to disk, recomputing anything they're marked as needing. 1963 * Flush cgs to disk, recomputing anything they're marked as needing.
1974 */ 1964 */
1975static void 1965static void
1976flush_cgs(void) 1966flush_cgs(void)
1977{ 1967{
1978 int i; 1968 int i;
1979 1969
1980 for (i = 0; i < newsb->fs_ncg; i++) { 1970 for (i = 0; i < newsb->fs_ncg; i++) {
1981 if (cgflags[i] & CGF_BLKMAPS) { 1971 if (cgflags[i] & CGF_BLKMAPS) {
1982 rescan_blkmaps(i); 1972 rescan_blkmaps(i);
1983 } 1973 }
1984 if (cgflags[i] & CGF_INOMAPS) { 1974 if (cgflags[i] & CGF_INOMAPS) {
1985 rescan_inomaps(i); 1975 rescan_inomaps(i);
1986 } 1976 }
1987 if (cgflags[i] & CGF_DIRTY) { 1977 if (cgflags[i] & CGF_DIRTY) {
1988 cgs[i]->cg_rotor = 0; 1978 cgs[i]->cg_rotor = 0;
1989 cgs[i]->cg_frotor = 0; 1979 cgs[i]->cg_frotor = 0;
1990 cgs[i]->cg_irotor = 0; 1980 cgs[i]->cg_irotor = 0;
1991 if (needswap) 1981 if (needswap)
1992 ffs_cg_swap(cgs[i],cgs[i],newsb); 1982 ffs_cg_swap(cgs[i],cgs[i],newsb);
1993 writeat(fsbtodb(newsb, cgtod(newsb, i)), cgs[i], 1983 writeat(fsbtodb(newsb, cgtod(newsb, i)), cgs[i],
1994 cgblksz); 1984 cgblksz);
1995 } 1985 }
1996 } 1986 }
1997 if (needswap) 1987 if (needswap)
1998 ffs_csum_swap(csums,csums,newsb->fs_cssize); 1988 ffs_csum_swap(csums,csums,newsb->fs_cssize);
1999 writeat(fsbtodb(newsb, newsb->fs_csaddr), csums, newsb->fs_cssize); 1989 writeat(fsbtodb(newsb, newsb->fs_csaddr), csums, newsb->fs_cssize);
2000} 1990}
2001/* 1991/*
2002 * Write the superblock, both to the main superblock and to each cg's 1992 * Write the superblock, both to the main superblock and to each cg's
2003 * alternative superblock. 1993 * alternative superblock.
2004 */ 1994 */
2005static void 1995static void
2006write_sbs(void) 1996write_sbs(void)
2007{ 1997{
2008 int i; 1998 int i;
2009 1999
2010 if (newsb->fs_magic == FS_UFS1_MAGIC && 2000 if (newsb->fs_magic == FS_UFS1_MAGIC &&
2011 (newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0) { 2001 (newsb->fs_old_flags & FS_FLAGS_UPDATED) == 0) {
2012 newsb->fs_old_time = newsb->fs_time; 2002 newsb->fs_old_time = newsb->fs_time;
2013 newsb->fs_old_size = newsb->fs_size; 2003 newsb->fs_old_size = newsb->fs_size;
2014 /* we don't update fs_csaddr */ 2004 /* we don't update fs_csaddr */
2015 newsb->fs_old_dsize = newsb->fs_dsize; 2005 newsb->fs_old_dsize = newsb->fs_dsize;
2016 newsb->fs_old_cstotal.cs_ndir = newsb->fs_cstotal.cs_ndir; 2006 newsb->fs_old_cstotal.cs_ndir = newsb->fs_cstotal.cs_ndir;
2017 newsb->fs_old_cstotal.cs_nbfree = newsb->fs_cstotal.cs_nbfree; 2007 newsb->fs_old_cstotal.cs_nbfree = newsb->fs_cstotal.cs_nbfree;
2018 newsb->fs_old_cstotal.cs_nifree = newsb->fs_cstotal.cs_nifree; 2008 newsb->fs_old_cstotal.cs_nifree = newsb->fs_cstotal.cs_nifree;
2019 newsb->fs_old_cstotal.cs_nffree = newsb->fs_cstotal.cs_nffree; 2009 newsb->fs_old_cstotal.cs_nffree = newsb->fs_cstotal.cs_nffree;
2020 /* fill fs_old_postbl_start with 256 bytes of 0xff? */ 2010 /* fill fs_old_postbl_start with 256 bytes of 0xff? */
2021 } 2011 }
2022 /* copy newsb back to oldsb, so we can use it for offsets if 2012 /* copy newsb back to oldsb, so we can use it for offsets if
2023 newsb has been swapped for writing to disk */ 2013 newsb has been swapped for writing to disk */
2024 memcpy(oldsb, newsb, SBLOCKSIZE); 2014 memcpy(oldsb, newsb, SBLOCKSIZE);
2025 if (needswap) 2015 if (needswap)
2026 ffs_sb_swap(newsb,newsb); 2016 ffs_sb_swap(newsb,newsb);
2027 writeat(where / DEV_BSIZE, newsb, SBLOCKSIZE); 2017 writeat(where / DEV_BSIZE, newsb, SBLOCKSIZE);
2028 for (i = 0; i < oldsb->fs_ncg; i++) { 2018 for (i = 0; i < oldsb->fs_ncg; i++) {
2029 writeat(fsbtodb(oldsb, cgsblock(oldsb, i)), newsb, SBLOCKSIZE); 2019 writeat(fsbtodb(oldsb, cgsblock(oldsb, i)), newsb, SBLOCKSIZE);
2030 } 2020 }
2031} 2021}
2032 2022
2033static off_t 2023static off_t
2034get_dev_size(char *dev_name) 2024get_dev_size(char *dev_name)
2035{ 2025{
2036 struct dkwedge_info dkw; 2026 struct dkwedge_info dkw;
2037 struct partition *pp; 2027 struct partition *pp;
2038 struct disklabel lp; 2028 struct disklabel lp;
2039 size_t ptn; 2029 size_t ptn;
2040 2030
2041 /* Get info about partition/wedge */ 2031 /* Get info about partition/wedge */
2042 if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) { 2032 if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) {
2043 if (ioctl(fd, DIOCGDINFO, &lp) == -1) 2033 if (ioctl(fd, DIOCGDINFO, &lp) == -1)
2044 return 0; 2034 return 0;
2045 2035
2046 ptn = strchr(dev_name, '\0')[-1] - 'a'; 2036 ptn = strchr(dev_name, '\0')[-1] - 'a';
2047 if (ptn >= lp.d_npartitions) 2037 if (ptn >= lp.d_npartitions)
2048 return 0; 2038 return 0;
2049 2039
2050 pp = &lp.d_partitions[ptn]; 2040 pp = &lp.d_partitions[ptn];
2051 return pp->p_size; 2041 return pp->p_size;
2052 } 2042 }
2053 2043
2054 return dkw.dkw_size; 2044 return dkw.dkw_size;
2055} 2045}
2056 2046
2057/* 2047/*
2058 * main(). 2048 * main().
2059 */ 2049 */
2060int 2050int
2061main(int argc, char **argv) 2051main(int argc, char **argv)
2062{ 2052{
2063 int ch; 2053 int ch;
2064 int ExpertFlag; 2054 int ExpertFlag;
2065 int SFlag; 2055 int SFlag;
2066 size_t i; 2056 size_t i;
2067 2057
2068 char *special; 2058 char *special;
2069 char reply[5]; 2059 char reply[5];
2070 2060
2071 newsize = 0; 2061 newsize = 0;
2072 ExpertFlag = 0; 2062 ExpertFlag = 0;
2073 SFlag = 0; 2063 SFlag = 0;
2074 2064
2075 while ((ch = getopt(argc, argv, "s:y")) != -1) { 2065 while ((ch = getopt(argc, argv, "s:y")) != -1) {
2076 switch (ch) { 2066 switch (ch) {
2077 case 's': 2067 case 's':
2078 SFlag = 1; 2068 SFlag = 1;
2079 newsize = strtoll(optarg, NULL, 10); 2069 newsize = strtoll(optarg, NULL, 10);
2080 if(newsize < 1) { 2070 if(newsize < 1) {
2081 usage(); 2071 usage();
2082 } 2072 }
2083 break; 2073 break;
2084 case 'y': 2074 case 'y':
2085 ExpertFlag = 1; 2075 ExpertFlag = 1;
2086 break; 2076 break;
2087 case '?': 2077 case '?':
2088 /* FALLTHROUGH */ 2078 /* FALLTHROUGH */
2089 default: 2079 default:
2090 usage(); 2080 usage();
2091 } 2081 }
2092 } 2082 }
2093 argc -= optind; 2083 argc -= optind;
2094 argv += optind; 2084 argv += optind;
2095 2085
2096 if (argc != 1) { 2086 if (argc != 1) {
2097 usage(); 2087 usage();
2098 } 2088 }
2099 2089
2100 special = *argv; 2090 special = *argv;
2101 2091
2102 if (ExpertFlag == 0) { 2092 if (ExpertFlag == 0) {
2103 printf("It's required to manually run fsck on file system " 2093 printf("It's required to manually run fsck on file system "
2104 "before you can resize it\n\n" 2094 "before you can resize it\n\n"
2105 " Did you run fsck on your disk (Yes/No) ? "); 2095 " Did you run fsck on your disk (Yes/No) ? ");
2106 fgets(reply, (int)sizeof(reply), stdin); 2096 fgets(reply, (int)sizeof(reply), stdin);
2107 if (strcasecmp(reply, "Yes\n")) { 2097 if (strcasecmp(reply, "Yes\n")) {
2108 printf("\n Nothing done \n"); 2098 printf("\n Nothing done \n");
2109 exit(EXIT_SUCCESS); 2099 exit(EXIT_SUCCESS);
2110 } 2100 }
2111 } 2101 }
2112 2102
2113 fd = open(special, O_RDWR, 0); 2103 fd = open(special, O_RDWR, 0);
2114 if (fd < 0) 2104 if (fd < 0)
2115 err(EXIT_FAILURE, "Can't open `%s'", special); 2105 err(EXIT_FAILURE, "Can't open `%s'", special);
2116 checksmallio(); 2106 checksmallio();
2117 2107
2118 if (SFlag == 0) { 2108 if (SFlag == 0) {
2119 newsize = get_dev_size(special); 2109 newsize = get_dev_size(special);
2120 if (newsize == 0) 2110 if (newsize == 0)
2121 err(EXIT_FAILURE, 2111 err(EXIT_FAILURE,
2122 "Can't resize file system, newsize not known."); 2112 "Can't resize file system, newsize not known.");
2123 } 2113 }
2124 2114
2125 oldsb = (struct fs *) & sbbuf; 2115 oldsb = (struct fs *) & sbbuf;
2126 newsb = (struct fs *) (SBLOCKSIZE + (char *) &sbbuf); 2116 newsb = (struct fs *) (SBLOCKSIZE + (char *) &sbbuf);
2127 for (where = search[i = 0]; search[i] != -1; where = search[++i]) { 2117 for (where = search[i = 0]; search[i] != -1; where = search[++i]) {
2128 readat(where / DEV_BSIZE, oldsb, SBLOCKSIZE); 2118 readat(where / DEV_BSIZE, oldsb, SBLOCKSIZE);
2129 switch (oldsb->fs_magic) { 2119 switch (oldsb->fs_magic) {
2130 case FS_UFS2_MAGIC: 2120 case FS_UFS2_MAGIC:
2131 is_ufs2 = 1; 2121 is_ufs2 = 1;
2132 /* FALLTHROUGH */ 2122 /* FALLTHROUGH */
2133 case FS_UFS1_MAGIC: 2123 case FS_UFS1_MAGIC:
2134 needswap = 0; 2124 needswap = 0;
2135 break; 2125 break;
2136 case FS_UFS2_MAGIC_SWAPPED: 2126 case FS_UFS2_MAGIC_SWAPPED:
2137 is_ufs2 = 1; 2127 is_ufs2 = 1;
2138 /* FALLTHROUGH */ 2128 /* FALLTHROUGH */
2139 case FS_UFS1_MAGIC_SWAPPED: 2129 case FS_UFS1_MAGIC_SWAPPED:
2140 needswap = 1; 2130 needswap = 1;
2141 break; 2131 break;
2142 default: 2132 default:
2143 continue; 2133 continue;
2144 } 2134 }
2145 if (!is_ufs2 && where == SBLOCK_UFS2) 2135 if (!is_ufs2 && where == SBLOCK_UFS2)
2146 continue; 2136 continue;
2147 break; 2137 break;
2148 } 2138 }
2149 if (where == (off_t)-1) 2139 if (where == (off_t)-1)
2150 errx(EXIT_FAILURE, "Bad magic number"); 2140 errx(EXIT_FAILURE, "Bad magic number");
2151 if (needswap) 2141 if (needswap)
2152 ffs_sb_swap(oldsb,oldsb); 2142 ffs_sb_swap(oldsb,oldsb);
2153 if (oldsb->fs_magic == FS_UFS1_MAGIC && 2143 if (oldsb->fs_magic == FS_UFS1_MAGIC &&
2154 (oldsb->fs_old_flags & FS_FLAGS_UPDATED) == 0) { 2144 (oldsb->fs_old_flags & FS_FLAGS_UPDATED) == 0) {
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 }
2186 flush_cgs(); 2174 flush_cgs();
2187 write_sbs(); 2175 write_sbs();
2188 if (isplainfile()) 2176 if (isplainfile())
2189 ftruncate(fd,newsize * DEV_BSIZE); 2177 ftruncate(fd,newsize * DEV_BSIZE);
2190 return 0; 2178 return 0;
2191} 2179}
2192 2180
2193static void 2181static void
2194usage(void) 2182usage(void)
2195{ 2183{
2196 2184
2197 (void)fprintf(stderr, "usage: %s [-y] [-s size] special\n", 2185 (void)fprintf(stderr, "usage: %s [-y] [-s size] special\n",
2198 getprogname()); 2186 getprogname());
2199 exit(EXIT_FAILURE); 2187 exit(EXIT_FAILURE);
2200} 2188}