Mercurial > hg > toybox
comparison toys/mke2fs.c @ 237:7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
macros in each C file, and making generated/globals.h from that. Rename
"toy" to "this" along the way to avoid toy/toys confusion.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 20 Jan 2008 17:25:44 -0600 |
parents | 6b292ee780ab |
children | 44abf4d901f3 |
comparison
equal
deleted
inserted
replaced
236:6b292ee780ab | 237:7cb15eae1664 |
---|---|
75 sparse_super Don't allocate huge numbers of redundant superblocks | 75 sparse_super Don't allocate huge numbers of redundant superblocks |
76 */ | 76 */ |
77 | 77 |
78 #include "toys.h" | 78 #include "toys.h" |
79 | 79 |
80 DEFINE_GLOBALS( | |
81 // Command line arguments. | |
82 long blocksize; | |
83 long bytes_per_inode; | |
84 long inodes; // Total inodes in filesystem. | |
85 long reserved_percent; // Integer precent of space to reserve for root. | |
86 char *gendir; // Where to read dirtree from. | |
87 | |
88 // Internal data. | |
89 struct dirtree *dt; // Tree of files to copy into the new filesystem. | |
90 unsigned treeblocks; // Blocks used by dt | |
91 unsigned treeinodes; // Inodes used by dt | |
92 | |
93 unsigned blocks; // Total blocks in the filesystem. | |
94 unsigned freeblocks; // Free blocks in the filesystem. | |
95 unsigned inodespg; // Inodes per group | |
96 unsigned groups; // Total number of block groups. | |
97 unsigned blockbits; // Bits per block. (Also blocks per group.) | |
98 | |
99 // For gene2fs | |
100 unsigned nextblock; // Next data block to allocate | |
101 unsigned nextgroup; // Next group we'll be allocating from | |
102 int fsfd; // File descriptor of filesystem (to output to). | |
103 | |
104 struct ext2_superblock sb; | |
105 ) | |
106 | |
80 // Shortcut to our global data structure, since we use it so much. | 107 // Shortcut to our global data structure, since we use it so much. |
81 #define TT toy.mke2fs | 108 #define TT this.mke2fs |
82 | 109 |
83 #define INODES_RESERVED 10 | 110 #define INODES_RESERVED 10 |
84 | 111 |
85 static uint32_t div_round_up(uint32_t a, uint32_t b) | 112 static uint32_t div_round_up(uint32_t a, uint32_t b) |
86 { | 113 { |
138 | 165 |
139 // Recursively calculate the number of blocks used by each inode in the tree. | 166 // Recursively calculate the number of blocks used by each inode in the tree. |
140 // Returns blocks used by this directory, assigns bytes used to *size. | 167 // Returns blocks used by this directory, assigns bytes used to *size. |
141 // Writes total block count to TT.treeblocks and inode count to TT.treeinodes. | 168 // Writes total block count to TT.treeblocks and inode count to TT.treeinodes. |
142 | 169 |
143 static long check_treesize(struct dirtree *this, off_t *size) | 170 static long check_treesize(struct dirtree *that, off_t *size) |
144 { | 171 { |
145 long blocks; | 172 long blocks; |
146 | 173 |
147 while (this) { | 174 while (that) { |
148 *size += sizeof(struct ext2_dentry) + strlen(this->name); | 175 *size += sizeof(struct ext2_dentry) + strlen(that->name); |
149 | 176 |
150 if (this->child) | 177 if (that->child) |
151 this->st.st_blocks = check_treesize(this->child, &this->st.st_size); | 178 that->st.st_blocks = check_treesize(that->child, &that->st.st_size); |
152 else if (S_ISREG(this->st.st_mode)) { | 179 else if (S_ISREG(that->st.st_mode)) { |
153 this->st.st_blocks = file_blocks_used(this->st.st_size, 0); | 180 that->st.st_blocks = file_blocks_used(that->st.st_size, 0); |
154 TT.treeblocks += this->st.st_blocks; | 181 TT.treeblocks += that->st.st_blocks; |
155 } | 182 } |
156 this = this->next; | 183 that = that->next; |
157 } | 184 } |
158 TT.treeblocks += blocks = file_blocks_used(*size, 0); | 185 TT.treeblocks += blocks = file_blocks_used(*size, 0); |
159 TT.treeinodes++; | 186 TT.treeinodes++; |
160 | 187 |
161 return blocks; | 188 return blocks; |
168 // numbers of files (> 100,000) but can be done in very little code. | 195 // numbers of files (> 100,000) but can be done in very little code. |
169 // This rewrites inode numbers to their final values, allocating depth first. | 196 // This rewrites inode numbers to their final values, allocating depth first. |
170 | 197 |
171 static void check_treelinks(struct dirtree *tree) | 198 static void check_treelinks(struct dirtree *tree) |
172 { | 199 { |
173 struct dirtree *this=tree, *that; | 200 struct dirtree *current=tree, *that; |
174 long inode = INODES_RESERVED; | 201 long inode = INODES_RESERVED; |
175 | 202 |
176 while (this) { | 203 while (current) { |
177 ++inode; | 204 ++inode; |
178 // Since we can't hardlink to directories, we know their link count. | 205 // Since we can't hardlink to directories, we know their link count. |
179 if (S_ISDIR(this->st.st_mode)) this->st.st_nlink = 2; | 206 if (S_ISDIR(current->st.st_mode)) current->st.st_nlink = 2; |
180 else { | 207 else { |
181 dev_t new = this->st.st_dev; | 208 dev_t new = current->st.st_dev; |
182 | 209 |
183 if (!new) continue; | 210 if (!new) continue; |
184 | 211 |
185 this->st.st_nlink = 0; | 212 // Look for other copies of current node |
213 current->st.st_nlink = 0; | |
186 for (that = tree; that; that = treenext(that)) { | 214 for (that = tree; that; that = treenext(that)) { |
187 if (this->st.st_ino == that->st.st_ino && | 215 if (current->st.st_ino == that->st.st_ino && |
188 this->st.st_dev == that->st.st_dev) | 216 current->st.st_dev == that->st.st_dev) |
189 { | 217 { |
190 this->st.st_nlink++; | 218 current->st.st_nlink++; |
191 this->st.st_ino = inode; | 219 current->st.st_ino = inode; |
192 } | 220 } |
193 } | 221 } |
194 } | 222 } |
195 this->st.st_ino = inode; | 223 current->st.st_ino = inode; |
196 this = treenext(this); | 224 current = treenext(current); |
197 } | 225 } |
198 } | 226 } |
199 | 227 |
200 // According to http://www.opengroup.org/onlinepubs/9629399/apdxa.htm | 228 // According to http://www.opengroup.org/onlinepubs/9629399/apdxa.htm |
201 // we should generate a uuid structure by reading a clock with 100 nanosecond | 229 // we should generate a uuid structure by reading a clock with 100 nanosecond |
361 } | 389 } |
362 } | 390 } |
363 } | 391 } |
364 | 392 |
365 // Fill out an inode structure from struct stat info in dirtree. | 393 // Fill out an inode structure from struct stat info in dirtree. |
366 static void fill_inode(struct ext2_inode *in, struct dirtree *this) | 394 static void fill_inode(struct ext2_inode *in, struct dirtree *that) |
367 { | 395 { |
368 uint32_t fbu[15]; | 396 uint32_t fbu[15]; |
369 int temp; | 397 int temp; |
370 | 398 |
371 file_blocks_used(this->st.st_size, fbu); | 399 file_blocks_used(that->st.st_size, fbu); |
372 | 400 |
373 // If this inode needs data blocks allocated to it. | 401 // If that inode needs data blocks allocated to it. |
374 if (this->st.st_size) { | 402 if (that->st.st_size) { |
375 int i, group = TT.nextblock/TT.blockbits; | 403 int i, group = TT.nextblock/TT.blockbits; |
376 | 404 |
377 // TODO: teach this about indirect blocks. | 405 // TODO: teach this about indirect blocks. |
378 for (i=0; i<15; i++) { | 406 for (i=0; i<15; i++) { |
379 // If we just jumped into a new group, skip group overhead blocks. | 407 // If we just jumped into a new group, skip group overhead blocks. |
380 while (group >= TT.nextgroup) | 408 while (group >= TT.nextgroup) |
381 TT.nextblock += group_overhead(TT.nextgroup++); | 409 TT.nextblock += group_overhead(TT.nextgroup++); |
382 } | 410 } |
383 } | 411 } |
384 // TODO : S_ISREG/DIR/CHR/BLK/FIFO/LNK/SOCK(m) | 412 // TODO : S_ISREG/DIR/CHR/BLK/FIFO/LNK/SOCK(m) |
385 in->mode = SWAP_LE32(this->st.st_mode); | 413 in->mode = SWAP_LE32(that->st.st_mode); |
386 | 414 |
387 in->uid = SWAP_LE16(this->st.st_uid & 0xFFFF); | 415 in->uid = SWAP_LE16(that->st.st_uid & 0xFFFF); |
388 in->uid_high = SWAP_LE16(this->st.st_uid >> 16); | 416 in->uid_high = SWAP_LE16(that->st.st_uid >> 16); |
389 in->gid = SWAP_LE16(this->st.st_gid & 0xFFFF); | 417 in->gid = SWAP_LE16(that->st.st_gid & 0xFFFF); |
390 in->gid_high = SWAP_LE16(this->st.st_gid >> 16); | 418 in->gid_high = SWAP_LE16(that->st.st_gid >> 16); |
391 in->size = SWAP_LE32(this->st.st_size & 0xFFFFFFFF); | 419 in->size = SWAP_LE32(that->st.st_size & 0xFFFFFFFF); |
392 | 420 |
393 // Contortions to make the compiler not generate a warning for x>>32 | 421 // Contortions to make the compiler not generate a warning for x>>32 |
394 // when x is 32 bits. The optimizer should clean this up. | 422 // when x is 32 bits. The optimizer should clean this up. |
395 if (sizeof(this->st.st_size) > 4) temp = 32; | 423 if (sizeof(that->st.st_size) > 4) temp = 32; |
396 else temp = 0; | 424 else temp = 0; |
397 if (temp) in->dir_acl = SWAP_LE32(this->st.st_size >> temp); | 425 if (temp) in->dir_acl = SWAP_LE32(that->st.st_size >> temp); |
398 | 426 |
399 in->atime = SWAP_LE32(this->st.st_atime); | 427 in->atime = SWAP_LE32(that->st.st_atime); |
400 in->ctime = SWAP_LE32(this->st.st_ctime); | 428 in->ctime = SWAP_LE32(that->st.st_ctime); |
401 in->mtime = SWAP_LE32(this->st.st_mtime); | 429 in->mtime = SWAP_LE32(that->st.st_mtime); |
402 | 430 |
403 in->links_count = SWAP_LE16(this->st.st_nlink); | 431 in->links_count = SWAP_LE16(that->st.st_nlink); |
404 in->blocks = SWAP_LE32(this->st.st_blocks); | 432 in->blocks = SWAP_LE32(that->st.st_blocks); |
405 // in->faddr | 433 // in->faddr |
406 } | 434 } |
407 | 435 |
408 // Works like an archiver. | 436 // Works like an archiver. |
409 // The first argument is the name of the file to create. If it already | 437 // The first argument is the name of the file to create. If it already |