int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *filename = "/"; int dev=0; int part=1; char *ep; block_dev_desc_t *dev_desc=NULL; int part_length; if (argc < 3) { printf ("Usage:\n%s\n", cmdtp->usage); return(1); } dev = (int)simple_strtoul (argv[2], &ep, 16); //printf("argv[1] = %s dev =%d",argv[1],dev); dev_desc = get_dev(argv[1],dev); if (dev_desc == NULL) { printf ("\n** Block device %s %d not supported\n", argv[1], dev); return(1); } if (*ep) { if (*ep != ':') { puts ("\n** Invalid boot device, use `dev[:part]' **\n"); return(1); } part = (int)simple_strtoul(++ep, NULL, 16); } if (argc == 4) { filename = argv[3]; } PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename); if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) { printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); ext2fs_close(); return(1); } if (!ext2fs_mount(part_length)) { printf ("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part); ext2fs_close(); return(1); } if (ext2fs_ls (filename)) { printf ("** Error ext2fs_ls() **\n"); ext2fs_close(); return(1); }; ext2fs_close(); return(0); }
static int get_resize_stats(struct resize_stats *stats, char *key_loc, char *blk_device) { errcode_t retval; ext2_filsys fs; ext2_filsys dup_fs; io_manager io_ptr; long long data_partition_size = 0; io_ptr = unix_io_manager; retval = ext2fs_open2(blk_device, NULL , 0, 0, 0, io_ptr, &fs); if (retval) { ERROR("Couldn't find valid filesystem superblock.\n"); return -1; } retval = ext2fs_dup_handle(fs, &dup_fs); if (retval) { ERROR("Couldn't duplicate filesys.\n"); ext2fs_close(fs); return -1; } if((data_partition_size = get_block_size(blk_device)) < 0) { ERROR("Get %s partition size fail.\n", blk_device); ext2fs_close(fs); ext2fs_free(dup_fs); return -1; } ERROR("Size for partition(%s) is %lluK.\n", blk_device, data_partition_size / 1024); ERROR("Size in superblock is %lluK.\n", (unsigned long long)fs->super->s_blocks_count * fs->blocksize / 1024); if (!strcmp(key_loc, KEY_IN_FOOTER)){ data_partition_size -= RESERVE_SIZE; ERROR("There is key in footer of partition(%s).\n", blk_device); } //adjust partition size to meet resizefs rule. //resizefs will adjust partition size in some case. retval = adjust_fs_size(dup_fs, &data_partition_size); if (retval) { ERROR("Couldn't adjust partition size.\n"); ext2fs_close(fs); ext2fs_free(dup_fs); return -1; } ERROR("Size will (maybe) resize to(after adjust) is %lluK.\n", data_partition_size / 1024); if((unsigned int)(data_partition_size / fs->blocksize) == (unsigned int)(fs->super->s_blocks_count)) { ERROR("The size of data already meet the request(size in superblock = size after adjust).\n"); stats->state = STATS_RESIZED; } stats->size = data_partition_size; ext2fs_close(fs); ext2fs_free(dup_fs); return 0; }
int extfs_mount(char *partition, char *mntbuf, char *fsbuf, int flags, char *mntinfo) { blk_t use_superblock=0; int use_blocksize=0; ext2_filsys fs; int origextfstype; char fsname[32]; msgprintf(MSG_DEBUG1, "extfs_mount(partition=[%s], mnt=[%s], fsbuf=[%s])\n", partition, mntbuf, fsbuf); if (ext2fs_open(partition, EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SOFTSUPP_FEATURES, use_superblock, use_blocksize, unix_io_manager, &fs)!=0) { msgprintf(MSG_DEBUG1, "ext2fs_open(%s) failed\n", partition); return -1; } origextfstype=extfs_get_fstype_from_compat_flags((u64)fs->super->s_feature_compat, (u64)fs->super->s_feature_incompat, (u64)fs->super->s_feature_ro_compat); snprintf(fsname, sizeof(fsname), "%s", format_fstype(origextfstype)); msgprintf(MSG_VERB2, "the filesystem of [%s] type determined by the features is [%s]\n", partition, fsname); ext2fs_close(fs); if (strcmp(fsname, fsbuf)!=0) { msgprintf(MSG_DEBUG1, "extfs_mount: the filesystem requested [%s] does not match the filesystem detected [%s]\n", fsbuf, fsname); return -1; } return generic_mount(partition, mntbuf, fsbuf, "user_xattr,acl", flags); }
int main (int argc, char ** argv) { errcode_t retval; ext2_filsys fs; io_manager io_ptr; initialize_ext2_error_table(); blkid_get_cache(&cache, NULL); PRS(argc, argv); #ifdef CONFIG_TESTIO_DEBUG io_ptr = test_io_manager; test_io_backing_manager = unix_io_manager; #else io_ptr = unix_io_manager; #endif retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs); if (retval) exit(1); if (root_type) get_root_type(fs); return (ext2fs_close (fs) ? 1 : 0); }
int main (int argc, char ** argv) { errcode_t retval; ext2_filsys fs; io_manager io_ptr; add_error_table(&et_ext2_error_table); blkid_get_cache(&cache, NULL); PRS(argc, argv); #ifdef CONFIG_TESTIO_DEBUG if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { io_ptr = test_io_manager; test_io_backing_manager = unix_io_manager; } else #endif io_ptr = unix_io_manager; retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs); if (retval) exit(1); if (root_type) get_root_type(fs); remove_error_table(&et_ext2_error_table); return (ext2fs_close (fs) ? 1 : 0); }
main(int argc, char **argv) { errcode_t retval; char *device_name; ext2_filsys fs; if (argc < 2) { fprintf(stderr, "Usage: %s filesystem\n", argv[0]); exit(1); } device_name = argv[1]; retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0, unix_io_manager, &fs); if (retval) { com_err(argv[0], retval, "while opening %s", device_name); exit(1); } retval = ext2fs_add_journal_inode(fs, 1024, 0); if (retval) { com_err(argv[0], retval, "while adding journal to %s", device_name); exit(1); } retval = ext2fs_flush(fs); if (retval) { printf("Warning, had trouble writing out superblocks.\n"); } ext2fs_close(fs); exit(0); }
void * op_init (struct fuse_conn_info *conn) { errcode_t rc; struct fuse_context *cntx=fuse_get_context(); struct extfs_data *e2data=cntx->private_data; debugf("enter %s", e2data->device); rc = ext2fs_open(e2data->device, (e2data->readonly) ? 0 : EXT2_FLAG_RW, 0, 0, unix_io_manager, &e2data->e2fs); if (rc) { debugf("Error while trying to open %s", e2data->device); exit(1); } #if 1 if (e2data->readonly != 1) #endif rc = ext2fs_read_bitmaps(e2data->e2fs); if (rc) { debugf("Error while reading bitmaps"); ext2fs_close(e2data->e2fs); exit(1); } debugf("FileSystem %s", (e2data->e2fs->flags & EXT2_FLAG_RW) ? "Read&Write" : "ReadOnly"); debugf("leave"); return e2data; }
int extfs_get_reqmntopt(char *partition, cstrlist *reqopt, cstrlist *badopt) { blk_t use_superblock=0; int use_blocksize=0; u32 defmntoptmask; ext2_filsys fs; if (!reqopt || !badopt) return -1; // check the "default mount options" if (ext2fs_open(partition, EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SOFTSUPP_FEATURES, use_superblock, use_blocksize, unix_io_manager, &fs)!=0) return -1; defmntoptmask=fs->super->s_default_mount_opts; if (!(defmntoptmask&EXT2_DEFM_XATTR_USER)) strlist_add(reqopt, "user_xattr"); if (!(defmntoptmask&EXT2_DEFM_ACL)) strlist_add(reqopt, "acl"); strlist_add(badopt, "nouser_xattr"); strlist_add(badopt, "noacl"); ext2fs_close(fs); return 0; }
static void dir_partition_ext2_close(dir_data_t *dir_data) { struct ext2_dir_struct *ls=(struct ext2_dir_struct *)dir_data->private_dir_data; ext2fs_close (ls->current_fs); /* ext2fs_close call the close function that freed my_data */ free(ls); }
static void undelfs_shutdown (void) { if (fs) ext2fs_close (fs); fs = NULL; MC_PTR_FREE (ext2_fname); MC_PTR_FREE (delarray); MC_PTR_FREE (block_buf); }
int main (int argc, char *argv[]) { errcode_t retval = 0; int exit_value = 0; int i; ext2_filsys fs; ext2_inode_scan scan; ext2_ino_t ino; struct ext2_inode inode; printf(_("size of inode=%d\n"), sizeof(inode)); device_name = "/dev/hda3"; init_resource_track(&global_rtrack); retval = ext2fs_open(device_name, 0, 0, 0, unix_io_manager, &fs); if (retval) { com_err(argv[0], retval, _("while trying to open %s"), device_name); exit(1); } retval = ext2fs_open_inode_scan(fs, 0, &scan); if (retval) { com_err(argv[0], retval, _("while opening inode scan")); exit(1); } retval = ext2fs_get_next_inode(scan, &ino, &inode); if (retval) { com_err(argv[0], retval, _("while starting inode scan")); exit(1); } while (ino) { if (!inode.i_links_count) goto next; printf("%lu\n", inode.i_blocks); next: retval = ext2fs_get_next_inode(scan, &ino, &inode); if (retval) { com_err(argv[0], retval, _("while doing inode scan")); exit(1); } } ext2fs_close(fs); print_resource_track(&global_rtrack); return exit_value; }
static int ext2lib_umount(fsi_t *fsi) { ext2_filsys *fs = fsip_fs_data(fsi); if (ext2fs_close(*fs) != 0) { free(fs); errno = EINVAL; return (-1); } free(fs); return (0); }
/********************************************************************** Function :check_ext2_usb Descriptor : Input : part: partition Output : none return : 0: success 1: not ext2 2: ext2,but lost file Notice : **********************************************************************/ int check_ext2_usb(int part) { int nfile; char *filename_kernel = "vmlinux.ub"; int dev=0; block_dev_desc_t *dev_desc=NULL; int part_length; dev_desc = get_dev("usb",0); //first partition if (dev_desc == NULL) { printf ("[error]: Block dev not supported\n"); return(1); } part_length = ext2fs_set_blk_dev(dev_desc, part); if (part_length == 0) { ext2fs_close(); return(1); } if (!ext2fs_mount(part_length)) //if ext2 type { ext2fs_close(); return(1); } if (ext2fs_open(filename_kernel) < 0) { printf("[error]:Kernel not found %s ...\n", filename_kernel); ext2fs_close(); return(2); } ext2fs_close(); return(0); }
static void undelfs_shutdown (void) { if (fs) ext2fs_close (fs); fs = NULL; g_free (ext2_fname); ext2_fname = NULL; g_free (delarray); delarray = NULL; g_free (block_buf); block_buf = NULL; }
long open_filesystem(char *name, ext2_filsys *fs, ext2_ino_t *root, int rw_mode) { int retval; int closeval; if ((retval = ext2fs_open(name, (rw_mode) ? EXT2_FLAG_RW : 0, 0, 0, unix_io_manager, fs))) { fprintf(stderr, "%s\n", error_message(retval)); *fs = NULL; return retval; } if ((retval = ext2fs_read_inode_bitmap(*fs))) { fprintf(stderr, "%s\n", error_message(retval)); if ((closeval = ext2fs_close(*fs))) fputs(error_message(closeval), stderr); *fs = NULL; return retval; } if ((retval = ext2fs_read_block_bitmap(*fs))) { fprintf(stderr, "%s\n", error_message(retval)); if ((closeval = ext2fs_close(*fs))) fputs(error_message(closeval), stderr); *fs = NULL; return retval; } *root = EXT2_ROOT_INO; return(0); }
void preenhalt(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; if (!(ctx->options & E2F_OPT_PREEN)) return; fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; " "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"), ctx->device_name); if (fs != NULL) { fs->super->s_state |= EXT2_ERROR_FS; ext2fs_mark_super_dirty(fs); ext2fs_close(fs); } exit(FSCK_UNCORRECTED); }
const char *ext2_uuid(char *device) { errcode_t e2fserr; ext2_filsys fs; const char *uuid; e2fserr = ext2fs_open(device, 0, 0, 0, unix_io_manager, &fs); if (e2fserr) { uuid = "<none>"; } else { uuid = uuid2str(fs->super->s_uuid); e2fserr = ext2fs_close(fs); } return uuid; }
int main(int argc, char **argv) { ext2_filsys fs; ext2fs_generic_bitmap bitmap; size_t size; ext2fs_open(argv[1], 0, 0, 0, unix_io_manager, &fs); ext2fs_read_bitmaps(fs); ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), &bitmap); memcpy(bitmap, fs->block_map, sizeof(struct ext2fs_struct_generic_bitmap)); size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1); printf("sBlock: %u\n", fs->blocksize); printf("sBitmap: %u\n", bitmap->real_end - bitmap->start + 1); printf("bitmap: "); fwrite(bitmap->bitmap, 1, size, stdout); ext2fs_close(fs); return 0; }
int extfs_test(char *partition, int extfstype) // returns true if it's that sort of filesystem { blk_t use_superblock=0; int use_blocksize=0; int extfstypedetected; ext2_filsys fs; if (ext2fs_open(partition, EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SOFTSUPP_FEATURES, use_superblock, use_blocksize, unix_io_manager, &fs)!=0) return false; extfstypedetected=extfs_get_fstype_from_compat_flags((u64)fs->super->s_feature_compat, (u64)fs->super->s_feature_incompat, (u64)fs->super->s_feature_ro_compat); msgprintf(MSG_DEBUG1, "the filesystem type determined by the extfs features is [%s]\n", format_fstype(extfstypedetected)); ext2fs_close(fs); // if detected is what is tested, say yes return (extfstypedetected==extfstype); }
static void close_filesystem(NOARGS) { int retval; if (current_fs->flags & EXT2_FLAG_IB_DIRTY) { retval = ext2fs_write_inode_bitmap(current_fs); if (retval) com_err("ext2fs_write_inode_bitmap", retval, 0); } if (current_fs->flags & EXT2_FLAG_BB_DIRTY) { retval = ext2fs_write_block_bitmap(current_fs); if (retval) com_err("ext2fs_write_block_bitmap", retval, 0); } retval = ext2fs_close(current_fs); if (retval) com_err("ext2fs_close", retval, 0); current_fs = NULL; return; }
int e2fsck_run_ext3_journal(e2fsck_t ctx) { io_manager io_ptr = ctx->fs->io->manager; int blocksize = ctx->fs->blocksize; errcode_t retval, recover_retval; printf(_("%s: recovering journal\n"), ctx->device_name); if (ctx->options & E2F_OPT_READONLY) { printf(_("%s: won't do journal recovery while read-only\n"), ctx->device_name); return EXT2_ET_FILE_RO; } if (ctx->fs->flags & EXT2_FLAG_DIRTY) ext2fs_flush(ctx->fs); /* Force out any modifications */ recover_retval = recover_ext3_journal(ctx); /* * Reload the filesystem context to get up-to-date data from disk * because journal recovery will change the filesystem under us. */ ext2fs_close(ctx->fs); retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW, ctx->superblock, blocksize, io_ptr, &ctx->fs); if (retval) { com_err(ctx->program_name, retval, _("while trying to re-open %s"), ctx->device_name); fatal_error(ctx, 0); } ctx->fs->priv_data = ctx; ctx->fs->now = ctx->now; ctx->fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; /* Set the superblock flags */ e2fsck_clear_recover(ctx, recover_retval); return recover_retval; }
/* function taken from anaconda/isys.c */ static PyObject * _sysutils_e2fslabel(PyObject * s, PyObject * args) { char * device; ext2_filsys fsys; char buf[50]; int rc; if (!PyArg_ParseTuple(args, "s", &device)) return NULL; rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, &fsys); if (rc) { Py_INCREF(Py_None); return Py_None; } memset(buf, 0, sizeof(buf)); strncpy(buf, fsys->super->s_volume_name, sizeof(fsys->super->s_volume_name)); ext2fs_close(fsys); return Py_BuildValue("s", buf); }
void make_journal_device(char *journal_device, ext2_filsys fs, int quiet, int force) { errcode_t retval; ext2_filsys jfs; io_manager io_ptr; check_plausibility(journal_device, force); check_mount(journal_device, force, "journal"); io_ptr = unix_io_manager; retval = ext2fs_open(journal_device, EXT2_FLAG_RW| EXT2_FLAG_JOURNAL_DEV_OK, 0, fs->blocksize, io_ptr, &jfs); if (retval) bb_error_msg_and_die("can't journal device %s", journal_device); if (!quiet) printf("Adding journal to device %s: ", journal_device); fflush(stdout); retval = ext2fs_add_journal_device(fs, jfs); if (retval) bb_error_msg_and_die("\nFailed to add journal to device %s", journal_device); if (!quiet) puts("done"); ext2fs_close(jfs); }
int main (int argc, char ** argv) { errcode_t retval; ext2_filsys fs; int print_badblocks = 0; blk64_t use_superblock = 0; int use_blocksize = 0; int image_dump = 0; int force = 0; int flags; int header_only = 0; int c; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); set_com_err_gettext(gettext); #endif add_error_table(&et_ext2_error_table); fprintf (stderr, "dumpe2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); if (argc && *argv) program_name = *argv; while ((c = getopt (argc, argv, "bfhixVo:")) != EOF) { switch (c) { case 'b': print_badblocks++; break; case 'f': force++; break; case 'h': header_only++; break; case 'i': image_dump++; break; case 'o': parse_extended_opts(optarg, &use_superblock, &use_blocksize); break; case 'V': /* Print version number and exit */ fprintf(stderr, _("\tUsing %s\n"), error_message(EXT2_ET_BASE)); exit(0); case 'x': hex_format++; break; default: usage(); } } if (optind > argc - 1) usage(); device_name = argv[optind++]; flags = EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS; if (force) flags |= EXT2_FLAG_FORCE; if (image_dump) flags |= EXT2_FLAG_IMAGE_FILE; if (use_superblock && !use_blocksize) { for (use_blocksize = EXT2_MIN_BLOCK_SIZE; use_blocksize <= EXT2_MAX_BLOCK_SIZE; use_blocksize *= 2) { retval = ext2fs_open (device_name, flags, use_superblock, use_blocksize, unix_io_manager, &fs); if (!retval) break; } } else retval = ext2fs_open (device_name, flags, use_superblock, use_blocksize, unix_io_manager, &fs); if (retval) { com_err (program_name, retval, _("while trying to open %s"), device_name); printf("%s", _("Couldn't find valid filesystem superblock.\n")); exit (1); } fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE; if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) blocks64 = 1; if (print_badblocks) { list_bad_blocks(fs, 1); } else { list_super (fs->super); if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { print_journal_information(fs); ext2fs_close(fs); exit(0); } if ((fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && (fs->super->s_journal_inum != 0)) print_inline_journal_information(fs); list_bad_blocks(fs, 0); if (header_only) { ext2fs_close (fs); exit (0); } retval = ext2fs_read_bitmaps (fs); list_desc (fs); if (retval) { printf(_("\n%s: %s: error reading bitmaps: %s\n"), program_name, device_name, error_message(retval)); } } ext2fs_close (fs); remove_error_table(&et_ext2_error_table); exit (0); }
int main (int argc, char ** argv) { errcode_t retval; ext2_filsys fs; int c; int flags = 0; int flush = 0; int force = 0; int io_flags = 0; int force_min_size = 0; int print_min_size = 0; int fd, ret; blk64_t new_size = 0; blk64_t max_size = 0; blk64_t min_size = 0; io_manager io_ptr; char *new_size_str = 0; int use_stride = -1; ext2fs_struct_stat st_buf; __s64 new_file_size; unsigned int sys_page_size = 4096; long sysval; int len, mount_flags; char *mtpt; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); set_com_err_gettext(gettext); #endif add_error_table(&et_ext2_error_table); fprintf (stderr, "resize2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); if (argc && *argv) program_name = *argv; while ((c = getopt (argc, argv, "d:fFhMPpS:")) != EOF) { switch (c) { case 'h': usage(program_name); break; case 'f': force = 1; break; case 'F': flush = 1; break; case 'M': force_min_size = 1; break; case 'P': print_min_size = 1; break; case 'd': flags |= atoi(optarg); break; case 'p': flags |= RESIZE_PERCENT_COMPLETE; break; case 'S': use_stride = atoi(optarg); break; default: usage(program_name); } } if (optind == argc) usage(program_name); device_name = argv[optind++]; if (optind < argc) new_size_str = argv[optind++]; if (optind < argc) usage(program_name); io_options = strchr(device_name, '?'); if (io_options) *io_options++ = 0; /* * Figure out whether or not the device is mounted, and if it is * where it is mounted. */ len=80; while (1) { mtpt = malloc(len); if (!mtpt) return ENOMEM; mtpt[len-1] = 0; retval = ext2fs_check_mount_point(device_name, &mount_flags, mtpt, len); if (retval) { com_err("ext2fs_check_mount_point", retval, _("while determining whether %s is mounted."), device_name); exit(1); } if (!(mount_flags & EXT2_MF_MOUNTED) || (mtpt[len-1] == 0)) break; free(mtpt); len = 2 * len; } fd = ext2fs_open_file(device_name, O_RDWR, 0); if (fd < 0) { com_err("open", errno, _("while opening %s"), device_name); exit(1); } ret = ext2fs_fstat(fd, &st_buf); if (ret < 0) { com_err("open", errno, _("while getting stat information for %s"), device_name); exit(1); } if (flush) { retval = ext2fs_sync_device(fd, 1); if (retval) { com_err(argv[0], retval, _("while trying to flush %s"), device_name); exit(1); } } if (!S_ISREG(st_buf.st_mode )) { close(fd); fd = -1; } #ifdef CONFIG_TESTIO_DEBUG if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { io_ptr = test_io_manager; test_io_backing_manager = unix_io_manager; } else #endif io_ptr = unix_io_manager; if (!(mount_flags & EXT2_MF_MOUNTED)) io_flags = EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE; io_flags |= EXT2_FLAG_64BITS; retval = ext2fs_open2(device_name, io_options, io_flags, 0, 0, io_ptr, &fs); if (retval) { com_err (program_name, retval, _("while trying to open %s"), device_name); printf (_("Couldn't find valid filesystem superblock.\n")); exit (1); } /* * Check for compatibility with the feature sets. We need to * be more stringent than ext2fs_open(). */ if (fs->super->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) { com_err(program_name, EXT2_ET_UNSUPP_FEATURE, "(%s)", device_name); exit(1); } min_size = calculate_minimum_resize_size(fs); if (print_min_size) { if (!force && ((fs->super->s_state & EXT2_ERROR_FS) || ((fs->super->s_state & EXT2_VALID_FS) == 0))) { fprintf(stderr, _("Please run 'e2fsck -f %s' first.\n\n"), device_name); exit(1); } printf(_("Estimated minimum size of the filesystem: %llu\n"), min_size); exit(0); } /* Determine the system page size if possible */ #ifdef HAVE_SYSCONF #if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE)) #define _SC_PAGESIZE _SC_PAGE_SIZE #endif #ifdef _SC_PAGESIZE sysval = sysconf(_SC_PAGESIZE); if (sysval > 0) sys_page_size = sysval; #endif /* _SC_PAGESIZE */ #endif /* HAVE_SYSCONF */ /* * Get the size of the containing partition, and use this for * defaults and for making sure the new filesystem doesn't * exceed the partition size. */ retval = ext2fs_get_device_size2(device_name, fs->blocksize, &max_size); if (retval) { com_err(program_name, retval, _("while trying to determine filesystem size")); exit(1); } if (force_min_size) new_size = min_size; else if (new_size_str) { new_size = parse_num_blocks2(new_size_str, fs->super->s_log_block_size); if (new_size == 0) { com_err(program_name, 0, _("Invalid new size: %s\n"), new_size_str); exit(1); } } else { new_size = max_size; /* Round down to an even multiple of a pagesize */ if (sys_page_size > fs->blocksize) new_size &= ~((sys_page_size / fs->blocksize)-1); } if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super, EXT4_FEATURE_INCOMPAT_64BIT)) { /* Take 16T down to 2^32-1 blocks */ if (new_size == (1ULL << 32)) new_size--; else if (new_size > (1ULL << 32)) { com_err(program_name, 0, _("New size too large to be " "expressed in 32 bits\n")); exit(1); } } if (!force && new_size < min_size) { com_err(program_name, 0, _("New size smaller than minimum (%llu)\n"), min_size); exit(1); } if (use_stride >= 0) { if (use_stride >= (int) fs->super->s_blocks_per_group) { com_err(program_name, 0, _("Invalid stride length")); exit(1); } fs->stride = fs->super->s_raid_stride = use_stride; ext2fs_mark_super_dirty(fs); } else determine_fs_stride(fs); /* * If we are resizing a plain file, and it's not big enough, * automatically extend it in a sparse fashion by writing the * last requested block. */ new_file_size = ((__u64) new_size) * fs->blocksize; if ((__u64) new_file_size > (((__u64) 1) << (sizeof(st_buf.st_size)*8 - 1)) - 1) fd = -1; if ((new_file_size > st_buf.st_size) && (fd > 0)) { if ((ext2fs_llseek(fd, new_file_size-1, SEEK_SET) >= 0) && (write(fd, "0", 1) == 1)) max_size = new_size; } if (!force && (new_size > max_size)) { fprintf(stderr, _("The containing partition (or device)" " is only %llu (%dk) blocks.\nYou requested a new size" " of %llu blocks.\n\n"), max_size, fs->blocksize / 1024, new_size); exit(1); } if (new_size == ext2fs_blocks_count(fs->super)) { fprintf(stderr, _("The filesystem is already %llu blocks " "long. Nothing to do!\n\n"), new_size); exit(0); } if (mount_flags & EXT2_MF_MOUNTED) { retval = online_resize_fs(fs, mtpt, &new_size, flags); } else { if (!force && ((fs->super->s_lastcheck < fs->super->s_mtime) || (fs->super->s_state & EXT2_ERROR_FS) || ((fs->super->s_state & EXT2_VALID_FS) == 0))) { fprintf(stderr, _("Please run 'e2fsck -f %s' first.\n\n"), device_name); exit(1); } /* * XXXX The combination of flex_bg and !resize_inode * causes major problems for resize2fs, since when the * group descriptors grow in size this can potentially * require multiple inode tables to be moved aside to * make room, and resize2fs chokes rather badly in * this scenario. It's a rare combination, except * when a filesystem is expanded more than a certain * size, so for now, we'll just prohibit that * combination. This is something we should fix * eventually, though. */ if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) && !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE)) { com_err(program_name, 0, _("%s: The combination of " "flex_bg and\n\t!resize_inode features " "is not supported by resize2fs.\n"), device_name); exit(1); } printf(_("Resizing the filesystem on " "%s to %llu (%dk) blocks.\n"), device_name, new_size, fs->blocksize / 1024); retval = resize_fs(fs, &new_size, flags, ((flags & RESIZE_PERCENT_COMPLETE) ? resize_progress_func : 0)); } free(mtpt); if (retval) { com_err(program_name, retval, _("while trying to resize %s"), device_name); fprintf(stderr, _("Please run 'e2fsck -fy %s' to fix the filesystem\n" "after the aborted resize operation.\n"), device_name); ext2fs_close(fs); exit(1); } printf(_("The filesystem on %s is now %llu blocks long.\n\n"), device_name, new_size); if ((st_buf.st_size > new_file_size) && (fd > 0)) { #ifdef HAVE_FTRUNCATE64 retval = ftruncate64(fd, new_file_size); #else retval = 0; /* Only truncate if new_file_size doesn't overflow off_t */ if (((off_t) new_file_size) == new_file_size) retval = ftruncate(fd, (off_t) new_file_size); #endif if (retval) com_err(program_name, retval, _("while trying to truncate %s"), device_name); } if (fd > 0) close(fd); remove_error_table(&et_ext2_error_table); return (0); }
static void PRS(int argc, char *argv[]) { int b, c; int size; char *tmp, *tmp2; int blocksize = 0; int inode_ratio = 0; int inode_size = 0; double reserved_ratio = 5.0; int sector_size = 0; int show_version_only = 0; ext2_ino_t num_inodes = 0; errcode_t retval; char * oldpath = getenv("PATH"); char * extended_opts = 0; const char * fs_type = 0; blk_t dev_size; #ifdef __linux__ struct utsname ut; #endif long sysval; int s_opt = -1, r_opt = -1; char *fs_features = 0; int use_bsize; /* Update our PATH to include /sbin */ if (oldpath) { char *newpath; newpath = malloc(sizeof (PATH_SET) + 1 + strlen (oldpath)); strcpy (newpath, PATH_SET); strcat (newpath, ":"); strcat (newpath, oldpath); putenv (newpath); } else putenv (PATH_SET); tmp = getenv("MKE2FS_SYNC"); if (tmp) sync_kludge = atoi(tmp); /* Determine the system page size if possible */ #ifdef HAVE_SYSCONF #if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE)) #define _SC_PAGESIZE _SC_PAGE_SIZE #endif #ifdef _SC_PAGESIZE sysval = sysconf(_SC_PAGESIZE); if (sysval > 0) sys_page_size = sysval; #endif /* _SC_PAGESIZE */ #endif /* HAVE_SYSCONF */ if ((tmp = getenv("MKE2FS_CONFIG")) != NULL) config_fn[0] = tmp; profile_set_syntax_err_cb(syntax_err_report); profile_init(config_fn, &profile); setbuf(stdout, NULL); setbuf(stderr, NULL); initialize_ext2_error_table(); memset(&fs_param, 0, sizeof(struct ext2_super_block)); fs_param.s_rev_level = 1; /* Create revision 1 filesystems now */ #ifdef __linux__ if (uname(&ut)) { perror("uname"); exit(1); } linux_version_code = parse_version_number(ut.release); if (linux_version_code && linux_version_code < (2*65536 + 2*256)) fs_param.s_rev_level = 0; #endif if (argc && *argv) { program_name = get_progname(*argv); /* If called as mkfs.ext3, create a journal inode */ if (!strcmp(program_name, "mkfs.ext3")) journal_size = -1; } while ((c = getopt (argc, argv, "b:cf:g:i:jl:m:no:qr:s:tvE:FI:J:L:M:N:O:R:ST:V")) != EOF) { switch (c) { case 'b': blocksize = strtol(optarg, &tmp, 0); b = (blocksize > 0) ? blocksize : -blocksize; if (b < EXT2_MIN_BLOCK_SIZE || b > EXT2_MAX_BLOCK_SIZE || *tmp) { com_err(program_name, 0, _("invalid block size - %s"), optarg); exit(1); } if (blocksize > 4096) fprintf(stderr, _("Warning: blocksize %d not " "usable on most systems.\n"), blocksize); if (blocksize > 0) fs_param.s_log_block_size = int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); break; case 'c': /* Check for bad blocks */ case 't': /* deprecated */ cflag++; break; case 'f': size = strtoul(optarg, &tmp, 0); if (size < EXT2_MIN_BLOCK_SIZE || size > EXT2_MAX_BLOCK_SIZE || *tmp) { com_err(program_name, 0, _("invalid fragment size - %s"), optarg); exit(1); } fs_param.s_log_frag_size = int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE); fprintf(stderr, _("Warning: fragments not supported. " "Ignoring -f option\n")); break; case 'g': fs_param.s_blocks_per_group = strtoul(optarg, &tmp, 0); if (*tmp) { com_err(program_name, 0, _("Illegal number for blocks per group")); exit(1); } if ((fs_param.s_blocks_per_group % 8) != 0) { com_err(program_name, 0, _("blocks per group must be multiple of 8")); exit(1); } break; case 'i': inode_ratio = strtoul(optarg, &tmp, 0); if (inode_ratio < EXT2_MIN_BLOCK_SIZE || inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024 || *tmp) { com_err(program_name, 0, _("invalid inode ratio %s (min %d/max %d)"), optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE); exit(1); } break; case 'J': parse_journal_opts(optarg); break; case 'j': if (!journal_size) journal_size = -1; break; case 'l': bad_blocks_filename = malloc(strlen(optarg)+1); if (!bad_blocks_filename) { com_err(program_name, ENOMEM, _("in malloc for bad_blocks_filename")); exit(1); } strcpy(bad_blocks_filename, optarg); break; case 'm': reserved_ratio = strtod(optarg, &tmp); if (reserved_ratio > 50 || *tmp) { com_err(program_name, 0, _("invalid reserved blocks percent - %s"), optarg); exit(1); } break; case 'n': noaction++; break; case 'o': creator_os = optarg; break; case 'q': quiet = 1; break; case 'r': r_opt = strtoul(optarg, &tmp, 0); if (*tmp) { com_err(program_name, 0, _("bad revision level - %s"), optarg); exit(1); } fs_param.s_rev_level = r_opt; break; case 's': /* deprecated */ s_opt = atoi(optarg); break; #ifdef EXT2_DYNAMIC_REV case 'I': inode_size = strtoul(optarg, &tmp, 0); if (*tmp) { com_err(program_name, 0, _("invalid inode size - %s"), optarg); exit(1); } break; #endif case 'v': verbose = 1; break; case 'F': force = 1; break; case 'L': volume_label = optarg; break; case 'M': mount_dir = optarg; break; case 'N': num_inodes = strtoul(optarg, &tmp, 0); if (*tmp) { com_err(program_name, 0, _("bad num inodes - %s"), optarg); exit(1); } break; case 'O': fs_features = optarg; break; case 'E': case 'R': extended_opts = optarg; break; case 'S': super_only = 1; break; case 'T': fs_type = optarg; break; case 'V': /* Print version number and exit */ show_version_only++; break; default: usage(); } } if ((optind == argc) && !show_version_only) usage(); device_name = argv[optind++]; if (!quiet || show_version_only) fprintf (stderr, "mke2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); if (show_version_only) { fprintf(stderr, _("\tUsing %s\n"), error_message(EXT2_ET_BASE)); exit(0); } /* * If there's no blocksize specified and there is a journal * device, use it to figure out the blocksize */ if (blocksize <= 0 && journal_device) { ext2_filsys jfs; io_manager io_ptr; #ifdef CONFIG_TESTIO_DEBUG io_ptr = test_io_manager; test_io_backing_manager = unix_io_manager; #else io_ptr = unix_io_manager; #endif retval = ext2fs_open(journal_device, EXT2_FLAG_JOURNAL_DEV_OK, 0, 0, io_ptr, &jfs); if (retval) { com_err(program_name, retval, _("while trying to open journal device %s\n"), journal_device); exit(1); } if ((blocksize < 0) && (jfs->blocksize < (unsigned) (-blocksize))) { com_err(program_name, 0, _("Journal dev blocksize (%d) smaller than " "minimum blocksize %d\n"), jfs->blocksize, -blocksize); exit(1); } blocksize = jfs->blocksize; fs_param.s_log_block_size = int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); ext2fs_close(jfs); }
static void open_filesystem(char *device, int open_flags, blk_t superblock, blk_t blocksize, int catastrophic, char *data_filename) { int retval; io_channel data_io = 0; if (superblock != 0 && blocksize == 0) { com_err(device, 0, "if you specify the superblock, you must also specify the block size"); current_fs = NULL; return; } if (data_filename) { if ((open_flags & EXT2_FLAG_IMAGE_FILE) == 0) { com_err(device, 0, "The -d option is only valid when reading an e2image file"); current_fs = NULL; return; } retval = unix_io_manager->open(data_filename, 0, &data_io); if (retval) { com_err(data_filename, 0, "while opening data source"); current_fs = NULL; return; } } if (catastrophic && (open_flags & EXT2_FLAG_RW)) { com_err(device, 0, "opening read-only because of catastrophic mode"); open_flags &= ~EXT2_FLAG_RW; } retval = ext2fs_open(device, open_flags, superblock, blocksize, unix_io_manager, ¤t_fs); if (retval) { com_err(device, retval, "while opening filesystem"); current_fs = NULL; return; } if (catastrophic) com_err(device, 0, "catastrophic mode - not reading inode or group bitmaps"); else { retval = ext2fs_read_inode_bitmap(current_fs); if (retval) { com_err(device, retval, "while reading inode bitmap"); goto errout; } retval = ext2fs_read_block_bitmap(current_fs); if (retval) { com_err(device, retval, "while reading block bitmap"); goto errout; } } if (data_io) { retval = ext2fs_set_data_io(current_fs, data_io); if (retval) { com_err(device, retval, "while setting data source"); goto errout; } } root = cwd = EXT2_ROOT_INO; return; errout: retval = ext2fs_close(current_fs); if (retval) com_err(device, retval, "while trying to close filesystem"); current_fs = NULL; }
/* * This routine checks to see if a filesystem can be skipped; if so, * it will exit with E2FSCK_OK. Under some conditions it will print a * message explaining why a check is being forced. */ static void check_if_skip(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; const char *reason = NULL; unsigned int reason_arg = 0; long next_check; int batt = is_on_batt(); int defer_check_on_battery; int broken_system_clock; time_t lastcheck; profile_get_boolean(ctx->profile, "options", "broken_system_clock", 0, 0, &broken_system_clock); if (ctx->flags & E2F_FLAG_TIME_INSANE) broken_system_clock = 1; profile_get_boolean(ctx->profile, "options", "defer_check_on_battery", 0, 1, &defer_check_on_battery); if (!defer_check_on_battery) batt = 0; if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file || cflag) return; if (ctx->options & E2F_OPT_JOURNAL_ONLY) goto skip; lastcheck = fs->super->s_lastcheck; if (lastcheck > ctx->now) lastcheck -= ctx->time_fudge; if ((fs->super->s_state & EXT2_ERROR_FS) || !ext2fs_test_valid(fs)) reason = _(" contains a file system with errors"); else if ((fs->super->s_state & EXT2_VALID_FS) == 0) reason = _(" was not cleanly unmounted"); else if (check_backup_super_block(ctx)) reason = _(" primary superblock features different from backup"); else if ((fs->super->s_max_mnt_count > 0) && (fs->super->s_mnt_count >= (unsigned) fs->super->s_max_mnt_count)) { reason = _(" has been mounted %u times without being checked"); reason_arg = fs->super->s_mnt_count; if (batt && (fs->super->s_mnt_count < (unsigned) fs->super->s_max_mnt_count*2)) reason = 0; } else if (!broken_system_clock && fs->super->s_checkinterval && (ctx->now < lastcheck)) { reason = _(" has filesystem last checked time in the future"); if (batt) reason = 0; } else if (!broken_system_clock && fs->super->s_checkinterval && ((ctx->now - lastcheck) >= ((time_t) fs->super->s_checkinterval))) { reason = _(" has gone %u days without being checked"); reason_arg = (ctx->now - fs->super->s_lastcheck)/(3600*24); if (batt && ((ctx->now - fs->super->s_lastcheck) < fs->super->s_checkinterval*2)) reason = 0; } if (reason) { fputs(ctx->device_name, stdout); printf(reason, reason_arg); fputs(_(", check forced.\n"), stdout); return; } printf(_("%s: clean, %u/%u files, %u/%u blocks"), ctx->device_name, fs->super->s_inodes_count - fs->super->s_free_inodes_count, fs->super->s_inodes_count, fs->super->s_blocks_count - fs->super->s_free_blocks_count, fs->super->s_blocks_count); next_check = 100000; if (fs->super->s_max_mnt_count > 0) { next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count; if (next_check <= 0) next_check = 1; } if (!broken_system_clock && fs->super->s_checkinterval && ((ctx->now - fs->super->s_lastcheck) >= fs->super->s_checkinterval)) next_check = 1; if (next_check <= 5) { if (next_check == 1) { if (batt) fputs(_(" (check deferred; on battery)"), stdout); else fputs(_(" (check after next mount)"), stdout); } else printf(_(" (check in %ld mounts)"), next_check); } fputc('\n', stdout); skip: ext2fs_close(fs); ctx->fs = NULL; e2fsck_free_context(ctx); exit(FSCK_OK); }
int main (int argc, char *argv[]) { errcode_t retval = 0, retval2 = 0, orig_retval = 0; int exit_value = FSCK_OK; ext2_filsys fs = 0; io_manager io_ptr; struct ext2_super_block *sb; const char *lib_ver_date; int my_ver, lib_ver; e2fsck_t ctx; blk_t orig_superblock; struct problem_context pctx; int flags, run_result; int journal_size; int sysval, sys_page_size = 4096; __u32 features[3]; char *cp; klog_init(); E2F_DBG_INFO("e2fsck start..."); #ifdef E2FSCK_PIPE_DEBUG_ memset(pipe_msg_temp, 0, MSG_LEN); memcpy(pipe_msg_temp, argv[2], strlen(argv[2])); pipe_open(); pipe_write(C_IN_START); #endif clear_problem_context(&pctx); #ifdef MTRACE mtrace(); #endif #ifdef MCHECK mcheck(0); #endif #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif my_ver = ext2fs_parse_version_string(my_ver_string); lib_ver = ext2fs_get_library_version(0, &lib_ver_date); if (my_ver > lib_ver) { fprintf( stderr, _("Error: ext2fs library version " "out of date!\n")); show_version_only++; } retval = PRS(argc, argv, &ctx); if (retval) { com_err("e2fsck", retval, _("while trying to initialize program")); exit(FSCK_ERROR); } reserve_stdio_fds(); init_resource_track(&ctx->global_rtrack, NULL); if (!(ctx->options & E2F_OPT_PREEN) || show_version_only) fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string, my_ver_date); if (show_version_only) { fprintf(stderr, _("\tUsing %s, %s\n"), error_message(EXT2_ET_BASE), lib_ver_date); exit(FSCK_OK); } check_mount(ctx); if (!(ctx->options & E2F_OPT_PREEN) && !(ctx->options & E2F_OPT_NO) && !(ctx->options & E2F_OPT_YES)) { if (!ctx->interactive) fatal_error(ctx, _("need terminal for interactive repairs")); } ctx->superblock = ctx->use_superblock; restart: #ifdef CONFIG_TESTIO_DEBUG if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { io_ptr = test_io_manager; test_io_backing_manager = unix_io_manager; } else #endif io_ptr = unix_io_manager; flags = EXT2_FLAG_NOFREE_ON_ERROR; if ((ctx->options & E2F_OPT_READONLY) == 0) flags |= EXT2_FLAG_RW; if ((ctx->mount_flags & EXT2_MF_MOUNTED) == 0) flags |= EXT2_FLAG_EXCLUSIVE; retval = try_open_fs(ctx, flags, io_ptr, &fs); if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) && !(ctx->flags & E2F_FLAG_SB_SPECIFIED) && ((retval == EXT2_ET_BAD_MAGIC) || (retval == EXT2_ET_CORRUPT_SUPERBLOCK) || ((retval == 0) && (retval2 = ext2fs_check_desc(fs))))) { if (retval2 == ENOMEM) { retval = retval2; goto failure; } if (fs->flags & EXT2_FLAG_NOFREE_ON_ERROR) { ext2fs_free(fs); fs = NULL; } if (!fs || (fs->group_desc_count > 1)) { printf(_("%s: %s trying backup blocks...\n"), ctx->program_name, retval ? _("Superblock invalid,") : _("Group descriptors look bad...")); orig_superblock = ctx->superblock; get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr); if (fs) ext2fs_close(fs); orig_retval = retval; retval = try_open_fs(ctx, flags, io_ptr, &fs); if ((orig_retval == 0) && retval != 0) { if (fs) ext2fs_close(fs); com_err(ctx->program_name, retval, "when using the backup blocks"); printf(_("%s: going back to original " "superblock\n"), ctx->program_name); ctx->superblock = orig_superblock; retval = try_open_fs(ctx, flags, io_ptr, &fs); } } } if (((retval == EXT2_ET_UNSUPP_FEATURE) || (retval == EXT2_ET_RO_UNSUPP_FEATURE)) && fs && fs->super) { sb = fs->super; features[0] = (sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP); features[1] = (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP); features[2] = (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP); if (features[0] || features[1] || features[2]) goto print_unsupp_features; } failure: if (retval) { if (orig_retval) retval = orig_retval; com_err(ctx->program_name, retval, _("while trying to open %s"), ctx->filesystem_name); if (retval == EXT2_ET_REV_TOO_HIGH) { printf(_("The filesystem revision is apparently " "too high for this version of e2fsck.\n" "(Or the filesystem superblock " "is corrupt)\n\n")); fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); } else if (retval == EXT2_ET_SHORT_READ) printf(_("Could this be a zero-length partition?\n")); else if ((retval == EPERM) || (retval == EACCES)) printf(_("You must have %s access to the " "filesystem or be root\n"), (ctx->options & E2F_OPT_READONLY) ? "r/o" : "r/w"); else if (retval == ENXIO) printf(_("Possibly non-existent or swap device?\n")); else if (retval == EBUSY) printf(_("Filesystem mounted or opened exclusively " "by another program?\n")); else if (retval == ENOENT) printf(_("Possibly non-existent device?\n")); #ifdef EROFS else if (retval == EROFS) printf(_("Disk write-protected; use the -n option " "to do a read-only\n" "check of the device.\n")); #endif else fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); fatal_error(ctx, 0); } /* * We only update the master superblock because (a) paranoia; * we don't want to corrupt the backup superblocks, and (b) we * don't need to update the mount count and last checked * fields in the backup superblock (the kernel doesn't update * the backup superblocks anyway). With newer versions of the * library this flag is set by ext2fs_open2(), but we set this * here just to be sure. (No, we don't support e2fsck running * with some other libext2fs than the one that it was shipped * with, but just in case....) */ fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; if (!(ctx->flags & E2F_FLAG_GOT_DEVSIZE)) { __u32 blocksize = EXT2_BLOCK_SIZE(fs->super); int need_restart = 0; pctx.errcode = ext2fs_get_device_size2(ctx->filesystem_name, blocksize, &ctx->num_blocks); /* * The floppy driver refuses to allow anyone else to * open the device if has been opened with O_EXCL; * this is unlike other block device drivers in Linux. * To handle this, we close the filesystem and then * reopen the filesystem after we get the device size. */ if (pctx.errcode == EBUSY) { ext2fs_close(fs); need_restart++; pctx.errcode = ext2fs_get_device_size2(ctx->filesystem_name, blocksize, &ctx->num_blocks); } if (pctx.errcode == EXT2_ET_UNIMPLEMENTED) ctx->num_blocks = 0; else if (pctx.errcode) { fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx); ctx->flags |= E2F_FLAG_ABORT; fatal_error(ctx, 0); } ctx->flags |= E2F_FLAG_GOT_DEVSIZE; if (need_restart) goto restart; } ctx->fs = fs; fs->priv_data = ctx; fs->now = ctx->now; sb = fs->super; if (sb->s_rev_level > E2FSCK_CURRENT_REV) { com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH, _("while trying to open %s"), ctx->filesystem_name); get_newer: fatal_error(ctx, _("Get a newer version of e2fsck!")); } /* * Set the device name, which is used whenever we print error * or informational messages to the user. */ if (ctx->device_name == 0 && (sb->s_volume_name[0] != 0)) { ctx->device_name = string_copy(ctx, sb->s_volume_name, sizeof(sb->s_volume_name)); } if (ctx->device_name == 0) ctx->device_name = string_copy(ctx, ctx->filesystem_name, 0); for (cp = ctx->device_name; *cp; cp++) if (isspace(*cp) || *cp == ':') *cp = '_'; ehandler_init(fs->io); if ((ctx->mount_flags & EXT2_MF_MOUNTED) && !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) goto skip_journal; /* * Make sure the ext3 superblock fields are consistent. */ retval = e2fsck_check_ext3_journal(ctx); if (retval) { com_err(ctx->program_name, retval, _("while checking ext3 journal for %s"), ctx->device_name); fatal_error(ctx, 0); } /* * Check to see if we need to do ext3-style recovery. If so, * do it, and then restart the fsck. */ if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { if (ctx->options & E2F_OPT_READONLY) { printf(_("Warning: skipping journal recovery " "because doing a read-only filesystem " "check.\n")); io_channel_flush(ctx->fs->io); } else { if (ctx->flags & E2F_FLAG_RESTARTED) { /* * Whoops, we attempted to run the * journal twice. This should never * happen, unless the hardware or * device driver is being bogus. */ com_err(ctx->program_name, 0, _("unable to set superblock flags on %s\n"), ctx->device_name); fatal_error(ctx, 0); } retval = e2fsck_run_ext3_journal(ctx); if (retval) { com_err(ctx->program_name, retval, _("while recovering ext3 journal of %s"), ctx->device_name); fatal_error(ctx, 0); } ext2fs_close(ctx->fs); ctx->fs = 0; ctx->flags |= E2F_FLAG_RESTARTED; goto restart; } } skip_journal: /* * Check for compatibility with the feature sets. We need to * be more stringent than ext2fs_open(). */ features[0] = sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP; features[1] = sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP; features[2] = (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP); print_unsupp_features: if (features[0] || features[1] || features[2]) { int i, j; __u32 *mask = features, m; fprintf(stderr, _("%s has unsupported feature(s):"), ctx->filesystem_name); for (i=0; i <3; i++,mask++) { for (j=0,m=1; j < 32; j++, m<<=1) { if (*mask & m) fprintf(stderr, " %s", e2p_feature2string(i, m)); } } putc('\n', stderr); goto get_newer; } #ifdef ENABLE_COMPRESSION if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) com_err(ctx->program_name, 0, _("Warning: compression support is experimental.\n")); #endif #ifndef ENABLE_HTREE if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) { com_err(ctx->program_name, 0, _("E2fsck not compiled with HTREE support,\n\t" "but filesystem %s has HTREE directories.\n"), ctx->device_name); goto get_newer; } #endif /* * If the user specified a specific superblock, presumably the * master superblock has been trashed. So we mark the * superblock as dirty, so it can be written out. */ if (ctx->superblock && !(ctx->options & E2F_OPT_READONLY)) ext2fs_mark_super_dirty(fs); /* * Calculate the number of filesystem blocks per pagesize. If * fs->blocksize > page_size, set the number of blocks per * pagesize to 1 to avoid division by zero errors. */ #ifdef _SC_PAGESIZE sysval = sysconf(_SC_PAGESIZE); if (sysval > 0) sys_page_size = sysval; #endif /* _SC_PAGESIZE */ ctx->blocks_per_page = sys_page_size / fs->blocksize; if (ctx->blocks_per_page == 0) ctx->blocks_per_page = 1; if (ctx->superblock) set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0); ext2fs_mark_valid(fs); check_super_block(ctx); if (ctx->flags & E2F_FLAG_SIGNAL_MASK) fatal_error(ctx, 0); check_if_skip(ctx); check_resize_inode(ctx); if (bad_blocks_file) read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks); else if (cflag) read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */ if (ctx->flags & E2F_FLAG_SIGNAL_MASK) fatal_error(ctx, 0); /* * Mark the system as valid, 'til proven otherwise */ ext2fs_mark_valid(fs); retval = ext2fs_read_bb_inode(fs, &fs->badblocks); if (retval) { com_err(ctx->program_name, retval, _("while reading bad blocks inode")); preenhalt(ctx); printf(_("This doesn't bode well," " but we'll try to go on...\n")); } /* * Save the journal size in megabytes. * Try and use the journal size from the backup else let e2fsck * find the default journal size. */ if (sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) journal_size = sb->s_jnl_blocks[16] >> 20; else
/****************************************************************************** * Ext2fs boot command intepreter. Derived from diskboot */ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *filename = NULL; char *ep; int dev, part = 1; ulong addr = 0, part_length, filelen; disk_partition_t info; block_dev_desc_t *dev_desc = NULL; char buf [12]; unsigned long count; char *addr_str; switch (argc) { case 3: addr_str = getenv("loadaddr"); if (addr_str != NULL) { addr = simple_strtoul (addr_str, NULL, 16); } else { addr = CONFIG_SYS_LOAD_ADDR; } filename = getenv ("bootfile"); count = 0; break; case 4: addr = simple_strtoul (argv[3], NULL, 16); filename = getenv ("bootfile"); count = 0; break; case 5: addr = simple_strtoul (argv[3], NULL, 16); filename = argv[4]; count = 0; break; case 6: addr = simple_strtoul (argv[3], NULL, 16); filename = argv[4]; count = simple_strtoul (argv[5], NULL, 16); break; default: cmd_usage(cmdtp); return(1); } if (!filename) { puts ("\n** No boot file defined **\n"); return(1); } dev = (int)simple_strtoul (argv[2], &ep, 16); dev_desc = get_dev(argv[1],dev); if (dev_desc==NULL) { printf ("\n** Block device %s %d not supported\n", argv[1], dev); return(1); } if (*ep) { if (*ep != ':') { puts ("\n** Invalid boot device, use `dev[:part]' **\n"); return(1); } part = (int)simple_strtoul(++ep, NULL, 16); } PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part); if (part != 0) { if (get_partition_info (dev_desc, part, &info)) { printf ("** Bad partition %d **\n", part); return(1); } if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); return(1); } PRINTF ("\nLoading from block device %s device %d, partition %d: " "Name: %.32s Type: %.32s File:%s\n", argv[1], dev, part, info.name, info.type, filename); } else { PRINTF ("\nLoading from block device %s device %d, File:%s\n", argv[1], dev, filename); } if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) { printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); ext2fs_close(); return(1); } if (!ext2fs_mount(part_length)) { printf ("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part); ext2fs_close(); return(1); } filelen = ext2fs_open(filename); if (filelen < 0) { printf("** File not found %s\n", filename); ext2fs_close(); return(1); } if ((count < filelen) && (count != 0)) { filelen = count; } if (ext2fs_read((char *)addr, filelen) != filelen) { printf("\n** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part); ext2fs_close(); return(1); } ext2fs_close(); /* Loading ok, update default load address */ load_addr = addr; printf ("\n%ld bytes read\n", filelen); sprintf(buf, "%lX", filelen); setenv("filesize", buf); return(filelen); }