Merge branch 'maint'

Conflicts:

	lib/blkid/devname.c
	lib/blkid/probe.c
	misc/mke2fs.c
	misc/tune2fs.c
This commit is contained in:
Theodore Ts'o 2008-02-27 18:53:34 -05:00
commit a49670e64e
24 changed files with 452 additions and 173 deletions

View File

@ -1,9 +1,9 @@
#!/bin/sh
set -e
groupadd -f -K GID_MIN=1 -K GID_MAX=999 libuuid
groupadd -f -K GID_MIN=100 -K GID_MAX=999 libuuid
if ! grep -q libuuid /etc/passwd; then
useradd -d /var/lib/libuuid -K UID_MIN=1 -K UID_MAX=499 -g libuuid libuuid
useradd -d /var/lib/libuuid -K UID_MIN=100 -K UID_MAX=999 -g libuuid libuuid
fi
mkdir -p /var/lib/libuuid
chown libuuid:libuuid /var/lib/libuuid

View File

@ -1152,7 +1152,7 @@ void do_unlink(int argc, char *argv[])
void do_find_free_block(int argc, char *argv[])
{
blk_t free_blk, goal;
blk_t free_blk, goal, first_free = 0;
int count;
errcode_t retval;
char *tmp;
@ -1188,6 +1188,11 @@ void do_find_free_block(int argc, char *argv[])
while (count-- > 0) {
retval = ext2fs_new_block(current_fs, free_blk + 1, 0,
&free_blk);
if (first_free) {
if (first_free == free_blk)
break;
} else
first_free = free_blk;
if (retval) {
com_err("ext2fs_new_block", retval, 0);
return;

View File

@ -17,18 +17,18 @@ MANPAGES= e2fsck.8
FMANPAGES= e2fsck.conf.5
XTRA_CFLAGS= -DRESOURCE_TRACK -I.
LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBBLKID) $(LIBUUID) $(LIBINTL)
DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(DEPLIBBLKID) $(DEPLIBUUID)
LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBBLKID) $(LIBUUID) $(LIBINTL) $(LIBE2P)
DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(DEPLIBBLKID) $(DEPLIBUUID) $(DEPLIBE2P)
STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(STATIC_LIBBLKID) \
$(STATIC_LIBUUID) $(LIBINTL)
$(STATIC_LIBUUID) $(LIBINTL) $(STATIC_LIBE2P)
STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(DEPSTATIC_LIBBLKID) \
$(DEPSTATIC_LIBUUID)
$(DEPSTATIC_LIBUUID) $(DEPSTATIC_LIBE2P)
PROFILED_LIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) \
$(PROFILED_LIBBLKID) $(PROFILED_LIBUUID) $(LIBINTL)
$(PROFILED_LIBBLKID) $(PROFILED_LIBUUID) $(PROFILED_LIBE2P) $(LIBINTL)
PROFILED_DEPLIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) \
$(DEPPROFILED_LIBBLKID) $(DEPPROFILED_LIBUUID)
$(DEPPROFILED_LIBBLKID) $(DEPPROFILED_LIBUUID) $(DEPPROFILED_LIBE2P)
COMPILE_ET=$(top_builddir)/lib/et/compile_et --build-tree

View File

