Check feature sets before running

master
Vitaliy Filippov 2014-01-17 14:45:08 +00:00
parent 17fdd46b42
commit cb7adffb41
1 changed files with 46 additions and 4 deletions

View File

@ -96,6 +96,33 @@
#define _(a) (a)
#define min(a,b) ((a)<(b)?(a):(b))
// Check our own feature sets for the case of linking with newer libext2fs
#define REALLOC_FEATURE_COMPAT_SUPP \
(EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
EXT2_FEATURE_COMPAT_RESIZE_INODE|\
EXT2_FEATURE_COMPAT_DIR_INDEX|\
EXT2_FEATURE_COMPAT_EXT_ATTR)
// 'journal_dev' and 'recover' incompat features are unsupported
#define REALLOC_FEATURE_INCOMPAT_SUPP \
(EXT2_FEATURE_INCOMPAT_FILETYPE|\
EXT2_FEATURE_INCOMPAT_COMPRESSION|\
EXT2_FEATURE_INCOMPAT_META_BG|\
EXT3_FEATURE_INCOMPAT_EXTENTS|\
EXT4_FEATURE_INCOMPAT_FLEX_BG|\
EXT4_FEATURE_INCOMPAT_MMP|\
EXT4_FEATURE_INCOMPAT_64BIT)
#define REALLOC_FEATURE_RO_COMPAT_SUPP \
(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
EXT4_FEATURE_RO_COMPAT_BIGALLOC|\
EXT4_FEATURE_RO_COMPAT_QUOTA)
// "local data" for the inode reallocation process
typedef struct
{
@ -489,7 +516,7 @@ int nonmovable_callback(ext2_filsys fs, blk64_t *blocknr, e2_blkcnt_t blockcnt,
* Allocate new place for all groups' inode tables and remember it.
* This is more correct, because allows us to correctly handle situations
* when flex_bg is so big that inode tables for all groups in flex_bg
* do not fit into its first group, and also allows up to honor bad blocks.
* do not fit into its first group, and also allows us to honor bad blocks.
*/
errcode_t alloc_itables(realloc_data *rd)
{
@ -713,6 +740,8 @@ int main(int narg, char **args)
{
if (!strcmp(args[optind], "--patch"))
rd.patch_file = args[++optind];
else if (!strcmp(args[optind], "--force"))
force = 1;
else if (args[optind][0] == '-' && args[optind][1] == '-')
{
if (strcmp(args[optind], "--help") != 0)
@ -774,10 +803,23 @@ int main(int narg, char **args)
printf(_("Couldn't find valid filesystem superblock.\n"));
goto close_fd;
}
if (!force && ((rd.fs->super->s_state & EXT2_ERROR_FS) || ((rd.fs->super->s_state & EXT2_VALID_FS) == 0)))
if (!force)
{
fprintf(stderr, _("Please run 'e2fsck -f %s' first.\n\n"), rd.device_name);
goto close_fs;
if ((rd.fs->super->s_state & EXT2_ERROR_FS) ||
!(rd.fs->super->s_state & EXT2_VALID_FS) ||
(rd.fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER))
{
fprintf(stderr, _("Please run 'e2fsck -f %s' first.\n\n"), rd.device_name);
goto close_fs;
}
if (rd.fs->super->s_feature_incompat & ~REALLOC_FEATURE_INCOMPAT_SUPP ||
rd.fs->super->s_feature_compat & ~REALLOC_FEATURE_COMPAT_SUPP ||
rd.fs->super->s_feature_ro_compat & ~REALLOC_FEATURE_RO_COMPAT_SUPP)
{
retval = EXT2_ET_UNSUPP_FEATURE;
com_err(program_name, retval, _("while trying to open %s"), rd.device_name);
goto close_fs;
}
}
// Call main realloc function
retval = do_realloc(&rd);