1 /* 2 ext2_mkfs.c -- ext2 fs creator 3 Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <config.h> 20 21 #ifndef DISCOVER_ONLY 22 23 #define USE_EXT2_IS_DATA_BLOCK 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <sys/stat.h> 29 #include <time.h> 30 #include <unistd.h> 31 #include <uuid/uuid.h> 32 #include "ext2.h" 33 34 /* formula grabbed from linux ext2 kernel source 35 * 36 * returns 1 iff: 37 * x == y^N, N is some natural number 38 * OR x == 0 39 */ 40 static __inline__ int is_root(int x, int y) 41 { 42 if (!x) return 1; 43 44 while (1) 45 { 46 if (x == 1) return 1; 47 48 if (x % y) return 0; 49 50 x /= y; 51 } 52 } 53 54 static __inline__ int is_group_sparse(int sparsesbfs, int group) 55 { 56 if (!sparsesbfs) 57 return 1; 58 59 if (is_root(group, 3) || is_root(group, 5) || is_root(group, 7)) 60 return 1; 61 62 return 0; 63 } 64 65 /* has implicit parameter 'sb' !! */ 66 #define is_sparse(group) is_group_sparse(EXT2_SUPER_FEATURE_RO_COMPAT(*sb) \ 67 & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER, (group)) 68 69 static int ext2_mkfs_write_main(struct ext2_dev_handle *handle, 70 struct ext2_super_block *sb, 71 struct ext2_group_desc *gd) 72 { 73 int freeit; 74 int i; 75 int numgroups; 76 int gdblocks; 77 unsigned char *sbbuf; 78 struct ext2_super_block *sb_for_io; 79 80 freeit = 0; 81 sbbuf = (unsigned char *)sb; 82 sb_for_io = sb; 83 if (EXT2_SUPER_LOG_BLOCK_SIZE(*sb)) 84 { 85 sbbuf = ped_malloc(1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)); 86 if (!(handle->ops->read)(handle->cookie, sbbuf, 0, 1)) 87 return 0; 88 memcpy (sbbuf+1024, sb, 1024); 89 freeit = 1; 90 sb_for_io = (struct ext2_super_block*) (sbbuf + 1024); 91 } 92 93 numgroups = ped_div_round_up (EXT2_SUPER_BLOCKS_COUNT(*sb) 94 - EXT2_SUPER_FIRST_DATA_BLOCK(*sb), 95 EXT2_SUPER_BLOCKS_PER_GROUP(*sb)); 96 gdblocks = ped_div_round_up (numgroups * sizeof(struct ext2_group_desc), 97 1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)); 98 99 for (i=0;i<numgroups;i++) 100 { 101 if (is_sparse(i)) 102 { 103 int offset; 104 105 offset = EXT2_SUPER_FIRST_DATA_BLOCK(*sb) 106 + i * EXT2_SUPER_BLOCKS_PER_GROUP(*sb); 107 108 sb_for_io->s_block_group_nr = PED_CPU_TO_LE16 (i); 109 110 if (!handle->ops->write(handle->cookie, sbbuf, 111 offset, 1)) 112 return 0; 113 if (!handle->ops->write(handle->cookie, gd, offset+1, 114 gdblocks)) 115 return 0; 116 } 117 } 118 119 sb_for_io->s_block_group_nr = 0; 120 121 if (freeit) 122 ped_free(sbbuf); 123 return 1; 124 } 125 126 static int ext2_mkfs_write_meta(struct ext2_dev_handle *handle, 127 struct ext2_super_block *sb, 128 struct ext2_group_desc *gd, 129 PedTimer* timer) 130 { 131 int blocksize; 132 int gdtsize; 133 int i; 134 int itsize; 135 int numgroups; 136 unsigned char *bb; 137 unsigned char *ib; 138 unsigned char *zero; 139 140 blocksize = 1 << (EXT2_SUPER_LOG_BLOCK_SIZE(*sb) + 13); 141 142 numgroups = ped_div_round_up (EXT2_SUPER_BLOCKS_COUNT(*sb) 143 - EXT2_SUPER_FIRST_DATA_BLOCK(*sb), 144 EXT2_SUPER_BLOCKS_PER_GROUP(*sb)); 145 itsize = ped_div_round_up (sizeof(struct ext2_inode) 146 * EXT2_SUPER_INODES_PER_GROUP(*sb), 147 (1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb))); 148 gdtsize = ped_div_round_up (sizeof(struct ext2_group_desc) * numgroups, 149 (1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb))); 150 151 bb = ped_malloc(1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)); 152 if (!bb) goto error; 153 ib = ped_malloc(1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)); 154 if (!ib) goto error_free_bb; 155 zero = ped_malloc((1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)) * itsize); 156 if (!zero) goto error_free_zero; 157 158 memset(zero, 0, (1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)) * itsize); 159 160 ped_timer_reset (timer); 161 ped_timer_set_state_name (timer, _("writing per-group metadata")); 162 163 for (i=0;i<numgroups;i++) 164 { 165 int admin; 166 blk_t bbblock; 167 int groupsize; 168 int groupoffset; 169 blk_t ibblock; 170 int j; 171 172 ped_timer_update (timer, 1.0 * i / numgroups); 173 174 groupoffset = i*EXT2_SUPER_BLOCKS_PER_GROUP(*sb) 175 + EXT2_SUPER_FIRST_DATA_BLOCK(*sb); 176 groupsize = PED_MIN(EXT2_SUPER_BLOCKS_COUNT(*sb) - groupoffset, 177 EXT2_SUPER_BLOCKS_PER_GROUP(*sb)); 178 179 admin = itsize + 2; 180 bbblock = groupoffset; 181 ibblock = groupoffset + 1; 182 if (is_sparse(i)) 183 { 184 admin += gdtsize + 1; 185 bbblock = groupoffset + gdtsize + 1; 186 ibblock = groupoffset + gdtsize + 2; 187 } 188 189 { 190 memset(bb, 0, 1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)); 191 if (is_sparse(i)) 192 for (j=0;j<gdtsize+1;j++) 193 bb[j>>3] |= _bitmap[j&7]; 194 195 j = bbblock - groupoffset; 196 bb[j>>3] |= _bitmap[j&7]; 197 198 j = ibblock - groupoffset; 199 bb[j>>3] |= _bitmap[j&7]; 200 201 for (j=0;j<itsize;j++) 202 { 203 int k = j + gdtsize + 3; 204 205 bb[k>>3] |= _bitmap[k&7]; 206 } 207 208 for (j=groupsize;j<blocksize;j++) 209 bb[j>>3] |= _bitmap[j&7]; 210 211 if (!handle->ops->write(handle->cookie, bb, bbblock, 1)) 212 goto error_free_zero; 213 } 214 215 { 216 memset(ib, 0, 1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)); 217 218 for (j=EXT2_SUPER_INODES_PER_GROUP(*sb);j<blocksize;j++) 219 bb[j>>3] |= _bitmap[j&7]; 220 221 if (!handle->ops->write(handle->cookie, ib, ibblock, 1)) 222 goto error_free_zero; 223 } 224 225 if (!handle->ops->write(handle->cookie, zero, 226 groupoffset + gdtsize + 3, itsize)) 227 goto error_free_zero; 228 229 gd[i].bg_block_bitmap = PED_CPU_TO_LE32(bbblock); 230 gd[i].bg_inode_bitmap = PED_CPU_TO_LE32(ibblock); 231 gd[i].bg_inode_table = PED_CPU_TO_LE32(groupoffset + gdtsize 232 + 3); 233 gd[i].bg_free_blocks_count = PED_CPU_TO_LE16(groupsize - admin); 234 gd[i].bg_free_inodes_count = PED_CPU_TO_LE16( 235 EXT2_SUPER_INODES_PER_GROUP(*sb)); 236 gd[i].bg_used_dirs_count = 0; 237 gd[i].bg_used_dirs_count = 0; 238 gd[i].bg_pad = 0; 239 gd[i].bg_reserved[0] = 0; 240 gd[i].bg_reserved[1] = 0; 241 gd[i].bg_reserved[2] = 0; 242 243 sb->s_free_blocks_count = PED_CPU_TO_LE32 ( 244 EXT2_SUPER_FREE_BLOCKS_COUNT(*sb) 245 + EXT2_GROUP_FREE_BLOCKS_COUNT(gd[i])); 246 } 247 248 ped_timer_update (timer, 1.0); 249 250 ped_free(zero); 251 ped_free(ib); 252 ped_free(bb); 253 return 1; 254 255 error_free_zero: 256 ped_free(zero); 257 ped_free(ib); 258 error_free_bb: 259 ped_free(bb); 260 error: 261 return 0; 262 } 263 264 /* returns the offset into the buffer of the start of the next dir entry */ 265 static int _set_dirent(void* buf, int offset, int block_size, int is_last, 266 uint32_t inode, char* name, int file_type) 267 { 268 struct ext2_dir_entry_2 *dirent = (void*) (((char*)buf) + offset); 269 int name_len = strlen(name); 270 int rec_len; 271 272 if (is_last) 273 rec_len = block_size - offset; 274 else 275 rec_len = ped_round_up_to(name_len + 1 + 8, 4); 276 277 memset (dirent, 0, rec_len); 278 279 dirent->inode = PED_CPU_TO_LE32(inode); 280 dirent->name_len = name_len; 281 dirent->rec_len = PED_CPU_TO_LE16(rec_len); 282 dirent->file_type = file_type; 283 strcpy(dirent->name, name); 284 285 return offset + rec_len; 286 } 287 288 static int ext2_mkfs_create_lost_and_found_inode(struct ext2_fs *fs) 289 { 290 struct ext2_buffer_head *bh; 291 blk_t blocks[12]; 292 uint32_t* data = ped_malloc ((fs->blocksize / 4) * sizeof(uint32_t)); 293 int i; 294 struct ext2_inode inode; 295 int offset; 296 297 for (i=0;i<12;i++) 298 { 299 if (!(blocks[i] = ext2_find_free_block(fs))) 300 return 0; 301 302 if (!ext2_set_block_state(fs, blocks[i], 1, 1)) 303 return 0; 304 } 305 306 /* create the directory entries, preallocating lots of blocks */ 307 /* first block contains . and .. */ 308 bh = ext2_bcreate(fs, blocks[0]); 309 if (!bh) 310 return 0; 311 memset(bh->data, 0, fs->blocksize); 312 offset = _set_dirent(bh->data, 0, fs->blocksize, 0, 313 11, ".", EXT2_FT_DIR); 314 offset = _set_dirent(bh->data, offset, fs->blocksize, 1, 315 EXT2_ROOT_INO, "..", EXT2_FT_DIR); 316 bh->dirty = 1; 317 ext2_brelse(bh, 1); 318 319 /* subsequent blocks are empty */ 320 memset(data, 0, fs->blocksize); 321 data[0] = 0; 322 data[1] = PED_CPU_TO_LE32(fs->blocksize); 323 for (i=1;i<12;i++) 324 { 325 bh = ext2_bcreate(fs, blocks[i]); 326 memcpy(bh->data, data, fs->blocksize); 327 bh->dirty = 1; 328 ext2_brelse(bh, 1); 329 } 330 331 /* create inode */ 332 memset(&inode, 0, sizeof(struct ext2_inode)); 333 inode.i_mode = PED_CPU_TO_LE16(S_IFDIR | 0755); 334 inode.i_uid = 0; 335 inode.i_size = PED_CPU_TO_LE32(12 * fs->blocksize); 336 inode.i_atime = PED_CPU_TO_LE32(time(NULL)); 337 inode.i_ctime = PED_CPU_TO_LE32(time(NULL)); 338 inode.i_mtime = PED_CPU_TO_LE32(time(NULL)); 339 inode.i_dtime = 0; 340 inode.i_gid = 0; 341 inode.i_links_count = PED_CPU_TO_LE16(2); 342 inode.i_blocks = PED_CPU_TO_LE32((12 * fs->blocksize) >> 9); 343 inode.i_flags = 0; 344 for (i=0;i<12;i++) 345 inode.i_block[i] = PED_CPU_TO_LE32(blocks[i]); 346 347 if (!ext2_write_inode(fs, 11, &inode)) 348 return 0; 349 fs->gd[0].bg_used_dirs_count = PED_CPU_TO_LE16( 350 EXT2_GROUP_USED_DIRS_COUNT(fs->gd[0]) + 1); 351 fs->metadirty |= EXT2_META_GD; 352 353 return 1; 354 } 355 356 static int ext2_mkfs_create_root_inode(struct ext2_fs *fs) 357 { 358 struct ext2_buffer_head *bh; 359 blk_t block; 360 struct ext2_inode inode; 361 int offset; 362 363 if (!(block = ext2_find_free_block(fs))) 364 return 0; 365 if (!ext2_set_block_state(fs, block, 1, 1)) 366 return 0; 367 368 /* create directory entries */ 369 bh = ext2_bcreate(fs, block); 370 memset(bh->data, 0, fs->blocksize); 371 offset = _set_dirent(bh->data, 0, fs->blocksize, 0, 372 EXT2_ROOT_INO, ".", EXT2_FT_DIR); 373 offset = _set_dirent(bh->data, offset, fs->blocksize, 0, 374 EXT2_ROOT_INO, "..", EXT2_FT_DIR); 375 offset = _set_dirent(bh->data, offset, fs->blocksize, 1, 376 11, "lost+found", EXT2_FT_DIR); 377 bh->dirty = 1; 378 if (!ext2_brelse(bh, 1)) 379 return 0; 380 381 /* create inode */ 382 memset(&inode, 0, sizeof(struct ext2_inode)); 383 inode.i_mode = PED_CPU_TO_LE16(S_IFDIR | 0755); 384 inode.i_uid = 0; 385 inode.i_size = PED_CPU_TO_LE32(fs->blocksize); 386 inode.i_atime = PED_CPU_TO_LE32(time(NULL)); 387 inode.i_ctime = PED_CPU_TO_LE32(time(NULL)); 388 inode.i_mtime = PED_CPU_TO_LE32(time(NULL)); 389 inode.i_dtime = 0; 390 inode.i_gid = 0; 391 inode.i_links_count = PED_CPU_TO_LE16(3); 392 inode.i_blocks = PED_CPU_TO_LE32(fs->blocksize >> 9); 393 inode.i_flags = 0; 394 inode.i_block[0] = PED_CPU_TO_LE32(block); 395 396 if (!ext2_write_inode(fs, 2, &inode)) 397 return 0; 398 fs->gd[0].bg_used_dirs_count = PED_CPU_TO_LE16 ( 399 EXT2_GROUP_USED_DIRS_COUNT(fs->gd[0]) + 1); 400 fs->metadirty |= EXT2_META_GD; 401 402 return 1; 403 } 404 405 static int ext2_reserve_inodes(struct ext2_fs *fs) 406 { 407 int i; 408 409 for (i=1;i<12;i++) 410 if (!ext2_set_inode_state(fs, i, 1, 1)) 411 return 0; 412 return 1; 413 } 414 415 static int ext2_mkfs_init_sb (struct ext2_super_block *sb, blk_t numblocks, 416 int numgroups, int first_block, 417 int log_block_size, blk_t blocks_per_group, 418 int inodes_per_group, int sparse_sb, 419 int reserved_block_percentage) 420 { 421 /* catch a bug in gcc 2.95.2 */ 422 PED_ASSERT(numgroups != 0, return 0); 423 424 memset(sb, 0, 1024); 425 426 sb->s_inodes_count = PED_CPU_TO_LE32(numgroups * inodes_per_group); 427 sb->s_blocks_count = PED_CPU_TO_LE32(numblocks); 428 sb->s_r_blocks_count = PED_CPU_TO_LE32(((uint64_t)numblocks 429 * reserved_block_percentage) / 100); 430 431 /* hack: this get's inc'd as we go through each group in 432 * ext2_mkfs_write_meta() 433 */ 434 sb->s_free_blocks_count = 0; 435 sb->s_free_inodes_count = PED_CPU_TO_LE32 (numgroups 436 * inodes_per_group); 437 sb->s_first_data_block = PED_CPU_TO_LE32(first_block); 438 sb->s_log_block_size = PED_CPU_TO_LE32(log_block_size - 10); 439 sb->s_log_frag_size = sb->s_log_block_size; 440 sb->s_blocks_per_group = PED_CPU_TO_LE32(blocks_per_group); 441 sb->s_frags_per_group = PED_CPU_TO_LE32(blocks_per_group); 442 sb->s_inodes_per_group = PED_CPU_TO_LE32(inodes_per_group); 443 sb->s_mtime = 0; 444 sb->s_wtime = 0; 445 sb->s_mnt_count = 0; 446 sb->s_max_mnt_count = PED_CPU_TO_LE16(30); 447 sb->s_magic = PED_CPU_TO_LE16(0xEF53); 448 sb->s_state = PED_CPU_TO_LE16(EXT2_VALID_FS); 449 sb->s_errors = PED_CPU_TO_LE16(EXT2_ERRORS_DEFAULT); 450 sb->s_minor_rev_level = 0; 451 sb->s_lastcheck = 0; 452 sb->s_checkinterval = 0; 453 sb->s_creator_os = 0; 454 sb->s_rev_level = PED_CPU_TO_LE32(1); 455 sb->s_def_resuid = 0; 456 sb->s_def_resgid = 0; 457 sb->s_first_ino = PED_CPU_TO_LE32(11); 458 sb->s_inode_size = PED_CPU_TO_LE16(128); 459 sb->s_block_group_nr = 0; 460 sb->s_feature_compat = 0; 461 sb->s_feature_incompat = 0; 462 sb->s_feature_ro_compat = 0; 463 if (sparse_sb) 464 sb->s_feature_ro_compat 465 |= PED_CPU_TO_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER); 466 467 /* FIXME: let the user decide? _set_dirent() assumes FILETYPE */ 468 sb->s_feature_incompat 469 |= PED_CPU_TO_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE); 470 471 uuid_generate(sb->s_uuid); 472 memset(sb->s_volume_name, 0, 16); 473 memset(sb->s_last_mounted, 0, 64); 474 sb->s_algorithm_usage_bitmap = 0; 475 sb->s_prealloc_blocks = 0; 476 sb->s_prealloc_dir_blocks = 0; 477 sb->s_padding1 = 0; 478 479 return 1; 480 } 481 482 /* Given these five inputs, compute the three outputs. */ 483 static void 484 compute_block_counts (blk_t numblocks, int numgroups, int log_block_size, 485 int sparse_sb, blk_t blocks_per_group, 486 int *last_group_blocks, 487 int *last_group_admin, 488 int *inodes_per_group) 489 { 490 int first_block = (log_block_size == 10) ? 1 : 0; 491 size_t block_size = 1 << log_block_size; 492 493 *last_group_blocks = ((numblocks - first_block) % blocks_per_group); 494 if (!*last_group_blocks) 495 *last_group_blocks = blocks_per_group; 496 *inodes_per_group = ped_round_up_to (numblocks / numgroups / 2, 497 (block_size 498 / sizeof(struct ext2_inode))); 499 *last_group_admin = (2 + *inodes_per_group * sizeof(struct ext2_inode) 500 / block_size); 501 if (is_group_sparse(sparse_sb, numgroups - 1)) { 502 *last_group_admin += 503 (ped_div_round_up (numgroups * sizeof(struct ext2_group_desc), 504 block_size)); 505 } 506 } 507 508 struct ext2_fs *ext2_mkfs(struct ext2_dev_handle *handle, 509 blk_t numblocks, 510 int log_block_size, 511 blk_t blocks_per_group, 512 int inodes_per_group, 513 int sparse_sb, 514 int reserved_block_percentage, 515 PedTimer* timer) 516 { 517 struct ext2_fs *fs; 518 struct ext2_super_block sb; 519 struct ext2_group_desc *gd; 520 int numgroups; 521 int first_block; 522 int last_group_blocks; 523 int last_group_admin; 524 525 /* if the FS is > 512Mb, use 4k blocks, otherwise 1k blocks */ 526 if (log_block_size == 0) { 527 handle->ops->set_blocksize(handle->cookie, 12); 528 if (handle->ops->get_size(handle->cookie) > (512 * 1024)) 529 log_block_size = 12; 530 else 531 log_block_size = 10; 532 } 533 534 /* FIXME: block size must be > MAX(logicalbs, physicalbs) 535 * to avoid modify-on-write. 536 * -- Leslie 537 */ 538 539 540 handle->ops->set_blocksize(handle->cookie, log_block_size); 541 542 if (numblocks == 0) 543 numblocks = handle->ops->get_size(handle->cookie); 544 if (numblocks == 0) 545 goto diagnose_fs_too_small; 546 547 if (blocks_per_group == (unsigned int) 0) 548 blocks_per_group = 8 << log_block_size; 549 550 first_block = (log_block_size == 10) ? 1 : 0; 551 552 numgroups = ped_div_round_up (numblocks 553 - first_block, blocks_per_group); 554 555 if (sparse_sb == -1) 556 sparse_sb = 1; 557 558 /* FIXME: 5% not appropriate for modern drive sizes */ 559 if (reserved_block_percentage == -1) 560 reserved_block_percentage = 5; 561 562 compute_block_counts (numblocks, numgroups, log_block_size, sparse_sb, 563 blocks_per_group, &last_group_blocks, 564 &last_group_admin, &inodes_per_group); 565 566 int fs_too_small = 0; 567 if (last_group_admin + 1 >= last_group_blocks) 568 { 569 numgroups--; 570 if (numgroups == 0) 571 fs_too_small = 1; 572 else 573 { 574 numblocks -= last_group_blocks; 575 compute_block_counts (numblocks, numgroups, log_block_size, 576 sparse_sb, blocks_per_group, 577 &last_group_blocks, &last_group_admin, 578 &inodes_per_group); 579 } 580 } 581 582 if (numgroups == 1 583 && (last_group_blocks - last_group_admin < 8 584 || inodes_per_group < 16 585 /* This final term ensures that we detect 586 mkpartfs primary ext2 10KB 27650B as invalid. */ 587 || (inodes_per_group == 16 588 && last_group_blocks - last_group_admin < 14))) 589 fs_too_small = 1; 590 591 if (fs_too_small) { 592 diagnose_fs_too_small: 593 ped_exception_throw ( 594 PED_EXCEPTION_ERROR, 595 PED_EXCEPTION_CANCEL, 596 _("File system too small for ext2.")); 597 goto error; 598 } 599 600 gd = ped_malloc(numgroups * sizeof(struct ext2_group_desc) 601 + (1 << log_block_size)); 602 if (!gd) 603 goto error; 604 605 if (!ext2_mkfs_init_sb(&sb, numblocks, numgroups, first_block, 606 log_block_size, blocks_per_group, 607 inodes_per_group, sparse_sb, 608 reserved_block_percentage)) 609 goto error_free_gd; 610 if (!ext2_mkfs_write_meta(handle, &sb, gd, timer)) 611 goto error_free_gd; 612 if (!ext2_mkfs_write_main(handle, &sb, gd)) 613 goto error_free_gd; 614 615 fs = ext2_open(handle, 0); 616 if (!fs) goto error_close_fs; 617 if (!ext2_reserve_inodes(fs)) goto error_close_fs; 618 if (!ext2_mkfs_create_root_inode(fs)) goto error_close_fs; 619 if (!ext2_mkfs_create_lost_and_found_inode(fs)) 620 goto error_close_fs; 621 if (!ext2_sync(fs)) goto error_close_fs; 622 ped_free(gd); 623 return fs; 624 625 error_close_fs: 626 ext2_close(fs); 627 error_free_gd: 628 ped_free (gd); 629 error: 630 return NULL; 631 } 632 #endif /* !DISCOVER_ONLY */