@ -97,6 +97,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
/*
* Finally, update the bad blocks from the bad_block_map
*/
printf("%s: Updating bad block inode.\n", ctx->device_name);
retval = ext2fs_update_bb_inode(fs, bb_list);
if (retval) {
com_err("ext2fs_update_bb_inode", retval,

View File

@ -167,6 +167,11 @@ and need to be rebuilt. The
option forces all directories in the filesystem to be optimized. This can
sometimes make them a little smaller and slightly faster to search, but
in practice, you should rarely need to use this option.
.IP
The
.B \-D
option will detect directory entries with duplicate names in a single
directory, which e2fsck normally does not enforce for performance reasons.
.TP
.BI \-E " extended_options"
Set e2fsck extended options. Extended options are comma

View File

@ -275,15 +275,6 @@ void e2fsck_pass2(e2fsck_t ctx)
ext2fs_update_dynamic_rev(fs);
ext2fs_mark_super_dirty(fs);
}
} else if (!ctx->large_files &&
(sb->s_feature_ro_compat &
EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
if (fs->flags & EXT2_FLAG_RW) {
sb->s_feature_ro_compat &=
~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
ext2fs_mark_super_dirty(fs);
}
}
#ifdef RESOURCE_TRACK

View File

@ -858,6 +858,7 @@ int main (int argc, char *argv[])
int flags, run_result;
int journal_size;
int sysval, sys_page_size = 4096;
__u32 features[3];
clear_problem_context(&pctx);
#ifdef MTRACE
@ -919,7 +920,7 @@ restart:
#else
io_ptr = unix_io_manager;
#endif
flags = 0;
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)
@ -948,6 +949,10 @@ restart:
((retval == EXT2_ET_BAD_MAGIC) ||
(retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
((retval == 0) && ext2fs_check_desc(fs)))) {
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,
@ -960,6 +965,19 @@ restart:
goto restart;
}
}
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;
}
if (retval) {
if (orig_retval)
retval = orig_retval;
@ -1115,15 +1133,26 @@ restart:
* Check for compatibility with the feature sets. We need to
* be more stringent than ext2fs_open().
*/
if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
(sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
"(%s)", ctx->device_name);
goto get_newer;
}
if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
"(%s)", ctx->device_name);
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

View File

@ -171,37 +171,42 @@ static int dm_device_has_dep(const dev_t dev, const char *name)
struct dm_deps *deps;
struct dm_info info;
unsigned int i;
int ret = 0;
task = dm_task_create(DM_DEVICE_DEPS);
if (!task)
return 0;
goto out;
dm_task_set_name(task, name);
dm_task_run(task);
dm_task_get_info(task, &info);
if (!dm_task_set_name(task, name))
goto out;
if (!info.exists) {
dm_task_destroy(task);
return 0;
}
if (!dm_task_run(task))
goto out;
if (!dm_task_get_info(task, &info))
goto out;
if (!info.exists)
goto out;
deps = dm_task_get_deps(task);
if (!deps || deps->count == 0) {
dm_task_destroy(task);
return 0;
}
if (!deps || deps->count == 0)
goto out;
for (i = 0; i < deps->count; i++) {
dev_t dep_dev = deps->device[i];
if (dev == dep_dev) {
dm_task_destroy(task);
return 1;
ret = 1;
goto out;
}
}
dm_task_destroy(task);
return 0;
out:
if (task)
dm_task_destroy(task);
return ret;
}
static int dm_device_is_leaf(const dev_t dev)
@ -214,15 +219,16 @@ static int dm_device_is_leaf(const dev_t dev)
dm_log_init(dm_quiet_log);
task = dm_task_create(DM_DEVICE_LIST);
if (!task)
return 1;
goto out;
dm_log_init(0);
dm_task_run(task);
if (!dm_task_run(task))
goto out;
names = dm_task_get_names(task);
if (!names || !names->dev) {
dm_task_destroy(task);
return 1;
}
if (!names || !names->dev)
goto out;
n = 0;
do {
@ -234,7 +240,9 @@ static int dm_device_is_leaf(const dev_t dev)
next = names->next;
} while (next);
dm_task_destroy(task);
out:
if (task)
dm_task_destroy(task);
return ret;
}
@ -247,20 +255,25 @@ static dev_t dm_get_devno(const char *name)
task = dm_task_create(DM_DEVICE_INFO);
if (!task)
return ret;
goto out;
dm_task_set_name(task, name);
dm_task_run(task);
dm_task_get_info(task, &info);
if (!dm_task_set_name(task, name))
goto out;
if (!info.exists) {
dm_task_destroy(task);
return ret;
}
if (!dm_task_run(task))
goto out;
if (!dm_task_get_info(task, &info))
goto out;
if (!info.exists)
goto out;
ret = makedev(info.major, info.minor);
dm_task_destroy(task);
out:
if (task)
dm_task_destroy(task);
return ret;
}
@ -275,15 +288,15 @@ static void dm_probe_all(blkid_cache cache, int only_if_new)
dm_log_init(dm_quiet_log);
task = dm_task_create(DM_DEVICE_LIST);
if (!task)
return;
goto out;
dm_log_init(0);
dm_task_run(task);
if (!dm_task_run(task))
goto out;
names = dm_task_get_names(task);
if (!names || !names->dev) {
dm_task_destroy(task);
return;
}
if (!names || !names->dev)
goto out;
n = 0;
do {
@ -311,7 +324,9 @@ try_next:
next = names->next;
} while (next);
dm_task_destroy(task);
out:
if (task)
dm_task_destroy(task);
}
#endif /* HAVE_DEVMAPPER */

