Esempio n. 1
0
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;
}
Esempio n. 3
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
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);
}
Esempio n. 6
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);

}
Esempio n. 7
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
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);
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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);
}
Esempio n. 13
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);
}
Esempio n. 14
0
File: undelfs.c Progetto: CTU-OSP/mc
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;
}
Esempio n. 15
0
File: util.c Progetto: er13/e2tools
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);
}
Esempio n. 16
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);
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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;
}
Esempio n. 19
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
/* 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); 
}
Esempio n. 23
0
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);
}
Esempio n. 24
0
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);
}
Esempio n. 26
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, &current_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
Esempio n. 30
0
/******************************************************************************
 * 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);
}