View File

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@ -163,7 +164,7 @@ static void get_ext2_info(blkid_dev dev, struct blkid_magic *id,
* Check to see if a filesystem is in /proc/filesystems.
* Returns 1 if found, 0 if not
*/
int fs_proc_check(const char *fs_name)
static int fs_proc_check(const char *fs_name)
{
FILE *f;
char buf[80], *cp, *t;
@ -200,7 +201,7 @@ int fs_proc_check(const char *fs_name)
* Check to see if a filesystem is available as a module
* Returns 1 if found, 0 if not
*/
int check_for_modules(const char *fs_name)
static int check_for_modules(const char *fs_name)
{
struct utsname uts;
FILE *f;
@ -236,7 +237,7 @@ int check_for_modules(const char *fs_name)
return (0);
}
static int system_supports_ext4()
static int system_supports_ext4(void)
{
static time_t last_check = 0;
static int ret = -1;
@ -249,7 +250,7 @@ static int system_supports_ext4()
return ret;
}
static int system_supports_ext4dev()
static int system_supports_ext4dev(void)
{
static time_t last_check = 0;
static int ret = -1;
@ -1008,7 +1009,7 @@ static int probe_gfs2(struct blkid_probe *probe,
return 1;
}
static int probe_hfsplus(struct blkid_probe *probe,
static int probe_hfsplus(struct blkid_probe *probe __BLKID_ATTR((unused)),
struct blkid_magic *id __BLKID_ATTR((unused)),
unsigned char *buf)
{
@ -1021,6 +1022,73 @@ static int probe_hfsplus(struct blkid_probe *probe,
return 1;
}
#define LVM2_LABEL_SIZE 512
static unsigned int lvm2_calc_crc(const void *buf, uint size)
{
static const uint crctab[] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
uint i, crc = 0xf597a6cf;
const __u8 *data = (const __u8 *) buf;
for (i = 0; i < size; i++) {
crc ^= *data++;
crc = (crc >> 4) ^ crctab[crc & 0xf];
crc = (crc >> 4) ^ crctab[crc & 0xf];
}
return crc;
}
static int probe_lvm2(struct blkid_probe *probe,
struct blkid_magic *id __BLKID_ATTR((unused)),
unsigned char *buf)
{
int sector = (id->bim_kboff) << 1;;
struct lvm2_pv_label_header *label;
label = (struct lvm2_pv_label_header *)buf;
char *p, *q, uuid[40];
unsigned int i, b;
/* buf is at 0k or 1k offset; find label inside */
if (memcmp(buf, "LABELONE", 8) == 0) {
label = (struct lvm2_pv_label_header *)buf;
} else if (memcmp(buf + 512, "LABELONE", 8) == 0) {
label = (struct lvm2_pv_label_header *)(buf + 512);
sector++;
} else {
return 1;
}
if (blkid_le64(label->sector_xl) != (unsigned) sector) {
DBG(DEBUG_PROBE,
printf("LVM2: label for sector %llu found at sector %d\n",
blkid_le64(label->sector_xl), sector));
return 1;
}
if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE -
((char *)&label->offset_xl - (char *)label)) !=
blkid_le32(label->crc_xl)) {
DBG(DEBUG_PROBE,
printf("LVM2: label checksum incorrect at sector %d\n",
sector));
return 1;
}
for (i=0, b=1, p=uuid, q= (char *) label->pv_uuid; i <= 32;
i++, b <<= 1) {
if (b & 0x4444440)
*p++ = '-';
*p++ = *q++;
}
blkid_set_tag(probe->dev, "UUID", uuid, LVM2_ID_LEN+6);
return 0;
}
/*
* BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined
* in the type_array table below + bim_kbalign.
@ -1114,6 +1182,10 @@ static struct blkid_magic type_array[] = {
{ "crypt_LUKS", 0, 0, 6, "LUKS\xba\xbe", probe_luks },
{ "squashfs", 0, 0, 4, "sqsh", 0 },
{ "squashfs", 0, 0, 4, "hsqs", 0 },
{ "lvm2pv", 0, 0x218, 8, "LVM2 001", probe_lvm2 },
{ "lvm2pv", 0, 0x018, 8, "LVM2 001", probe_lvm2 },
{ "lvm2pv", 1, 0x018, 8, "LVM2 001", probe_lvm2 },
{ "lvm2pv", 1, 0x218, 8, "LVM2 001", probe_lvm2 },
{ NULL, 0, 0, 0, NULL, NULL }
};

View File

@ -531,6 +531,20 @@ struct hfs_mdb {
__u16 embed_blockcount;
} __attribute__((packed));
/* this is lvm's label_header & pv_header combined. */
#define LVM2_ID_LEN 32
struct lvm2_pv_label_header {
/* label_header */
__u8 id[8]; /* LABELONE */
__u64 sector_xl; /* Sector number of this label */
__u32 crc_xl; /* From next field to end of sector */
__u32 offset_xl; /* Offset from start of struct to contents */
__u8 type[8]; /* LVM2 001 */
/* pv_header */
__u8 pv_uuid[LVM2_ID_LEN];
} __attribute__ ((packed));
/*
* Byte swap functions

View File

@ -7,7 +7,9 @@
#define E2P_FEATURE_COMPAT 0
#define E2P_FEATURE_INCOMPAT 1
#define E2P_FEATURE_RO_INCOMPAT 2
#define E2P_FEATURE_TYPE_MASK 0x03
#define E2P_FEATURE_NEGATE_FLAG 0x80
/* `options' for print_flags() */
@ -34,6 +36,9 @@ int setversion (int fd, unsigned long version);
const char *e2p_feature2string(int compat, unsigned int mask);
int e2p_string2feature(char *string, int *compat, unsigned int *mask);
int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array);
int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
__u32 *clear_ok_array, int *type_err,
unsigned int *mask_err);
int e2p_is_null_uuid(void *uu);
void e2p_uuid_to_str(void *uu, char *out);

View File

@ -163,9 +163,12 @@ static char *skip_over_word(char *cp)
/*
* Edit a feature set array as requested by the user. The ok_array,
* if set, allows the application to limit what features the user is
* allowed to set or clear using this function.
* allowed to set or clear using this function. If clear_ok_array is set,
* then use it tell whether or not it is OK to clear a filesystem feature.
*/
int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
__u32 *clear_ok_array, int *type_err,
unsigned int *mask_err)
{
char *cp, *buf, *next;
int neg;
@ -173,6 +176,14 @@ int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
int compat_type;
int rc = 0;
if (!clear_ok_array)
clear_ok_array = ok_array;
if (type_err)
*type_err = 0;
if (mask_err)
*mask_err = 0;
buf = malloc(strlen(str)+1);
if (!buf)
return 1;
@ -207,15 +218,35 @@ int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
rc = 1;
break;
}
if (ok_array && !(ok_array[compat_type] & mask)) {
rc = 1;
break;
}
if (neg)
if (neg) {
if (clear_ok_array &&
!(clear_ok_array[compat_type] & mask)) {
rc = 1;
if (type_err)
*type_err = (compat_type |
E2P_FEATURE_NEGATE_FLAG);
if (mask_err)
*mask_err = mask;
break;
}
compat_array[compat_type] &= ~mask;
else
} else {
if (ok_array && !(ok_array[compat_type] & mask)) {
rc = 1;
if (type_err)
*type_err = compat_type;
if (mask_err)
*mask_err = mask;
break;
}
compat_array[compat_type] |= mask;
}
}
free(buf);
return rc;
}
int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
{
return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
}

View File

@ -234,10 +234,10 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
fprintf(f, "Inodes per group: %u\n", sb->s_inodes_per_group);
fprintf(f, "Inode blocks per group: %u\n", inode_blocks_per_group);
if (sb->s_raid_stride)
fprintf(f, "Raid stride: %u\n",
fprintf(f, "RAID stride: %u\n",
sb->s_raid_stride);
if (sb->s_raid_stripe_width)
fprintf(f, "Raid stripe width: %u\n",
fprintf(f, "RAID stripe width: %u\n",
sb->s_raid_stripe_width);
if (sb->s_first_meta_bg)
fprintf(f, "First meta block group: %u\n",

View File

@ -134,7 +134,6 @@ errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
ext2fs_block_alloc_stats(fs, block, +1);
*ret = block;
return 0;
fail:
if (buf)

View File

@ -171,6 +171,7 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_IMAGE_FILE 0x2000
#define EXT2_FLAG_EXCLUSIVE 0x4000
#define EXT2_FLAG_SOFTSUPP_FEATURES 0x8000
#define EXT2_FLAG_NOFREE_ON_ERROR 0x10000
/*
* Special flag in the ext2 inode i_flag field that means that this is

View File

@ -303,10 +303,14 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
fs->stride = fs->super->s_raid_stride;
fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
*ret_fs = fs;
return 0;
cleanup:
ext2fs_free(fs);
if (flags & EXT2_FLAG_NOFREE_ON_ERROR)
*ret_fs = fs;
else
ext2fs_free(fs);
return retval;
}

View File

@ -11,12 +11,10 @@ dumpe2fs \- dump ext2/ext3 filesystem information
.B \-bfhixV
]
[
.B \-ob
.I superblock
.B \-o superblock=\fIsuperblock
]
[
.B \-oB
.I blocksize
.B \-o blocksize=\fIblocksize
]
.I device
.SH DESCRIPTION
@ -34,14 +32,14 @@ program for the BSD Fast File System.
.B \-b
print the blocks which are reserved as bad in the filesystem.
.TP
.BI \-ob " superblock"
.B \-o superblock=\fIsuperblock
use the block
.I superblock
when examining the filesystem.
This option is not usually needed except by a filesystem wizard who
is examining the remains of a very badly corrupted filesystem.
.TP
.BI \-oB " blocksize"
.B \-o blocksize=\fIblocksize
use blocks of
.I blocksize
bytes when examining the filesystem.

View File

@ -333,6 +333,83 @@ static void print_journal_information(ext2_filsys fs)
}
}
static void parse_extended_opts(const char *opts, blk_t *superblock,
int *blocksize)
{
char *buf, *token, *next, *p, *arg, *badopt = "";
int len;
int usage = 0;
len = strlen(opts);
buf = malloc(len+1);
if (!buf) {
fprintf(stderr,
_("Couldn't allocate memory to parse options!\n"));
exit(1);
}
strcpy(buf, opts);
for (token = buf; token && *token; token = next) {
p = strchr(token, ',');
next = 0;
if (p) {
*p = 0;
next = p+1;
}
arg = strchr(token, '=');
if (arg) {
*arg = 0;
arg++;
}
if (strcmp(token, "superblock") == 0 ||
strcmp(token, "sb") == 0) {
if (!arg) {
usage++;
badopt = token;
continue;
}
*superblock = strtoul(arg, &p, 0);
if (*p) {
fprintf(stderr,
_("Invalid superblock parameter: %s\n"),
arg);
usage++;
continue;
}
} else if (strcmp(token, "blocksize") == 0 ||
strcmp(token, "bs") == 0) {
if (!arg) {
usage++;
badopt = token;
continue;
}
*blocksize = strtoul(arg, &p, 0);
if (*p) {
fprintf(stderr,
_("Invalid blocksize parameter: %s\n"),
arg);
usage++;
continue;
}
} else {
usage++;
badopt = token;
}
}
if (usage) {
fprintf(stderr, _("\nBad extended option(s) specified: %s\n\n"
"Extended options are separated by commas, "
"and may take an argument which\n"
"\tis set off by an equals ('=') sign.\n\n"
"Valid extended options are:\n"
"\tsuperblock=<superblock number>\n"
"\tblocksize=<blocksize>\n"),
badopt);
free(buf);
exit(1);
}
free(buf);
}
int main (int argc, char ** argv)
{
errcode_t retval;
@ -373,12 +450,8 @@ int main (int argc, char ** argv)
image_dump++;
break;
case 'o':
if (optarg[0] == 'b')
use_superblock = atoi(optarg+1);
else if (optarg[0] == 'B')
use_blocksize = atoi(optarg+1);
else
usage();
parse_extended_opts(optarg, &use_superblock,
&use_blocksize);
break;
case 'V':
/* Print version number and exit */
@ -395,16 +468,26 @@ int main (int argc, char ** argv)
if (optind > argc - 1)
usage();
device_name = argv[optind++];
if (use_superblock && !use_blocksize)
use_blocksize = 1024;
flags = EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SOFTSUPP_FEATURES;
if (force)
flags |= EXT2_FLAG_FORCE;
if (image_dump)
flags |= EXT2_FLAG_IMAGE_FILE;
retval = ext2fs_open (device_name, flags, use_superblock,
use_blocksize, unix_io_manager, &fs);
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);

View File

@ -364,7 +364,7 @@ static void load_fs_info(const char *filename)
fclose(f);
if (old_fstab) {
if (old_fstab && filesys_info) {
fputs(_("\007\007\007"
"WARNING: Your /etc/fstab does not contain the fsck passno\n"
" field. I will kludge around things for you, but you\n"

View File

@ -415,6 +415,10 @@ prefix the feature name with a caret ('^') character. The
pseudo-filesystem feature "none" will clear all filesystem features.
.RS 1.2i
.TP
.B large_file
Filesystem can contain files that are greater than 2GB. (Modern kernels
set this feature automatically when a file > 2GB is created.)
.TP
.B dir_index
Use hashed b-trees to speed up lookups in large directories.
.TP

View File

@ -897,17 +897,21 @@ static void parse_extended_opts(struct ext2_super_block *param,
}
static __u32 ok_features[3] = {
/* Compat */
EXT3_FEATURE_COMPAT_HAS_JOURNAL |
EXT2_FEATURE_COMPAT_RESIZE_INODE |
EXT2_FEATURE_COMPAT_DIR_INDEX |
EXT2_FEATURE_COMPAT_LAZY_BG |
EXT2_FEATURE_COMPAT_EXT_ATTR, /* Compat */
EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */
EXT2_FEATURE_COMPAT_EXT_ATTR,
/* Incompat */
EXT2_FEATURE_INCOMPAT_FILETYPE|
EXT3_FEATURE_INCOMPAT_EXTENTS|
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
EXT2_FEATURE_INCOMPAT_META_BG|
EXT4_FEATURE_INCOMPAT_FLEX_BG,
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
};

View File

@ -415,6 +415,10 @@ The following filesystem features can be set or cleared using
.BR tune2fs :
.RS 1.2i
.TP
.B large_file
Filesystem can contain files that are greater than 2GB. (Modern kernels
set this feature automatically when a file > 2GB is created.)
.TP
.B dir_index
Use hashed b-trees to speed up lookups in large directories.
.TP
@ -429,12 +433,19 @@ option.
.TP
.B sparse_super
Limit the number of backup superblocks to save space on large filesystems.
.TP
.B resize_inode
Reserve space so the block group descriptor table may grow in the
future.
.B Tune2fs
only supports clearing this filesystem feature.
.RE
.IP
After setting or clearing
.B sparse_super
and
.B filetype
.BR sparse_super ,
.BR filetype ,
or
.B resize_inode
filesystem features,
.BR e2fsck (8)
must be run on the filesystem to return the filesystem to a consistent state.
@ -446,12 +457,6 @@ if necessary. After setting the
feature,
.B e2fsck -D
can be run to convert existing directories to the hashed B-tree format.
.IP
.B Warning:
Linux kernels before 2.0.39 and many 2.1 series kernels do not support
the filesystems that use any of these features.
Enabling certain filesystem features may prevent the filesystem from
being mounted by kernels which do not support those features.
.TP
.BI \-r " reserved-blocks-count"
Set the number of reserved filesystem blocks.
@ -461,14 +466,6 @@ Turn the sparse super feature off or on. Turning this feature on
saves space on really big filesystems. This is the same as using the
.B "\-O sparse_super"
option.
.IP
.B Warning:
Linux kernels before 2.0.39 do not support this feature. Neither do
all Linux 2.1 kernels; please don't use this unless you know what you're
doing! You need to run
.BR e2fsck (8)
on the filesystem after changing this feature in order to have a valid
filesystem.
.TP
.BI \-T " time-last-checked"
Set the time the filesystem was last checked using

View File

@ -108,12 +108,29 @@ static void usage(void)
}
static __u32 ok_features[3] = {
/* Compat */
EXT3_FEATURE_COMPAT_HAS_JOURNAL |
EXT2_FEATURE_COMPAT_DIR_INDEX, /* Compat */
EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */
EXT3_FEATURE_INCOMPAT_EXTENTS|
EXT2_FEATURE_COMPAT_DIR_INDEX,
/* Incompat */
EXT2_FEATURE_INCOMPAT_FILETYPE |
EXT3_FEATURE_INCOMPAT_EXTENTS |
EXT4_FEATURE_INCOMPAT_FLEX_BG,
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
};
static __u32 clear_ok_features[3] = {
/* Compat */
EXT3_FEATURE_COMPAT_HAS_JOURNAL |
EXT2_FEATURE_COMPAT_RESIZE_INODE |
EXT2_FEATURE_COMPAT_DIR_INDEX,
/* Incompat */
EXT2_FEATURE_INCOMPAT_FILETYPE |
EXT4_FEATURE_INCOMPAT_FLEX_BG,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
};
/*
@ -297,47 +314,44 @@ static void update_mntopts(ext2_filsys fs, char *mntopts)
*/
static void update_feature_set(ext2_filsys fs, char *features)
{
int sparse, old_sparse, filetype, old_filetype;
int journal, old_journal, dxdir, old_dxdir;
int flex_bg, old_flex_bg, extents, old_extents;
struct ext2_super_block *sb= fs->super;
__u32 old_compat, old_incompat, old_ro_compat;
__u32 old_features[3];
int type_err;
unsigned int mask_err;
old_compat = sb->s_feature_compat;
old_ro_compat = sb->s_feature_ro_compat;
old_incompat = sb->s_feature_incompat;
#define FEATURE_ON(type, mask) (!(old_features[(type)] & (mask)) && \
((&sb->s_feature_compat)[(type)] & (mask)))
#define FEATURE_OFF(type, mask) ((old_features[(type)] & (mask)) && \
!((&sb->s_feature_compat)[(type)] & (mask)))
#define FEATURE_CHANGED(type, mask) ((mask) & \
(old_features[(type)] ^ (&sb->s_feature_compat)[(type)]))
old_sparse = sb->s_feature_ro_compat &
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
old_filetype = sb->s_feature_incompat &
EXT2_FEATURE_INCOMPAT_FILETYPE;
old_extents = sb->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_EXTENTS;
old_flex_bg = sb->s_feature_incompat &
EXT4_FEATURE_INCOMPAT_FLEX_BG;
old_journal = sb->s_feature_compat &
EXT3_FEATURE_COMPAT_HAS_JOURNAL;
old_dxdir = sb->s_feature_compat &
EXT2_FEATURE_COMPAT_DIR_INDEX;
if (e2p_edit_feature(features, &sb->s_feature_compat,
ok_features)) {
fprintf(stderr, _("Invalid filesystem option set: %s\n"),
features);
old_features[E2P_FEATURE_COMPAT] = sb->s_feature_compat;
old_features[E2P_FEATURE_INCOMPAT] = sb->s_feature_incompat;
old_features[E2P_FEATURE_RO_INCOMPAT] = sb->s_feature_ro_compat;
if (e2p_edit_feature2(features, &sb->s_feature_compat,
ok_features, clear_ok_features,
&type_err, &mask_err)) {
if (!mask_err)
fprintf(stderr,
_("Invalid filesystem option set: %s\n"),
features);
else if (type_err & E2P_FEATURE_NEGATE_FLAG)
fprintf(stderr, _("Clearing filesystem feature '%s' "
"not supported.\n"),
e2p_feature2string(type_err &
E2P_FEATURE_TYPE_MASK,
mask_err));
else
fprintf(stderr, _("Setting filesystem feature '%s' "
"not supported.\n"),
e2p_feature2string(type_err, mask_err));
exit(1);
}
sparse = sb->s_feature_ro_compat &
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
filetype = sb->s_feature_incompat &
EXT2_FEATURE_INCOMPAT_FILETYPE;
extents = sb->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_EXTENTS;
flex_bg = sb->s_feature_incompat &
EXT4_FEATURE_INCOMPAT_FLEX_BG;
journal = sb->s_feature_compat &
EXT3_FEATURE_COMPAT_HAS_JOURNAL;
dxdir = sb->s_feature_compat &
EXT2_FEATURE_COMPAT_DIR_INDEX;
if (old_journal && !journal) {
if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
if ((mount_flags & EXT2_MF_MOUNTED) &&
!(mount_flags & EXT2_MF_READONLY)) {
fputs(_("The has_journal flag may only be "
@ -360,7 +374,8 @@ static void update_feature_set(ext2_filsys fs, char *features)
remove_journal_device(fs);
}
}
if (journal && !old_journal) {
if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
/*
* If adding a journal flag, let the create journal
* code below handle creating setting the flag and
@ -371,18 +386,15 @@ static void update_feature_set(ext2_filsys fs, char *features)
journal_size = -1;
sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
}
if (old_extents && !extents) {
fputs(_("Clearing the extents feature flag not supported.\n"),
stderr);
exit(1);
}
if (dxdir && !old_dxdir) {
if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX)) {
if (!sb->s_def_hash_version)
sb->s_def_hash_version = EXT2_HASH_TEA;
if (uuid_is_null((unsigned char *) sb->s_hash_seed))
uuid_generate((unsigned char *) sb->s_hash_seed);
}
if (!flex_bg && old_flex_bg) {
if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
if (ext2fs_check_desc(fs)) {
fputs(_("Clearing the flex_bg flag would "
"cause the the filesystem to be\n"
@ -395,14 +407,22 @@ static void update_feature_set(ext2_filsys fs, char *features)
(sb->s_feature_compat || sb->s_feature_ro_compat ||
sb->s_feature_incompat))
ext2fs_update_dynamic_rev(fs);
if ((sparse != old_sparse) ||
(filetype != old_filetype)) {
if (FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT,
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
FEATURE_CHANGED(E2P_FEATURE_INCOMPAT,
EXT2_FEATURE_INCOMPAT_FILETYPE) ||
FEATURE_CHANGED(E2P_FEATURE_COMPAT,
EXT2_FEATURE_COMPAT_RESIZE_INODE) ||
FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
sb->s_state &= ~EXT2_VALID_FS;
printf("\n%s\n", _(please_fsck));
}
if ((old_compat != sb->s_feature_compat) ||
(old_ro_compat != sb->s_feature_ro_compat) ||
(old_incompat != sb->s_feature_incompat))
if ((old_features[E2P_FEATURE_COMPAT] != sb->s_feature_compat) ||
(old_features[E2P_FEATURE_INCOMPAT] != sb->s_feature_incompat) ||
(old_features[E2P_FEATURE_RO_INCOMPAT] != sb->s_feature_ro_compat))
ext2fs_mark_super_dirty(fs);
}

View File

@ -151,6 +151,7 @@ Blocks per group: 1024
Fragments per group: 1024
Inodes per group: 256
Inode blocks per group: 32
RAID stride: 13
Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0