Merge branch 'next'

crypto
Theodore Ts'o 2014-07-29 10:56:34 -04:00
commit 5543f45eea
61 changed files with 1410 additions and 319 deletions

4
configure vendored
View File

@ -12404,7 +12404,7 @@ fi
done
fi
for ac_header in dirent.h errno.h execinfo.h getopt.h malloc.h mntent.h paths.h semaphore.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h termio.h unistd.h utime.h linux/falloc.h linux/fd.h linux/major.h linux/loop.h net/if_dl.h netinet/in.h sys/disklabel.h sys/disk.h sys/file.h sys/ioctl.h sys/mkdev.h sys/mman.h sys/mount.h sys/prctl.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h
for ac_header in dirent.h errno.h execinfo.h getopt.h malloc.h mntent.h paths.h semaphore.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h termio.h unistd.h utime.h attr/xattr.h linux/falloc.h linux/fd.h linux/major.h linux/loop.h net/if_dl.h netinet/in.h sys/disklabel.h sys/disk.h sys/file.h sys/ioctl.h sys/mkdev.h sys/mman.h sys/mount.h sys/prctl.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -13071,7 +13071,7 @@ if test "$ac_res" != no; then :
fi
fi
for ac_func in __secure_getenv backtrace blkid_probe_get_topology blkid_probe_enable_partitions chflags fadvise64 fallocate fallocate64 fchown fdatasync fstat64 ftruncate64 futimes getcwd getdtablesize getmntinfo getpwuid_r getrlimit getrusage jrand48 llseek lseek64 mallinfo mbstowcs memalign mempcpy mmap msync nanosleep open64 pathconf posix_fadvise posix_fadvise64 posix_memalign prctl secure_getenv setmntent setresgid setresuid snprintf srandom stpcpy strcasecmp strdup strnlen strptime strtoull sync_file_range sysconf usleep utime valloc
for ac_func in __secure_getenv backtrace blkid_probe_get_topology blkid_probe_enable_partitions chflags fadvise64 fallocate fallocate64 fchown fdatasync fstat64 ftruncate64 futimes getcwd getdtablesize getmntinfo getpwuid_r getrlimit getrusage jrand48 llistxattr llseek lseek64 mallinfo mbstowcs memalign mempcpy mmap msync nanosleep open64 pathconf posix_fadvise posix_fadvise64 posix_memalign prctl secure_getenv setmntent setresgid setresuid snprintf srandom stpcpy strcasecmp strdup strnlen strptime strtoull sync_file_range sysconf usleep utime valloc
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -920,6 +920,7 @@ AC_CHECK_HEADERS(m4_flatten([
termio.h
unistd.h
utime.h
attr/xattr.h
linux/falloc.h
linux/fd.h
linux/major.h
@ -1098,6 +1099,7 @@ AC_CHECK_FUNCS(m4_flatten([
getrlimit
getrusage
jrand48
llistxattr
llseek
lseek64
mallinfo

View File

@ -2094,7 +2094,6 @@ void do_symlink(int argc, char *argv[])
void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[])
{
#if CONFIG_MMP
struct ext2_super_block *sb;
struct mmp_struct *mmp_s;
time_t t;
errcode_t retval = 0;
@ -2102,8 +2101,6 @@ void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[])
if (check_fs_open(argv[0]))
return;
sb = current_fs->super;
if (current_fs->mmp_buf == NULL) {
retval = ext2fs_get_mem(current_fs->blocksize,
&current_fs->mmp_buf);

View File

@ -369,6 +369,9 @@ struct e2fsck_struct {
profile_t profile;
int blocks_per_page;
/* Reserve blocks for root and l+f re-creation */
blk64_t root_repair_block, lnf_repair_block;
/*
* For the use of callers of the e2fsck functions; not used by
* e2fsck functions themselves.

View File

@ -443,8 +443,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
if (ext_journal) {
blk64_t maxlen;
if (ctx->fs->blocksize == 1024)
start = 1;
start = ext2fs_journal_sb_start(ctx->fs->blocksize) - 1;
bh = getblk(dev_journal, start, ctx->fs->blocksize);
if (!bh) {
retval = EXT2_ET_NO_MEMORY;
@ -455,7 +454,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
brelse(bh);
goto errout;
}
memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
memcpy(&jsuper, start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET,
sizeof(jsuper));
brelse(bh);
#ifdef WORDS_BIGENDIAN

View File

@ -277,8 +277,7 @@ static void check_size(e2fsck_t ctx, struct problem_context *pctx)
if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
return;
inode->i_size = 0;
inode->i_size_high = 0;
ext2fs_inode_size_set(ctx->fs, inode, 0);
e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
}
@ -601,6 +600,42 @@ static errcode_t recheck_bad_inode_checksum(ext2_filsys fs, ext2_ino_t ino,
return 0;
}
static void reserve_block_for_root_repair(e2fsck_t ctx)
{
blk64_t blk = 0;
errcode_t err;
ext2_filsys fs = ctx->fs;
ctx->root_repair_block = 0;
if (ext2fs_test_inode_bitmap2(ctx->inode_used_map, EXT2_ROOT_INO))
return;
err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
if (err)
return;
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
ctx->root_repair_block = blk;
}
static void reserve_block_for_lnf_repair(e2fsck_t ctx)
{
blk64_t blk = 0;
errcode_t err;
ext2_filsys fs = ctx->fs;
static const char name[] = "lost+found";
ext2_ino_t ino;
ctx->lnf_repair_block = 0;
if (!ext2fs_lookup(fs, EXT2_ROOT_INO, name, sizeof(name)-1, 0, &ino))
return;
err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
if (err)
return;
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
ctx->lnf_repair_block = blk;
}
void e2fsck_pass1(e2fsck_t ctx)
{
int i;
@ -935,8 +970,10 @@ void e2fsck_pass1(e2fsck_t ctx)
if (ino == EXT2_BAD_INO) {
struct process_block_struct pb;
if ((inode->i_mode || inode->i_uid || inode->i_gid ||
inode->i_links_count || inode->i_file_acl) &&
if ((failed_csum || inode->i_mode || inode->i_uid ||
inode->i_gid || inode->i_links_count ||
(inode->i_flags & EXT4_INLINE_DATA_FL) ||
inode->i_file_acl) &&
fix_problem(ctx, PR_1_INVALID_BAD_INODE, &pctx)) {
memset(inode, 0, sizeof(struct ext2_inode));
e2fsck_write_inode(ctx, ino, inode,
@ -1280,6 +1317,9 @@ void e2fsck_pass1(e2fsck_t ctx)
ext2fs_close_inode_scan(scan);
scan = NULL;
reserve_block_for_root_repair(ctx);
reserve_block_for_lnf_repair(ctx);
/*
* If any extended attribute blocks' reference counts need to
* be adjusted, either up (ctx->refcount_extra), or down
@ -1906,6 +1946,40 @@ void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
e2fsck_write_inode(ctx, ino, inode, source);
}
/*
* Use the multiple-blocks reclamation code to fix alignment problems in
* a bigalloc filesystem. We want a logical cluster to map to *only* one
* physical cluster, and we want the block offsets within that cluster to
* line up.
*/
static int has_unaligned_cluster_map(e2fsck_t ctx,
blk64_t last_pblk, e2_blkcnt_t last_lblk,
blk64_t pblk, blk64_t lblk)
{
blk64_t cluster_mask;
if (!ctx->fs->cluster_ratio_bits)
return 0;
cluster_mask = EXT2FS_CLUSTER_MASK(ctx->fs);
/*
* If the block in the logical cluster doesn't align with the block in
* the physical cluster...
*/
if ((lblk & cluster_mask) != (pblk & cluster_mask))
return 1;
/*
* If we cross a physical cluster boundary within a logical cluster...
*/
if (last_pblk && (lblk & cluster_mask) != 0 &&
EXT2FS_B2C(ctx->fs, lblk) == EXT2FS_B2C(ctx->fs, last_lblk) &&
EXT2FS_B2C(ctx->fs, pblk) != EXT2FS_B2C(ctx->fs, last_pblk))
return 1;
return 0;
}
static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
struct process_block_struct *pb,
blk64_t start_block, blk64_t end_block,
@ -1937,12 +2011,14 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
last_lblk = extent.e_lblk + extent.e_len - 1;
problem = 0;
pctx->blk = extent.e_pblk;
pctx->blk2 = extent.e_lblk;
pctx->num = extent.e_len;
pctx->blkcount = extent.e_lblk + extent.e_len;
/* Ask to clear a corrupt extent block */
if (try_repairs &&
pctx->errcode == EXT2_ET_EXTENT_CSUM_INVALID) {
pctx->blk = extent.e_pblk;
pctx->blk2 = extent.e_lblk;
pctx->num = extent.e_len;
problem = PR_1_EXTENT_CSUM_INVALID;
if (fix_problem(ctx, problem, pctx))
goto fix_problem_now;
@ -1970,19 +2046,6 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
(1 << (21 - ctx->fs->super->s_log_block_size))))
problem = PR_1_TOOBIG_DIR;
/* Corrupt but passes checks? Ask to fix checksum. */
if (try_repairs && failed_csum) {
pctx->blk = extent.e_pblk;
pctx->blk2 = extent.e_lblk;
pctx->num = extent.e_len;
problem = 0;
if (fix_problem(ctx, PR_1_EXTENT_ONLY_CSUM_INVALID,
pctx)) {
pb->inode_modified = 1;
ext2fs_extent_replace(ehandle, 0, &extent);
}
}
/*
* Uninitialized blocks in a directory? Clear the flag and
* we'll interpret the blocks later.
@ -1999,12 +2062,18 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
failed_csum = 0;
}
/* Failed csum but passes checks? Ask to fix checksum. */
if (try_repairs && failed_csum && problem == 0 &&
fix_problem(ctx, PR_1_EXTENT_ONLY_CSUM_INVALID, pctx)) {
pb->inode_modified = 1;
pctx->errcode = ext2fs_extent_replace(ehandle,
0, &extent);
if (pctx->errcode)
return;
}
if (try_repairs && problem) {
report_problem:
pctx->blk = extent.e_pblk;
pctx->blk2 = extent.e_lblk;
pctx->num = extent.e_len;
pctx->blkcount = extent.e_lblk + extent.e_len;
if (fix_problem(ctx, problem, pctx)) {
fix_problem_now:
if (ctx->invalid_bitmaps) {
@ -2210,7 +2279,16 @@ alloc_later:
mark_block_used(ctx, blk);
pb->num_blocks++;
}
if (has_unaligned_cluster_map(ctx, pb->previous_block,
pb->last_block, blk,
blockcnt)) {
pctx->blk = blockcnt;
pctx->blk2 = blk;
fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
mark_block_used(ctx, blk);
mark_block_used(ctx, blk);
}
pb->last_block = blockcnt;
pb->previous_block = blk;
if (is_dir) {
@ -2505,9 +2583,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
pctx->num = (pb.last_block+1) * fs->blocksize;
pctx->group = bad_size;
if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
inode->i_size = pctx->num;
if (!LINUX_S_ISDIR(inode->i_mode))
inode->i_size_high = pctx->num >> 32;
if (LINUX_S_ISDIR(inode->i_mode))
pctx->num &= 0xFFFFFFFFULL;
ext2fs_inode_size_set(fs, inode, pctx->num);
dirty_inode++;
}
pctx->num = 0;
@ -2776,6 +2854,13 @@ static int process_block(ext2_filsys fs,
((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
mark_block_used(ctx, blk);
p->num_blocks++;
} else if (has_unaligned_cluster_map(ctx, p->previous_block,
p->last_block, blk, blockcnt)) {
pctx->blk = blockcnt;
pctx->blk2 = blk;
fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
mark_block_used(ctx, blk);
mark_block_used(ctx, blk);
}
if (blockcnt >= 0)
p->last_block = blockcnt;

View File

@ -261,7 +261,7 @@ struct process_block_struct {
e2fsck_t ctx;
ext2_ino_t ino;
int dup_blocks;
blk64_t cur_cluster;
blk64_t cur_cluster, phys_cluster;
blk64_t last_blk;
struct ext2_inode *inode;
struct problem_context *pctx;
@ -317,6 +317,7 @@ static void pass1b(e2fsck_t ctx, char *block_buf)
pb.dup_blocks = 0;
pb.inode = &inode;
pb.cur_cluster = ~0;
pb.phys_cluster = ~0;
pb.last_blk = 0;
pb.pctx->blk = pb.pctx->blk2 = 0;
@ -360,7 +361,7 @@ static int process_pass1b_block(ext2_filsys fs EXT2FS_ATTR((unused)),
{
struct process_block_struct *p;
e2fsck_t ctx;
blk64_t lc;
blk64_t lc, pc;
problem_t op;
if (HOLE_BLKADDR(*block_nr))
@ -368,6 +369,7 @@ static int process_pass1b_block(ext2_filsys fs EXT2FS_ATTR((unused)),
p = (struct process_block_struct *) priv_data;
ctx = p->ctx;
lc = EXT2FS_B2C(fs, blockcnt);
pc = EXT2FS_B2C(fs, *block_nr);
if (!ext2fs_test_block_bitmap2(ctx->block_dup_map, *block_nr))
goto finish;
@ -389,11 +391,19 @@ static int process_pass1b_block(ext2_filsys fs EXT2FS_ATTR((unused)),
p->dup_blocks++;
ext2fs_mark_inode_bitmap2(inode_dup_map, p->ino);
if (blockcnt < 0 || lc != p->cur_cluster)
/*
* Qualifications for submitting a block for duplicate processing:
* It's an extent/indirect block (and has a negative logical offset);
* we've crossed a logical cluster boundary; or the physical cluster
* suddenly changed, which indicates that blocks in a logical cluster
* are mapped to multiple physical clusters.
*/
if (blockcnt < 0 || lc != p->cur_cluster || pc != p->phys_cluster)
add_dupe(ctx, p->ino, EXT2FS_B2C(fs, *block_nr), p->inode);
finish:
p->cur_cluster = lc;
p->phys_cluster = pc;
return 0;
}
@ -563,7 +573,11 @@ static void pass1d(e2fsck_t ctx, char *block_buf)
pctx.dir = t->dir;
fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
}
if (file_ok) {
/*
* Even if the file shares blocks with itself, we still need to
* clone the blocks.
*/
if (file_ok && (meta_data ? shared_len+1 : shared_len) != 0) {
fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
continue;
}
@ -630,7 +644,8 @@ static int delete_file_block(ext2_filsys fs,
_("internal error: can't find dup_blk for %llu\n"),
*block_nr);
} else {
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
if ((*block_nr % EXT2FS_CLUSTER_RATIO(ctx->fs)) == 0)
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
pb->dup_blocks++;
}
pb->cur_cluster = lc;
@ -706,9 +721,10 @@ struct clone_struct {
errcode_t errcode;
blk64_t dup_cluster;
blk64_t alloc_block;
ext2_ino_t dir;
ext2_ino_t dir, ino;
char *buf;
e2fsck_t ctx;
struct ext2_inode *inode;
};
static int clone_file_block(ext2_filsys fs,
@ -756,13 +772,26 @@ static int clone_file_block(ext2_filsys fs,
decrement_badcount(ctx, *block_nr, p);
cs->dup_cluster = c;
/*
* Let's try an implied cluster allocation. If we get the same
* cluster back, then we need to find a new block; otherwise,
* we're merely fixing the problem of one logical cluster being
* mapped to multiple physical clusters.
*/
new_block = 0;
retval = ext2fs_map_cluster_block(fs, cs->ino, cs->inode,
blockcnt, &new_block);
if (retval == 0 && new_block != 0 &&
EXT2FS_B2C(ctx->fs, new_block) !=
EXT2FS_B2C(ctx->fs, *block_nr))
goto cluster_alloc_ok;
retval = ext2fs_new_block2(fs, 0, ctx->block_found_map,
&new_block);
if (retval) {
cs->errcode = retval;
return BLOCK_ABORT;
}
cluster_alloc_ok:
cs->alloc_block = new_block;
got_block:
@ -817,6 +846,8 @@ static errcode_t clone_file(e2fsck_t ctx, ext2_ino_t ino,
cs.dup_cluster = ~0;
cs.alloc_block = 0;
cs.ctx = ctx;
cs.ino = ino;
cs.inode = &dp->inode;
retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
if (retval)
return retval;

View File

@ -665,7 +665,8 @@ clear_and_exit:
static void salvage_directory(ext2_filsys fs,
struct ext2_dir_entry *dirent,
struct ext2_dir_entry *prev,
unsigned int *offset)
unsigned int *offset,
unsigned int block_len)
{
char *cp = (char *) dirent;
int left;
@ -673,7 +674,7 @@ static void salvage_directory(ext2_filsys fs,
unsigned int name_len = ext2fs_dirent_name_len(dirent);
(void) ext2fs_get_rec_len(fs, dirent, &rec_len);
left = fs->blocksize - *offset - rec_len;
left = block_len - *offset - rec_len;
/*
* Special case of directory entry of size 8: copy what's left
@ -703,7 +704,7 @@ static void salvage_directory(ext2_filsys fs,
* previous directory entry absorb the invalid one.
*/
if (prev && rec_len && (rec_len % 4) == 0 &&
(*offset + rec_len <= fs->blocksize)) {
(*offset + rec_len <= block_len)) {
(void) ext2fs_get_rec_len(fs, prev, &prev_rec_len);
prev_rec_len += rec_len;
(void) ext2fs_set_rec_len(fs, prev_rec_len, prev);
@ -718,11 +719,11 @@ static void salvage_directory(ext2_filsys fs,
*/
if (prev) {
(void) ext2fs_get_rec_len(fs, prev, &prev_rec_len);
prev_rec_len += fs->blocksize - *offset;
prev_rec_len += block_len - *offset;
(void) ext2fs_set_rec_len(fs, prev_rec_len, prev);
*offset = fs->blocksize;
} else {
rec_len = fs->blocksize - *offset;
rec_len = block_len - *offset;
(void) ext2fs_set_rec_len(fs, rec_len, dirent);
ext2fs_dirent_set_name_len(dirent, 0);
ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN);
@ -739,6 +740,38 @@ static int is_last_entry(ext2_filsys fs, int inline_data_size,
return (offset < fs->blocksize - csum_size);
}
#define NEXT_DIRENT(d) ((void *)((char *)(d) + (d)->rec_len))
static errcode_t insert_dirent_tail(ext2_filsys fs, void *dirbuf)
{
struct ext2_dir_entry *d;
void *top;
struct ext2_dir_entry_tail *t;
unsigned int rec_len;
d = dirbuf;
top = EXT2_DIRENT_TAIL(dirbuf, fs->blocksize);
while (d->rec_len && !(d->rec_len & 0x3) && NEXT_DIRENT(d) <= top)
d = NEXT_DIRENT(d);
if (d != top) {
size_t min_size = EXT2_DIR_REC_LEN(
ext2fs_dirent_name_len(dirbuf));
if (min_size > top - (void *)d)
return EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
d->rec_len = top - (void *)d;
}
t = (struct ext2_dir_entry_tail *)top;
if (t->det_reserved_zero1 ||
t->det_rec_len != sizeof(struct ext2_dir_entry_tail) ||
t->det_reserved_name_len != EXT2_DIR_NAME_LEN_CSUM)
ext2fs_initialize_dirent_tail(fs, t);
return 0;
}
#undef NEXT_DIRENT
static int check_dir_block(ext2_filsys fs,
struct ext2_db_entry2 *db,
void *priv_data)
@ -960,8 +993,12 @@ skip_checksum:
(rec_len < 12) ||
((rec_len % 4) != 0) ||
((ext2fs_dirent_name_len(dirent) + 8) > rec_len)) {
if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
salvage_directory(fs, dirent, prev, &offset);
if (fix_problem(ctx, PR_2_DIR_CORRUPTED,
&cd->pctx)) {
salvage_directory(fs, dirent, prev,
&offset,
fs->blocksize -
de_csum_size);
dir_modified++;
continue;
} else
@ -1275,8 +1312,12 @@ skip_checksum:
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
is_leaf &&
!ext2fs_dirent_has_tail(fs, (struct ext2_dir_entry *)buf))
!inline_data_size &&
!ext2fs_dirent_has_tail(fs, (struct ext2_dir_entry *)buf)) {
if (insert_dirent_tail(fs, buf) == 0)
goto write_and_fix;
e2fsck_rehash_dir_later(ctx, ino);
}
write_and_fix:
if (e2fsck_dir_will_be_rehashed(ctx, ino))
@ -1336,7 +1377,8 @@ static int deallocate_inode_block(ext2_filsys fs,
if ((*block_nr < fs->super->s_first_data_block) ||
(*block_nr >= ext2fs_blocks_count(fs->super)))
return 0;
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
if ((*block_nr % EXT2FS_CLUSTER_RATIO(fs)) == 0)
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
p->num++;
return 0;
}
@ -1577,7 +1619,7 @@ static int allocate_dir_block(e2fsck_t ctx,
struct problem_context *pctx)
{
ext2_filsys fs = ctx->fs;
blk64_t blk;
blk64_t blk = 0;
char *block;
struct ext2_inode inode;
@ -1593,11 +1635,17 @@ static int allocate_dir_block(e2fsck_t ctx,
/*
* First, find a free block
*/
pctx->errcode = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
if (pctx->errcode) {
pctx->str = "ext2fs_new_block";
fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
return 1;
e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
pctx->errcode = ext2fs_map_cluster_block(fs, db->ino, &inode,
db->blockcnt, &blk);
if (pctx->errcode || blk == 0) {
pctx->errcode = ext2fs_new_block2(fs, 0,
ctx->block_found_map, &blk);
if (pctx->errcode) {
pctx->str = "ext2fs_new_block";
fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
return 1;
}
}
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
ext2fs_mark_block_bitmap2(fs->block_map, blk);
@ -1629,10 +1677,16 @@ static int allocate_dir_block(e2fsck_t ctx,
/*
* Update the inode block count
*/
e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
ext2fs_iblk_add_blocks(fs, &inode, 1);
if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
inode.i_size = (db->blockcnt+1) * fs->blocksize;
if (EXT2_I_SIZE(&inode) < (db->blockcnt+1) * fs->blocksize) {
pctx->errcode = ext2fs_inode_size_set(fs, &inode,
(db->blockcnt+1) * fs->blocksize);
if (pctx->errcode) {
pctx->str = "ext2fs_inode_size_set";
fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
return 1;
}
}
e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
/*

View File

@ -134,6 +134,17 @@ abort_exit:
inode_done_map = 0;
}
if (ctx->lnf_repair_block) {
ext2fs_unmark_block_bitmap2(ctx->block_found_map,
ctx->lnf_repair_block);
ctx->lnf_repair_block = 0;
}
if (ctx->root_repair_block) {
ext2fs_unmark_block_bitmap2(ctx->block_found_map,
ctx->root_repair_block);
ctx->root_repair_block = 0;
}
print_resource_track(ctx, _("Pass 3"), &rtrack, ctx->fs->io);
}
@ -176,6 +187,11 @@ static void check_root(e2fsck_t ctx)
/*
* First, find a free block
*/
if (ctx->root_repair_block) {
blk = ctx->root_repair_block;
ctx->root_repair_block = 0;
goto skip_new_block;
}
pctx.errcode = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
if (pctx.errcode) {
pctx.str = "ext2fs_new_block";
@ -184,31 +200,10 @@ static void check_root(e2fsck_t ctx)
return;
}
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
skip_new_block:
ext2fs_mark_block_bitmap2(fs->block_map, blk);
ext2fs_mark_bb_dirty(fs);
/*
* Now let's create the actual data block for the inode
*/
pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
&block);
if (pctx.errcode) {
pctx.str = "ext2fs_new_dir_block";
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
EXT2_ROOT_INO);
if (pctx.errcode) {
pctx.str = "ext2fs_write_dir_block4";
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
ext2fs_free_mem(&block);
/*
* Set up the inode structure
*/
@ -231,6 +226,30 @@ static void check_root(e2fsck_t ctx)
return;
}
/*
* Now let's create the actual data block for the inode.
* Due to metadata_csum, we must write the dir blocks AFTER
* the inode has been written to disk!
*/
pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
&block);
if (pctx.errcode) {
pctx.str = "ext2fs_new_dir_block";
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
EXT2_ROOT_INO);
ext2fs_free_mem(&block);
if (pctx.errcode) {
pctx.str = "ext2fs_write_dir_block4";
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
/*
* Miscellaneous bookkeeping...
*/
@ -425,6 +444,11 @@ unlink:
/*
* First, find a free block
*/
if (ctx->lnf_repair_block) {
blk = ctx->lnf_repair_block;
ctx->lnf_repair_block = 0;
goto skip_new_block;
}
retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
if (retval) {
pctx.errcode = retval;
@ -432,6 +456,7 @@ unlink:
return 0;
}
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
skip_new_block:
ext2fs_block_alloc_stats2(fs, blk, +1);
/*
@ -448,24 +473,6 @@ unlink:
ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
/*
* Now let's create the actual data block for the inode
*/
retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
if (retval) {
pctx.errcode = retval;
fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
return 0;
}
retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
ext2fs_free_mem(&block);
if (retval) {
pctx.errcode = retval;
fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
return 0;
}
/*
* Set up the inode structure
*/
@ -486,6 +493,27 @@ unlink:
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
return 0;
}
/*
* Now let's create the actual data block for the inode.
* Due to metadata_csum, the directory block MUST be written
* after the inode is written to disk!
*/
retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
if (retval) {
pctx.errcode = retval;
fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
return 0;
}
retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
ext2fs_free_mem(&block);
if (retval) {
pctx.errcode = retval;
fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
return 0;
}
/*
* Finally, create the directory link
*/
@ -823,8 +851,9 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
return retval;
sz = (es.last_block + 1) * fs->blocksize;
inode.i_size = sz;
inode.i_size_high = sz >> 32;
retval = ext2fs_inode_size_set(fs, &inode, sz);
if (retval)
return retval;
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
quota_data_add(ctx->qctx, &inode, dir, es.newblocks * fs->blocksize);

View File

@ -327,7 +327,6 @@ static void check_block_bitmaps(e2fsck_t ctx)
problem_t problem, save_problem;
int fixit, had_problem;
errcode_t retval;
int csum_flag;
int old_desc_blocks = 0;
int count = 0;
int cmp_block = 0;
@ -374,7 +373,6 @@ static void check_block_bitmaps(e2fsck_t ctx)
goto errout;
}
csum_flag = ext2fs_has_group_desc_csum(fs);
redo_counts:
had_problem = 0;
save_problem = 0;
@ -898,7 +896,7 @@ static void check_block_end(e2fsck_t ctx)
clear_problem_context(&pctx);
end = ext2fs_get_block_bitmap_start2(fs->block_map) +
((blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
EXT2_GROUPS_TO_CLUSTERS(fs->super, fs->group_desc_count) - 1;
pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, end,
&save_blocks_count);
if (pctx.errcode) {

View File

@ -992,19 +992,17 @@ static struct e2fsck_problem problem_table[] = {
"extent\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
PROMPT_FIX, 0 },
/* Extended attribute block checksum for inode does not match. */
/* Inode extended attribute block checksum does not match block. */
{ PR_1_EA_BLOCK_CSUM_INVALID,
N_("Extended attribute @a @b %b checksum for @i %i does not "
"match. "),
N_("@i %i @a @b %b checksum does not match block. "),
PROMPT_CLEAR, 0 },
/*
* Extended attribute block passes checks, but checksum for inode does
* not match.
* Inode extended attribute block passes checks, but checksum does not
* match block.
*/
{ PR_1_EA_BLOCK_ONLY_CSUM_INVALID,
N_("Extended attribute @a @b %b passes checks, but checksum for "
"@i %i does not match. "),
N_("@i %i @a @b %b passes checks, but checksum does not match @b. "),
PROMPT_FIX, 0 },
/*
@ -1048,6 +1046,11 @@ static struct e2fsck_problem problem_table[] = {
N_("@d @i %i has @x marked uninitialized at @b %c. "),
PROMPT_FIX, PR_PREEN_OK },
/* Inode logical block (physical block ) is misaligned. */
{ PR_1_MISALIGNED_CLUSTER,
N_("@i %i logical @b %b (physical @b %c) violates cluster allocation rules.\nWill fix in pass 1B.\n"),
PROMPT_NONE, 0 },
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
@ -1477,27 +1480,27 @@ static struct e2fsck_problem problem_table[] = {
/* htree root node fails checksum */
{ PR_2_HTREE_ROOT_CSUM_INVALID,
N_("@p @h %d: root node fails checksum\n"),
N_("@p @h %d: root node fails checksum.\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },
/* htree internal node fails checksum */
{ PR_2_HTREE_NODE_CSUM_INVALID,
N_("@p @h %d: internal node fails checksum\n"),
N_("@p @h %d: internal node fails checksum.\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },
/* leaf node fails checksum */
{ PR_2_LEAF_NODE_CSUM_INVALID,
N_("@d @i %i, %B, offset %N: @d fails checksum\n"),
N_("@d @i %i, %B, offset %N: @d fails checksum.\n"),
PROMPT_SALVAGE, PR_PREEN_OK },
/* leaf node has no checksum */
{ PR_2_LEAF_NODE_MISSING_CSUM,
N_("@d @i %i, %B, offset %N: @d has no checksum\n"),
N_("@d @i %i, %B, offset %N: @d has no checksum.\n"),
PROMPT_FIX, PR_PREEN_OK },
/* leaf node passes checks but fails checksum */
{ PR_2_LEAF_NODE_ONLY_CSUM_INVALID,
N_("@d @i %i, %B, offset %N: @d passes checks but fails checksum\n"),
N_("@d @i %i, %B, offset %N: @d passes checks but fails checksum.\n"),
PROMPT_FIX, PR_PREEN_OK },
/* Pass 3 errors */
@ -1823,12 +1826,12 @@ static struct e2fsck_problem problem_table[] = {
/* Group N inode bitmap does not match checksum */
{ PR_5_INODE_BITMAP_CSUM_INVALID,
N_("@g %g @i bitmap does not match checksum\n"),
N_("@g %g @i @B does not match checksum.\n"),
PROMPT_FIX, PR_LATCH_IBITMAP | PR_PREEN_OK },
/* Group N block bitmap does not match checksum */
{ PR_5_BLOCK_BITMAP_CSUM_INVALID,
N_("@g %g @b bitmap does not match checksum\n"),
N_("@g %g @b @B does not match checksum.\n"),
PROMPT_FIX, PR_LATCH_BBITMAP | PR_PREEN_OK },
/* Post-Pass 5 errors */

View File

@ -609,6 +609,9 @@ struct problem_context {
/* uninit directory block */
#define PR_1_UNINIT_DBLOCK 0x010073
/* Inode logical block is misaligned */
#define PR_1_MISALIGNED_CLUSTER 0x010074
/*
* Pass 1b errors
*/

View File

@ -771,7 +771,10 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
inode.i_flags &= ~EXT2_INDEX_FL;
else
inode.i_flags |= EXT2_INDEX_FL;
inode.i_size = outdir->num * fs->blocksize;
retval = ext2fs_inode_size_set(fs, &inode,
outdir->num * fs->blocksize);
if (retval)
return retval;
ext2fs_iblk_sub_blocks(fs, &inode, wd.cleared);
e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");

View File

@ -421,7 +421,7 @@ void check_resize_inode(e2fsck_t ctx)
for (j = 1; j < fs->group_desc_count; j++) {
if (!ext2fs_bg_has_super(fs, j))
continue;
expect = pblk + (j * fs->super->s_blocks_per_group);
expect = pblk + EXT2_GROUPS_TO_BLOCKS(fs->super, j);
if (ind_buf[ind_off] != expect)
goto resize_inode_invalid;
ind_off++;

View File

@ -70,6 +70,9 @@
/* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF
/* Define to 1 if you have the <attr/xattr.h> header file. */
#undef HAVE_ATTR_XATTR_H
/* Define to 1 if you have the `backtrace' function. */
#undef HAVE_BACKTRACE
@ -244,6 +247,9 @@
/* Define to 1 if you have the <linux/major.h> header file. */
#undef HAVE_LINUX_MAJOR_H
/* Define to 1 if you have the `llistxattr' function. */
#undef HAVE_LLISTXATTR
/* Define to 1 if you have the `llseek' function. */
#undef HAVE_LLSEEK

View File

@ -78,7 +78,7 @@ void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse)
ext2fs_group_desc_csum_set(fs, group);
ext2fs_free_blocks_count_add(fs->super,
-inuse * EXT2FS_CLUSTER_RATIO(fs));
-inuse * (blk64_t) EXT2FS_CLUSTER_RATIO(fs));
ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs);
if (fs->block_alloc_stats)
@ -139,7 +139,7 @@ void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
inuse*n/EXT2FS_CLUSTER_RATIO(fs));
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group);
ext2fs_free_blocks_count_add(fs->super, -inuse * n);
ext2fs_free_blocks_count_add(fs->super, -inuse * (blk64_t) n);
blk += n;
num -= n;
}

View File

@ -128,7 +128,10 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
if (!inode.i_ctime)
inode.i_ctime = fs->now ? fs->now : time(0);
ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
inode.i_size = rec.bad_block_count * fs->blocksize;
retval = ext2fs_inode_size_set(fs, &inode,
rec.bad_block_count * fs->blocksize);
if (retval)
goto cleanup;
retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
if (retval)

View File

@ -83,7 +83,7 @@ static void print_tree(struct rb_root *root)
static void check_tree(struct rb_root *root, const char *msg)
{
struct rb_node *new_node, *node, *next;
struct rb_node *node;
struct bmap_rb_extent *ext, *old = NULL;
for (node = ext2fs_rb_first(root); node;
@ -297,21 +297,19 @@ static errcode_t rb_resize_bmap(ext2fs_generic_bitmap bmap,
{
struct ext2fs_rb_private *bp;
if (new_real_end >= bmap->real_end) {
bmap->end = new_end;
bmap->real_end = new_real_end;
return 0;
}
bp = (struct ext2fs_rb_private *) bmap->private;
bp->rcursor = NULL;
bp->wcursor = NULL;
/* truncate tree to new_real_end size */
rb_truncate(new_real_end, &bp->root);
rb_truncate(((new_end < bmap->end) ? new_end : bmap->end) - bmap->start,
&bp->root);
bmap->end = new_end;
bmap->real_end = new_real_end;
if (bmap->end < bmap->real_end)
rb_insert_extent(bmap->end + 1 - bmap->start,
bmap->real_end - bmap->end, bp);
return 0;
}

View File

@ -29,7 +29,7 @@ dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t blk)
blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group)
{
return fs->super->s_first_data_block +
((blk64_t)group * fs->super->s_blocks_per_group);
EXT2_GROUPS_TO_BLOCKS(fs->super, group);
}
/*
@ -523,3 +523,31 @@ void ext2fs_file_acl_block_set(ext2_filsys fs, struct ext2_inode *inode,
inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32;
}
/*
* Set the size of the inode
*/
errcode_t ext2fs_inode_size_set(ext2_filsys fs, struct ext2_inode *inode,
ext2_off64_t size)
{
/* Only regular files get to be larger than 4GB */
if (!LINUX_S_ISREG(inode->i_mode) && (size >> 32))
return EXT2_ET_FILE_TOO_BIG;
/* If we're writing a large file, set the large_file flag */
if (LINUX_S_ISREG(inode->i_mode) &&
ext2fs_needs_large_file_feature(size) &&
(!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
fs->super->s_feature_ro_compat |=
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
ext2fs_update_dynamic_rev(fs);
ext2fs_mark_super_dirty(fs);
}
inode->i_size = size & 0xffffffff;
inode->i_size_high = (size >> 32);
return 0;
}

View File

@ -62,15 +62,16 @@ static errcode_t dos_write_blk(io_channel channel, unsigned long block,
static errcode_t dos_flush(io_channel channel);
static struct struct_io_manager struct_dos_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
"DOS I/O Manager",
dos_open,
dos_close,
dos_set_blksize,
dos_read_blk,
dos_write_blk,
dos_flush
.magic = EXT2_ET_MAGIC_IO_MANAGER,
.name = "DOS I/O Manager",
.open = dos_open,
.close = dos_close,
.set_blksize = dos_set_blksize,
.read_blk = dos_read_blk,
.write_blk = dos_write_blk,
.flush = dos_flush
};
io_manager dos_io_manager = &struct_dos_manager;
/*

View File

@ -278,6 +278,11 @@ struct ext2_dx_tail {
#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
#endif
#define EXT2_GROUPS_TO_BLOCKS(s, g) ((blk64_t) EXT2_BLOCKS_PER_GROUP(s) * \
(g))
#define EXT2_GROUPS_TO_CLUSTERS(s, g) ((blk64_t) EXT2_CLUSTERS_PER_GROUP(s) * \
(g))
/*
* Constants relative to the data blocks
*/

View File

@ -39,6 +39,8 @@ extern "C" {
#define SUPERBLOCK_OFFSET 1024
#define SUPERBLOCK_SIZE 1024
#define UUID_STR_SIZE 37
/*
* The last ext2fs revision level that this version of the library is
* able to support.
@ -894,6 +896,8 @@ extern blk64_t ext2fs_file_acl_block(ext2_filsys fs,
const struct ext2_inode *inode);
extern void ext2fs_file_acl_block_set(ext2_filsys fs,
struct ext2_inode *inode, blk64_t blk);
extern errcode_t ext2fs_inode_size_set(ext2_filsys fs, struct ext2_inode *inode,
ext2_off64_t size);
/* block.c */
extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
@ -1499,6 +1503,7 @@ extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks,
extern errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
blk64_t goal, int flags);
extern int ext2fs_default_journal_size(__u64 num_blocks);
extern int ext2fs_journal_sb_start(int blocksize);
/* openfs.c */
extern errcode_t ext2fs_open(const char *name, int flags, int superblock,

View File

@ -568,20 +568,10 @@ errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
old_truncate = ((old_size + file->fs->blocksize - 1) >>
EXT2_BLOCK_SIZE_BITS(file->fs->super));
/* If we're writing a large file, set the large_file flag */
if (LINUX_S_ISREG(file->inode.i_mode) &&
ext2fs_needs_large_file_feature(EXT2_I_SIZE(&file->inode)) &&
(!EXT2_HAS_RO_COMPAT_FEATURE(file->fs->super,
EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
file->fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
file->fs->super->s_feature_ro_compat |=
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
ext2fs_update_dynamic_rev(file->fs);
ext2fs_mark_super_dirty(file->fs);
}
retval = ext2fs_inode_size_set(file->fs, &file->inode, size);
if (retval)
return retval;
file->inode.i_size = size & 0xffffffff;
file->inode.i_size_high = (size >> 32);
if (file->ino) {
retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
if (retval)

View File

@ -286,8 +286,8 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
ext2fs_generic_bitmap bmap;
errcode_t retval;
ssize_t actual;
__u32 itr, cnt, size;
int c, total_size;
size_t c;
__u64 itr, cnt, size, total_size;
char buf[1024];
if (flags & IMAGER_FLAG_INODEMAP) {
@ -308,7 +308,7 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
}
bmap = fs->block_map;
itr = fs->super->s_first_data_block;
cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count;
cnt = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count);
size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
}
total_size = size * fs->group_desc_count;
@ -342,9 +342,9 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
if (c > (int) sizeof(buf))
c = sizeof(buf);
actual = write(fd, buf, c);
if (actual == -1)
if (actual < 0)
return errno;
if (actual != c)
if ((size_t) actual != c)
return EXT2_ET_SHORT_WRITE;
size -= c;
}
@ -360,7 +360,7 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
{
ext2fs_generic_bitmap bmap;
errcode_t retval;
__u32 itr, cnt;
__u64 itr, cnt;
char buf[1024];
unsigned int size;
ssize_t actual;
@ -383,7 +383,7 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
}
bmap = fs->block_map;
itr = fs->super->s_first_data_block;
cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count;
cnt = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count);
size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
}

View File

@ -63,19 +63,17 @@ static errcode_t inode_write_blk64(io_channel channel,
unsigned long long block, int count, const void *data);
static struct struct_io_manager struct_inode_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
"Inode I/O Manager",
inode_open,
inode_close,
inode_set_blksize,
inode_read_blk,
inode_write_blk,
inode_flush,
inode_write_byte,
NULL,
NULL,
inode_read_blk64,
inode_write_blk64
.magic = EXT2_ET_MAGIC_IO_MANAGER,
.name = "Inode I/O Manager",
.open = inode_open,
.close = inode_close,
.set_blksize = inode_set_blksize,
.read_blk = inode_read_blk,
.write_blk = inode_write_blk,
.flush = inode_flush,
.write_byte = inode_write_byte,
.read_blk64 = inode_read_blk64,
.write_blk64 = inode_write_blk64
};
io_manager inode_io_manager = &struct_inode_manager;

View File

@ -186,6 +186,9 @@ struct journal_revoke_tail {
#define JFS_FLAG_LAST_TAG 8 /* last tag in this descriptor block */
#define UUID_SIZE 16
#define JFS_USERS_MAX 48
#define JFS_USERS_SIZE (UUID_SIZE * JFS_USERS_MAX)
/*
* The journal superblock. All fields are in big-endian byte order.
*/
@ -233,7 +236,8 @@ typedef struct journal_superblock_s
__u32 s_checksum; /* crc32c(superblock) */
/* 0x0100 */
__u8 s_users[16*48]; /* ids of all fs'es sharing the log */
__u8 s_users[JFS_USERS_SIZE]; /* ids of all fs'es sharing the log */
/* 0x0400 */
} journal_superblock_t;

View File

@ -49,7 +49,7 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
errcode_t retval;
journal_superblock_t *jsb;
if (num_blocks < 1024)
if (num_blocks < JFS_MIN_JOURNAL_BLOCKS)
return EXT2_ET_JOURNAL_TOO_SMALL;
if ((retval = ext2fs_get_mem(fs->blocksize, &jsb)))
@ -75,10 +75,7 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
if (fs->super->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
jsb->s_nr_users = 0;
if (fs->blocksize == 1024)
jsb->s_first = htonl(3);
else
jsb->s_first = htonl(2);
jsb->s_first = htonl(ext2fs_journal_sb_start(fs->blocksize) + 1);
}
*ret_jsb = (char *) jsb;
@ -383,15 +380,13 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
goto errout;
inode_size = (unsigned long long)fs->blocksize * num_blocks;
inode.i_size = inode_size & 0xFFFFFFFF;
inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
if (ext2fs_needs_large_file_feature(inode_size))
fs->super->s_feature_ro_compat |=
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
inode.i_links_count = 1;
inode.i_mode = LINUX_S_IFREG | 0600;
retval = ext2fs_inode_size_set(fs, &inode, inode_size);
if (retval)
goto errout;
if ((retval = ext2fs_write_new_inode(fs, journal_ino, &inode)))
goto errout;
@ -430,6 +425,13 @@ int ext2fs_default_journal_size(__u64 num_blocks)
return 32768;
}
int ext2fs_journal_sb_start(int blocksize)
{
if (blocksize == EXT2_MIN_BLOCK_SIZE)
return 2;
return 1;
}
/*
* This function adds a journal device to a filesystem
*/
@ -437,7 +439,7 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
{
struct stat st;
errcode_t retval;
char buf[1024];
char buf[SUPERBLOCK_SIZE];
journal_superblock_t *jsb;
int start;
__u32 i, nr_users;
@ -450,10 +452,9 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
return EXT2_ET_JOURNAL_NOT_BLOCK; /* Must be a block device */
/* Get the journal superblock */
start = 1;
if (journal_dev->blocksize == 1024)
start++;
if ((retval = io_channel_read_blk64(journal_dev->io, start, -1024,
start = ext2fs_journal_sb_start(journal_dev->blocksize);
if ((retval = io_channel_read_blk64(journal_dev->io, start,
-SUPERBLOCK_SIZE,
buf)))
return retval;
@ -479,7 +480,8 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
}
/* Writeback the journal superblock */
if ((retval = io_channel_write_blk64(journal_dev->io, start, -1024, buf)))
if ((retval = io_channel_write_blk64(journal_dev->io, start,
-SUPERBLOCK_SIZE, buf)))
return retval;
fs->super->s_journal_inum = 0;
@ -632,7 +634,7 @@ main(int argc, char **argv)
exit(1);
}
retval = ext2fs_add_journal_inode(fs, 1024, 0);
retval = ext2fs_add_journal_inode(fs, JFS_MIN_JOURNAL_BLOCKS, 0);
if (retval) {
com_err(argv[0], retval, "while adding journal to %s",
device_name);

View File

@ -230,18 +230,16 @@ static errcode_t nt_write_blk(io_channel channel, unsigned long block,
static errcode_t nt_flush(io_channel channel);
static struct struct_io_manager struct_nt_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
"NT I/O Manager",
nt_open,
nt_close,
nt_set_blksize,
nt_read_blk,
nt_write_blk,
nt_flush
.magic = EXT2_ET_MAGIC_IO_MANAGER,
.name = "NT I/O Manager",
.open = nt_open,
.close = nt_close,
.set_blksize = nt_set_blksize,
.read_blk = nt_read_blk,
.write_blk = nt_write_blk,
.flush = nt_flush
};
//
// function to get API
//

View File

@ -133,12 +133,9 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
dindir_dirty = inode_dirty = 1;
inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
inode_size *= fs->blocksize;
inode.i_size = inode_size & 0xFFFFFFFF;
inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
if(inode.i_size_high) {
sb->s_feature_ro_compat |=
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
}
retval = ext2fs_inode_size_set(fs, &inode, inode_size);
if (retval)
goto out_free;
inode.i_ctime = fs->now ? fs->now : time(0);
}

View File

@ -271,8 +271,8 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
}
blk = (fs->image_header->offset_blockmap /
fs->blocksize);
blk_cnt = (blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) *
fs->group_desc_count;
blk_cnt = EXT2_GROUPS_TO_CLUSTERS(fs->super,
fs->group_desc_count);
while (block_nbytes > 0) {
retval = io_channel_read_blk64(fs->image_io, blk++,
1, block_bitmap);

View File

@ -79,7 +79,7 @@ errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
inode.i_uid = inode.i_gid = 0;
ext2fs_iblk_set(fs, &inode, fastlink ? 0 : 1);
inode.i_links_count = 1;
inode.i_size = target_len;
ext2fs_inode_size_set(fs, &inode, target_len);
/* The time fields are set by ext2fs_write_new_inode() */
if (fastlink) {

View File

@ -487,20 +487,20 @@ static errcode_t test_discard(io_channel channel, unsigned long long block,
}
static struct struct_io_manager struct_test_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
"Test I/O Manager",
test_open,
test_close,
test_set_blksize,
test_read_blk,
test_write_blk,
test_flush,
test_write_byte,
test_set_option,
test_get_stats,
test_read_blk64,
test_write_blk64,
test_discard,
.magic = EXT2_ET_MAGIC_IO_MANAGER,
.name = "Test I/O Manager",
.open = test_open,
.close = test_close,
.set_blksize = test_set_blksize,
.read_blk = test_read_blk,
.write_blk = test_write_blk,
.flush = test_flush,
.write_byte = test_write_byte,
.set_option = test_set_option,
.get_stats = test_get_stats,
.read_blk64 = test_read_blk64,
.write_blk64 = test_write_blk64,
.discard = test_discard,
};
io_manager test_io_manager = &struct_test_manager;

View File

@ -588,19 +588,19 @@ static errcode_t undo_get_stats(io_channel channel, io_stats *stats)
}
static struct struct_io_manager struct_undo_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
"Undo I/O Manager",
undo_open,
undo_close,
undo_set_blksize,
undo_read_blk,
undo_write_blk,
undo_flush,
undo_write_byte,
undo_set_option,
undo_get_stats,
undo_read_blk64,
undo_write_blk64,
.magic = EXT2_ET_MAGIC_IO_MANAGER,
.name = "Undo I/O Manager",
.open = undo_open,
.close = undo_close,
.set_blksize = undo_set_blksize,
.read_blk = undo_read_blk,
.write_blk = undo_write_blk,
.flush = undo_flush,
.write_byte = undo_write_byte,
.set_option = undo_set_option,
.get_stats = undo_get_stats,
.read_blk64 = undo_read_blk64,
.write_blk64 = undo_write_blk64,
};
io_manager undo_io_manager = &struct_undo_manager;

View File

@ -923,20 +923,20 @@ unimplemented:
}
static struct struct_io_manager struct_unix_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
"Unix I/O Manager",
unix_open,
unix_close,
unix_set_blksize,
unix_read_blk,
unix_write_blk,
unix_flush,
unix_write_byte,
unix_set_option,
unix_get_stats,
unix_read_blk64,
unix_write_blk64,
unix_discard,
.magic = EXT2_ET_MAGIC_IO_MANAGER,
.name = "Unix I/O Manager",
.open = unix_open,
.close = unix_close,
.set_blksize = unix_set_blksize,
.read_blk = unix_read_blk,
.write_blk = unix_write_blk,
.flush = unix_flush,
.write_byte = unix_write_byte,
.set_option = unix_set_option,
.get_stats = unix_get_stats,
.read_blk64 = unix_read_blk64,
.write_blk64 = unix_write_blk64,
.discard = unix_discard,
};
io_manager unix_io_manager = &struct_unix_manager;

View File

@ -580,7 +580,6 @@ out:
errcode_t quota_compare_and_update(quota_ctx_t qctx, int qtype,
int *usage_inconsistent)
{
ext2_filsys fs = qctx->fs;
struct quota_handle qh;
struct scan_dquots_data scan_data;
struct dquot *dq;

View File

@ -12,6 +12,9 @@
#include <time.h>
#include <unistd.h>
#include <limits.h> /* for PATH_MAX */
#ifdef HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
#include "create_inode.h"
@ -103,6 +106,94 @@ static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t cwd,
return retval;
}
static errcode_t set_inode_xattr(ext2_filsys fs, ext2_ino_t ino, const char *filename)
{
#ifdef HAVE_LLISTXATTR
errcode_t retval, close_retval;
struct ext2_inode inode;
struct ext2_xattr_handle *handle;
ssize_t size, value_size;
char *list;
int i;
size = llistxattr(filename, NULL, 0);
if (size == -1) {
com_err(__func__, errno, "llistxattr failed on %s", filename);
return errno;
} else if (size == 0) {
return 0;
}
retval = ext2fs_xattrs_open(fs, ino, &handle);
if (retval) {
if (retval == EXT2_ET_MISSING_EA_FEATURE)
return 0;
com_err(__func__, retval, "while opening inode %u", ino);
return retval;
}
retval = ext2fs_get_mem(size, &list);
if (retval) {
com_err(__func__, retval, "whilst allocating memory");
goto out;
}
size = llistxattr(filename, list, size);
if (size == -1) {
com_err(__func__, errno, "llistxattr failed on %s", filename);
retval = errno;
goto out;
}
for (i = 0; i < size; i += strlen(&list[i]) + 1) {
const char *name = &list[i];
char *value;
value_size = getxattr(filename, name, NULL, 0);
if (value_size == -1) {
com_err(__func__, errno, "getxattr failed on %s",
filename);
retval = errno;
break;
}
retval = ext2fs_get_mem(value_size, &value);
if (retval) {
com_err(__func__, retval, "whilst allocating memory");
break;
}
value_size = getxattr(filename, name, value, value_size);
if (value_size == -1) {
ext2fs_free_mem(&value);
com_err(__func__, errno, "getxattr failed on %s",
filename);
retval = errno;
break;
}
retval = ext2fs_xattr_set(handle, name, value, value_size);
ext2fs_free_mem(&value);
if (retval) {
com_err(__func__, retval,
"while writing xattr %u", ino);
break;
}
}
out:
ext2fs_free_mem(&list);
close_retval = ext2fs_xattrs_close(&handle);
if (close_retval) {
com_err(__func__, retval, "while closing inode %u", ino);
retval = retval ? retval : close_retval;
}
return retval;
#else /* HAVE_LLISTXATTR */
return 0;
#endif /* HAVE_LLISTXATTR */
}
/* Make a special files (block and character devices), fifo's, and sockets */
errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
struct stat *st)
@ -418,7 +509,12 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
inode.i_atime = inode.i_ctime = inode.i_mtime =
fs->now ? fs->now : time(0);
inode.i_links_count = 1;
inode.i_size = statbuf.st_size;
retval = ext2fs_inode_size_set(fs, &inode, statbuf.st_size);
if (retval) {
com_err(dest, retval, 0);
close(fd);
return retval;
}
if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
EXT4_FEATURE_INCOMPAT_INLINE_DATA)) {
inode.i_flags |= EXT4_INLINE_DATA_FL;
@ -615,6 +711,13 @@ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
goto out;
}
retval = set_inode_xattr(fs, ino, name);
if (retval) {
com_err(__func__, retval,
_("while setting xattrs for \"%s\""), name);
goto out;
}
/* Save the hardlink ino */
if (save_inode) {
/*

View File

@ -331,9 +331,10 @@ static int filefrag_fibmap(int fd, int blk_shift, int *num_extents,
fm_ext.fe_physical = block * st->st_blksize;
fm_ext.fe_length = 0;
(*num_extents)++;
} else if (verbose && last_block && (block != last_block + 1)) {
printf("Discontinuity: Block %ld is at %lu (was %lu)\n",
i, block, last_block + 1);
} else if (last_block && (block != last_block + 1)) {
if (verbose)
printf("Discontinuity: Block %ld is at %lu (was "
"%lu)\n", i, block, last_block + 1);
(*num_extents)++;
}
fm_ext.fe_length += st->st_blksize;
@ -350,6 +351,7 @@ static int filefrag_fibmap(int fd, int blk_shift, int *num_extents,
static int frag_report(const char *filename)
{
static struct statfs fsinfo;
static unsigned int blksize;
ext2fs_struct_stat st;
int blk_shift;
long fd;
@ -380,22 +382,22 @@ static int frag_report(const char *filename)
#endif
rc = -errno;
perror("stat");
close(fd);
return rc;
goto out_close;
}
if (last_device != st.st_dev) {
if (fstatfs(fd, &fsinfo) < 0) {
rc = -errno;
perror("fstatfs");
close(fd);
return rc;
goto out_close;
}
if (ioctl(fd, FIGETBSZ, &blksize) < 0)
blksize = fsinfo.f_bsize;
if (verbose)
printf("Filesystem type is: %lx\n",
(unsigned long)fsinfo.f_type);
}
st.st_blksize = fsinfo.f_bsize;
st.st_blksize = blksize;
if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
flags = 0;
if (!(flags & EXT4_EXTENTS_FL) &&
@ -404,13 +406,13 @@ static int frag_report(const char *filename)
is_ext2++;
if (is_ext2) {
long cylgroups = div_ceil(fsinfo.f_blocks, fsinfo.f_bsize * 8);
long cylgroups = div_ceil(fsinfo.f_blocks, blksize * 8);
if (verbose && last_device != st.st_dev)
printf("Filesystem cylinder groups approximately %ld\n",
cylgroups);
data_blocks_per_cyl = fsinfo.f_bsize * 8 -
data_blocks_per_cyl = blksize * 8 -
(fsinfo.f_files / 8 / cylgroups) - 3;
}
last_device = st.st_dev;
@ -419,11 +421,11 @@ static int frag_report(const char *filename)
if (width > physical_width)
physical_width = width;
numblocks = (st.st_size + fsinfo.f_bsize - 1) / fsinfo.f_bsize;
numblocks = (st.st_size + blksize - 1) / blksize;
if (blocksize != 0)
blk_shift = int_log2(blocksize);
else
blk_shift = int_log2(fsinfo.f_bsize);
blk_shift = int_log2(blksize);
width = int_log10(numblocks);
if (width > logical_width)
@ -431,7 +433,7 @@ static int frag_report(const char *filename)
if (verbose)
printf("File size of %s is %llu (%llu block%s of %d bytes)\n",
filename, (unsigned long long)st.st_size,
numblocks * fsinfo.f_bsize >> blk_shift,
numblocks * blksize >> blk_shift,
numblocks == 1 ? "" : "s", 1 << blk_shift);
if (!force_bmap) {
@ -439,7 +441,7 @@ static int frag_report(const char *filename)
expected = 0;
}
if (rc < 0) {
if (force_bmap || rc < 0) {
expected = filefrag_fibmap(fd, blk_shift, &num_extents,
&st, numblocks, is_ext2);
if (expected < 0) {

View File

@ -357,8 +357,9 @@ static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
if (retval)
goto errout;
size = (__u64) count * fs->blocksize;
inode.i_size = size & 0xffffffff;
inode.i_size_high = (size >> 32);
retval = ext2fs_inode_size_set(fs, &inode, size);
if (retval)
goto errout;
retval = ext2fs_write_new_inode(fs, *ino, &inode);
if (retval)
@ -468,7 +469,7 @@ errcode_t mk_hugefiles(ext2_filsys fs, const char *device_name)
unsigned long i;
ext2_ino_t dir;
errcode_t retval;
blk64_t fs_blocks, part_offset;
blk64_t fs_blocks, part_offset = 0;
unsigned long align;
int d, dsize;
char *t;

View File

@ -180,6 +180,50 @@ static __u32 clear_ok_features[3] = {
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
};
/**
* Try to get journal super block if any
*/
static int get_journal_sb(ext2_filsys jfs, char buf[SUPERBLOCK_SIZE])
{
int retval;
int start;
journal_superblock_t *jsb;
if (!(jfs->super->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
return EXT2_ET_UNSUPP_FEATURE;
}
/* Get the journal superblock */
if ((retval = io_channel_read_blk64(jfs->io,
ext2fs_journal_sb_start(jfs->blocksize), -SUPERBLOCK_SIZE, buf))) {
com_err(program_name, retval, "%s",
_("while reading journal superblock"));
return retval;
}
jsb = (journal_superblock_t *) buf;
if ((jsb->s_header.h_magic != (unsigned)ntohl(JFS_MAGIC_NUMBER)) ||
(jsb->s_header.h_blocktype != (unsigned)ntohl(JFS_SUPERBLOCK_V2))) {
fputs(_("Journal superblock not found!\n"), stderr);
return EXT2_ET_BAD_MAGIC;
}
return 0;
}
static void *
journal_user(char uuid[UUID_SIZE], char s_users[JFS_USERS_SIZE], int nr_users)
{
int i;
for (i = 0; i < nr_users; i++) {
if (memcmp(uuid, &s_users[i * UUID_SIZE], UUID_SIZE) == 0)
return &s_users[i * UUID_SIZE];
}
return NULL;
}
/*
* Remove an external journal from the filesystem
*/
@ -187,12 +231,13 @@ static int remove_journal_device(ext2_filsys fs)
{
char *journal_path;
ext2_filsys jfs;
char buf[1024];
char buf[SUPERBLOCK_SIZE];
journal_superblock_t *jsb;
int i, nr_users;
errcode_t retval;
int commit_remove_journal = 0;
io_manager io_ptr;
int start;
if (f_flag)
commit_remove_journal = 1; /* force removal even if error */
@ -222,34 +267,19 @@ static int remove_journal_device(ext2_filsys fs)
_("while trying to open external journal"));
goto no_valid_journal;
}
if (!(jfs->super->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
fprintf(stderr, _("%s is not a journal device.\n"),
journal_path);
goto no_valid_journal;
}
/* Get the journal superblock */
if ((retval = io_channel_read_blk64(jfs->io, 1, -1024, buf))) {
com_err(program_name, retval, "%s",
_("while reading journal superblock"));
if ((retval = get_journal_sb(jfs, buf))) {
if (retval == EXT2_ET_UNSUPP_FEATURE)
fprintf(stderr, _("%s is not a journal device.\n"),
journal_path);
goto no_valid_journal;
}
jsb = (journal_superblock_t *) buf;
if ((jsb->s_header.h_magic != (unsigned)ntohl(JFS_MAGIC_NUMBER)) ||
(jsb->s_header.h_blocktype != (unsigned)ntohl(JFS_SUPERBLOCK_V2))) {
fputs(_("Journal superblock not found!\n"), stderr);
goto no_valid_journal;
}
/* Find the filesystem UUID */
nr_users = ntohl(jsb->s_nr_users);
for (i = 0; i < nr_users; i++) {
if (memcmp(fs->super->s_uuid, &jsb->s_users[i * 16], 16) == 0)
break;
}
if (i >= nr_users) {
if (!journal_user(fs->super->s_uuid, jsb->s_users, nr_users)) {
fputs(_("Filesystem's UUID not found on journal device.\n"),
stderr);
commit_remove_journal = 1;
@ -261,7 +291,8 @@ static int remove_journal_device(ext2_filsys fs)
jsb->s_nr_users = htonl(nr_users);
/* Write back the journal superblock */
if ((retval = io_channel_write_blk64(jfs->io, 1, -1024, buf))) {
if ((retval = io_channel_write_blk64(jfs->io, start,
-SUPERBLOCK_SIZE, buf))) {
com_err(program_name, retval,
"while writing journal superblock.");
goto no_valid_journal;
@ -1894,7 +1925,7 @@ static int ext2fs_is_block_in_group(ext2_filsys fs, dgrp_t group, blk64_t blk)
{
blk64_t start_blk, end_blk;
start_blk = fs->super->s_first_data_block +
EXT2_BLOCKS_PER_GROUP(fs->super) * group;
EXT2_GROUPS_TO_BLOCKS(fs->super, group);
/*
* We cannot get new block beyond end_blk for for the last block group
* so we can check with EXT2_BLOCKS_PER_GROUP even for last block group
@ -2404,6 +2435,68 @@ static int tune2fs_setup_tdb(const char *name, io_manager *io_ptr)
return retval;
}
int
fs_update_journal_user(struct ext2_super_block *sb, char old_uuid[UUID_SIZE])
{
int retval, nr_users, start;
journal_superblock_t *jsb;
ext2_filsys jfs;
char *j_uuid, *journal_path;
char uuid[UUID_STR_SIZE];
char buf[SUPERBLOCK_SIZE];
if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) ||
uuid_is_null(sb->s_journal_uuid))
return 0;
uuid_unparse(sb->s_journal_uuid, uuid);
journal_path = blkid_get_devname(NULL, "UUID", uuid);
if (!journal_path)
return 0;
retval = ext2fs_open2(journal_path, io_options,
EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_RW,
0, 0, unix_io_manager, &jfs);
if (retval) {
com_err(program_name, retval,
_("while trying to open %s"),
journal_path);
return retval;
}
if ((retval = get_journal_sb(jfs, buf))) {
if (retval == EXT2_ET_UNSUPP_FEATURE)
fprintf(stderr, _("%s is not a journal device.\n"),
journal_path);
return retval;
}
jsb = (journal_superblock_t *) buf;
/* Find the filesystem UUID */
nr_users = ntohl(jsb->s_nr_users);
if (!(j_uuid = journal_user(old_uuid, jsb->s_users, nr_users))) {
fputs(_("Filesystem's UUID not found on journal device.\n"),
stderr);
return EXT2_ET_LOAD_EXT_JOURNAL;
}
memcpy(j_uuid, sb->s_uuid, UUID_SIZE);
start = ext2fs_journal_sb_start(jfs->blocksize);
/* Write back the journal superblock */
if ((retval = io_channel_write_blk64(jfs->io, start,
-SUPERBLOCK_SIZE, buf))) {
com_err(program_name, retval,
"while writing journal superblock.");
return retval;
}
ext2fs_close(jfs);
return 0;
}
int main(int argc, char **argv)
{
errcode_t retval;
@ -2691,6 +2784,8 @@ retry_open:
if (U_flag) {
int set_csum = 0;
dgrp_t i;
char buf[SUPERBLOCK_SIZE];
char old_uuid[UUID_SIZE];
if (ext2fs_has_group_desc_csum(fs)) {
/*
@ -2717,6 +2812,8 @@ retry_open:
if (i >= fs->group_desc_count)
set_csum = 1;
}
memcpy(old_uuid, sb->s_uuid, UUID_SIZE);
if ((strcasecmp(new_UUID, "null") == 0) ||
(strcasecmp(new_UUID, "clear") == 0)) {
uuid_clear(sb->s_uuid);
@ -2736,6 +2833,29 @@ retry_open:
ext2fs_group_desc_csum_set(fs, i);
fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
}
/* If this is a journal dev, we need to copy UUID into jsb */
if (!(rc = get_journal_sb(fs, buf))) {
journal_superblock_t *jsb;
jsb = (journal_superblock_t *) buf;
fputs(_("Need to update journal superblock.\n"), stdout);
memcpy(jsb->s_uuid, sb->s_uuid, sizeof(sb->s_uuid));
/* Writeback the journal superblock */
if ((rc = io_channel_write_blk64(fs->io,
ext2fs_journal_sb_start(fs->blocksize),
-SUPERBLOCK_SIZE, buf)))
goto closefs;
} else if (rc != EXT2_ET_UNSUPP_FEATURE)
goto closefs;
else {
rc = 0; /** Reset rc to avoid ext2fs_mmp_stop() */
if ((rc = fs_update_journal_user(sb, old_uuid)))
goto closefs;
}
ext2fs_mark_super_dirty(fs);
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))

View File

@ -36,6 +36,7 @@ extern int optind;
#include "uuid/uuid.h"
#include "uuid/uuidd.h"
#include "nls-enable.h"
#include "ext2fs/ext2fs.h"
#ifdef __GNUC__
#define CODE_ATTR(x) __attribute__(x)
@ -236,7 +237,7 @@ static void server_loop(const char *socket_path, const char *pidfile_path,
uuid_t uu;
mode_t save_umask;
char reply_buf[1024], *cp;
char op, str[37];
char op, str[UUID_STR_SIZE];
int i, s, ns, len, num;
int fd_pidfile, ret;

View File

@ -318,6 +318,7 @@ int main (int argc, char ** argv)
printf("%s", _("Couldn't find valid filesystem superblock.\n"));
exit (1);
}
fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
if (!(mount_flags & EXT2_MF_MOUNTED)) {
if (!force && ((fs->super->s_lastcheck < fs->super->s_mtime) ||

View File

@ -435,8 +435,7 @@ retry:
fs->inode_map);
if (retval) goto errout;
real_end = (((blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super) *
fs->group_desc_count)) - 1 +
real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 +
fs->super->s_first_data_block;
retval = ext2fs_resize_block_bitmap2(new_size - 1,
real_end, fs->block_map);
@ -2394,7 +2393,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
fs->super->s_free_inodes_count;
blks_needed = ext2fs_div_ceil(inode_count,
fs->super->s_inodes_per_group) *
EXT2_BLOCKS_PER_GROUP(fs->super);
(blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super);
groups = ext2fs_div64_ceil(blks_needed,
EXT2_BLOCKS_PER_GROUP(fs->super));
#ifdef RESIZE2FS_DEBUG
@ -2441,7 +2440,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
* figure out how many data blocks we have given the number of groups
* we need for our inodes
*/
data_blocks = groups * EXT2_BLOCKS_PER_GROUP(fs->super);
data_blocks = EXT2_GROUPS_TO_BLOCKS(fs->super, groups);
last_start = 0;
for (grp = 0; grp < flex_groups; grp++) {
overhead = calc_group_overhead(fs, grp, old_desc_blocks);
@ -2479,7 +2478,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
extra_grps = ext2fs_div64_ceil(remainder,
EXT2_BLOCKS_PER_GROUP(fs->super));
data_blocks += extra_grps * EXT2_BLOCKS_PER_GROUP(fs->super);
data_blocks += EXT2_GROUPS_TO_BLOCKS(fs->super, extra_grps);
/* ok we have to account for the last group */
overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
@ -2577,7 +2576,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
* blocks needed to handle the group descriptor metadata+data
* that we need
*/
blks_needed = (groups-1) * EXT2_BLOCKS_PER_GROUP(fs->super);
blks_needed = EXT2_GROUPS_TO_BLOCKS(fs->super, groups - 1);
blks_needed += overhead;
/*

198
tests/f_badcluster/expect Normal file
View File

@ -0,0 +1,198 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12 logical block 2 (physical block 1154) violates cluster allocation rules.
Will fix in pass 1B.
Inode 12, i_blocks is 32, should be 64. Fix? yes
Inode 16 logical block 5 (physical block 1173) violates cluster allocation rules.
Will fix in pass 1B.
Inode 16, i_size is 3072, should be 6144. Fix? yes
Inode 16, i_blocks is 32, should be 64. Fix? yes
Inode 17 logical block 0 (physical block 1186) violates cluster allocation rules.
Will fix in pass 1B.
Inode 17 logical block 2 (physical block 1184) violates cluster allocation rules.
Will fix in pass 1B.
Inode 17, i_blocks is 32, should be 64. Fix? yes
Inode 18 logical block 3 (physical block 1201) violates cluster allocation rules.
Will fix in pass 1B.
Inode 18, i_blocks is 32, should be 64. Fix? yes
Running additional passes to resolve blocks claimed by more than one inode...
Pass 1B: Rescanning for multiply-claimed blocks
Multiply-claimed block(s) in inode 12: 1154
Multiply-claimed block(s) in inode 13: 1152--1154
Multiply-claimed block(s) in inode 14: 1648--1650
Multiply-claimed block(s) in inode 15: 1650
Multiply-claimed block(s) in inode 16: 1173
Multiply-claimed block(s) in inode 17: 1186 1185 1184
Multiply-claimed block(s) in inode 18: 1201
Pass 1C: Scanning directories for inodes with multiply-claimed blocks
Pass 1D: Reconciling multiply-claimed blocks
(There are 7 inodes containing multiply-claimed blocks.)
File /a (inode #12, mod time Tue Jun 17 08:00:50 2014)
has 1 multiply-claimed block(s), shared with 1 file(s):
/b (inode #13, mod time Tue Jun 17 08:00:50 2014)
Clone multiply-claimed blocks? yes
File /b (inode #13, mod time Tue Jun 17 08:00:50 2014)
has 1 multiply-claimed block(s), shared with 1 file(s):
/a (inode #12, mod time Tue Jun 17 08:00:50 2014)
Multiply-claimed blocks already reassigned or cloned.
File /c (inode #14, mod time Tue Jun 17 08:00:50 2014)
has 1 multiply-claimed block(s), shared with 1 file(s):
/d (inode #15, mod time Tue Jun 17 08:00:50 2014)
Clone multiply-claimed blocks? yes
File /d (inode #15, mod time Tue Jun 17 08:00:50 2014)
has 1 multiply-claimed block(s), shared with 1 file(s):
/c (inode #14, mod time Tue Jun 17 08:00:50 2014)
Multiply-claimed blocks already reassigned or cloned.
File /e (inode #16, mod time Tue Jun 17 08:00:50 2014)
has 1 multiply-claimed block(s), shared with 0 file(s):
Clone multiply-claimed blocks? yes
File /f (inode #17, mod time Tue Jun 17 08:00:50 2014)
has 1 multiply-claimed block(s), shared with 0 file(s):
Clone multiply-claimed blocks? yes
File /g (inode #18, mod time Tue Jun 17 08:00:50 2014)
has 1 multiply-claimed block(s), shared with 0 file(s):
Clone multiply-claimed blocks? yes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong for group #0 (50, counted=47).
Fix? yes
Free blocks count wrong (800, counted=752).
Fix? yes
test_fs: ***** FILE SYSTEM WAS MODIFIED *****
test_fs: 18/128 files (22.2% non-contiguous), 1296/2048 blocks
Pass 1: Checking inodes, blocks, and sizes
Inode 12, i_blocks is 64, should be 32. Fix? yes
Inode 16, i_blocks is 64, should be 32. Fix? yes
Inode 17, i_blocks is 64, should be 32. Fix? yes
Inode 18, i_blocks is 64, should be 32. Fix? yes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Block bitmap differences: -(1168--1200)
Fix? yes
Free blocks count wrong for group #0 (47, counted=50).
Fix? yes
Free blocks count wrong (752, counted=800).
Fix? yes
test_fs: ***** FILE SYSTEM WAS MODIFIED *****
test_fs: 18/128 files (5.6% non-contiguous), 1248/2048 blocks
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_fs: 18/128 files (5.6% non-contiguous), 1248/2048 blocks
debugfs: stat /a
Inode: 12 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1117152157 Version: 0x00000001
User: 0 Group: 0 Size: 3072
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 32
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
EXTENTS:
(0-1):1136-1137, (2):1138
debugfs: stat /b
Inode: 13 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1117152158 Version: 0x00000001
User: 0 Group: 0 Size: 3072
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 32
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
EXTENTS:
(0-2):1152-1154
debugfs: stat /c
Inode: 14 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1117152159 Version: 0x00000001
User: 0 Group: 0 Size: 3072
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 32
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
EXTENTS:
(0-1):1216-1217, (2):1218
debugfs: stat /d
Inode: 15 Type: regular Mode: 0644 Flags: 0x0
Generation: 1117152160 Version: 0x00000001
User: 0 Group: 0 Size: 3072
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 32
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
BLOCKS:
(TIND):1650
TOTAL: 1
debugfs: stat /e
Inode: 16 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1117152161 Version: 0x00000001
User: 0 Group: 0 Size: 6144
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 32
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
EXTENTS:
(0-2):1664-1666, (5):1669
debugfs: stat /f
Inode: 17 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1117152162 Version: 0x00000001
User: 0 Group: 0 Size: 3072
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 32
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
EXTENTS:
(0):1232, (1):1233, (2):1234
debugfs: stat /g
Inode: 18 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1117152163 Version: 0x00000001
User: 0 Group: 0 Size: 3072
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 32
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
EXTENTS:
(0-2):1680-1682, (3):1683
debugfs:

BIN
tests/f_badcluster/image.gz Normal file

Binary file not shown.

2
tests/f_badcluster/name Normal file
View File

@ -0,0 +1,2 @@
test alignment problems with bigalloc clusters

24
tests/f_badcluster/script Normal file
View File

@ -0,0 +1,24 @@
if test -x $DEBUGFS_EXE; then
IMAGE=$test_dir/../f_badcluster/image.gz
OUT=$test_name.log
EXP=$test_dir/expect
gzip -d < $IMAGE > $TMPFILE
$FSCK -fy $TMPFILE 2>&1 | sed -f $cmd_dir/filter.sed > $OUT
$FSCK -fy $TMPFILE 2>&1 | sed -f $cmd_dir/filter.sed >> $OUT
$FSCK -fy $TMPFILE 2>&1 | sed -f $cmd_dir/filter.sed >> $OUT
for i in a b c d e f g; do echo "stat /$i"; done | $DEBUGFS_EXE $TMPFILE >> $OUT
cmp -s $OUT $EXP
status=$?
if [ "$status" = 0 ]; then
echo "$test_name: $test_description: ok"
touch $test_name.ok
else
echo "$test_name: $test_description: failed"
diff $DIFF_OPTS $EXP $OUT > $test_name.failed
rm -f $test_name.tmp
fi
else
echo "$test_name: skipped"
fi

View File

@ -2,11 +2,6 @@ Pass 1: Checking inodes, blocks, and sizes
Inode 12, i_size is 61440, should be 4398050758656. Fix? yes
Pass 2: Checking directory structure
Filesystem contains large files, but lacks LARGE_FILE flag in superblock.
Fix? yes
Filesystem has feature flag(s) set, but is a revision 0 filesystem. Fix? yes
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

View File

@ -0,0 +1,16 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Directory inode 2, block #0, offset 0: directory has no checksum.
Fix? yes
Directory inode 2, block #0, offset 1012: directory corrupted
Salvage? yes
Pass 3: Checking directory connectivity
Pass 3A: Optimizing directories
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/128 files (9.1% non-contiguous), 1090/2048 blocks
Exit status is 1

View File

@ -0,0 +1,7 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 11/128 files (9.1% non-contiguous), 1090/2048 blocks
Exit status is 0

Binary file not shown.

View File

@ -0,0 +1 @@
rebuild a directory with corrupt dirent tail

View File

@ -12,7 +12,7 @@ Relocate? yes
../e2fsck/e2fsck: A block group is missing an inode table while reading bad blocks inode
This doesn't bode well, but we'll try to go on...
Pass 1: Checking inodes, blocks, and sizes
Relocating group 0's inode table to 5...
Relocating group 0's inode table to 7...
Restarting e2fsck from the beginning...
Pass 1: Checking inodes, blocks, and sizes
Root inode is not a directory. Clear? yes

View File

@ -0,0 +1,311 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Directory inode 2, block #0, offset 0: directory has no checksum.
Fix? yes
Directory inode 2, block #0, offset 0: directory corrupted
Salvage? yes
Missing '.' in directory inode 2.
Fix? yes
Setting filetype for entry '.' in ??? (2) to 2.
Missing '..' in directory inode 2.
Fix? yes
Setting filetype for entry '..' in ??? (2) to 2.
Pass 3: Checking directory connectivity
'..' in / (2) is <The NULL inode> (0), should be / (2).
Fix? yes
Unconnected directory inode 11 (/???)
Connect to /lost+found? yes
/lost+found not found. Create? yes
Pass 3A: Optimizing directories
Pass 4: Checking reference counts
Inode 11 ref count is 3, should be 2. Fix? yes
Unattached inode 12
Connect to /lost+found? yes
Inode 12 ref count is 2, should be 1. Fix? yes
Unattached inode 13
Connect to /lost+found? yes
Inode 13 ref count is 2, should be 1. Fix? yes
Unattached inode 14
Connect to /lost+found? yes
Inode 14 ref count is 2, should be 1. Fix? yes
Unattached inode 15
Connect to /lost+found? yes
Inode 15 ref count is 2, should be 1. Fix? yes
Unattached inode 16
Connect to /lost+found? yes
Inode 16 ref count is 2, should be 1. Fix? yes
Unattached inode 17
Connect to /lost+found? yes
Inode 17 ref count is 2, should be 1. Fix? yes
Unattached inode 18
Connect to /lost+found? yes
Inode 18 ref count is 2, should be 1. Fix? yes
Unattached inode 19
Connect to /lost+found? yes
Inode 19 ref count is 2, should be 1. Fix? yes
Unattached inode 20
Connect to /lost+found? yes
Inode 20 ref count is 2, should be 1. Fix? yes
Unattached inode 21
Connect to /lost+found? yes
Inode 21 ref count is 2, should be 1. Fix? yes
Unattached inode 22
Connect to /lost+found? yes
Inode 22 ref count is 2, should be 1. Fix? yes
Unattached inode 23
Connect to /lost+found? yes
Inode 23 ref count is 2, should be 1. Fix? yes
Unattached inode 24
Connect to /lost+found? yes
Inode 24 ref count is 2, should be 1. Fix? yes
Unattached inode 25
Connect to /lost+found? yes
Inode 25 ref count is 2, should be 1. Fix? yes
Unattached inode 26
Connect to /lost+found? yes
Inode 26 ref count is 2, should be 1. Fix? yes
Unattached inode 27
Connect to /lost+found? yes
Inode 27 ref count is 2, should be 1. Fix? yes
Unattached inode 28
Connect to /lost+found? yes
Inode 28 ref count is 2, should be 1. Fix? yes
Unattached inode 29
Connect to /lost+found? yes
Inode 29 ref count is 2, should be 1. Fix? yes
Unattached inode 30
Connect to /lost+found? yes
Inode 30 ref count is 2, should be 1. Fix? yes
Unattached inode 31
Connect to /lost+found? yes
Inode 31 ref count is 2, should be 1. Fix? yes
Unattached inode 32
Connect to /lost+found? yes
Inode 32 ref count is 2, should be 1. Fix? yes
Unattached inode 33
Connect to /lost+found? yes
Inode 33 ref count is 2, should be 1. Fix? yes
Unattached inode 34
Connect to /lost+found? yes
Inode 34 ref count is 2, should be 1. Fix? yes
Unattached inode 35
Connect to /lost+found? yes
Inode 35 ref count is 2, should be 1. Fix? yes
Unattached inode 36
Connect to /lost+found? yes
Inode 36 ref count is 2, should be 1. Fix? yes
Unattached inode 37
Connect to /lost+found? yes
Inode 37 ref count is 2, should be 1. Fix? yes
Unattached inode 38
Connect to /lost+found? yes
Inode 38 ref count is 2, should be 1. Fix? yes
Unattached inode 39
Connect to /lost+found? yes
Inode 39 ref count is 2, should be 1. Fix? yes
Unattached inode 40
Connect to /lost+found? yes
Inode 40 ref count is 2, should be 1. Fix? yes
Unattached inode 41
Connect to /lost+found? yes
Inode 41 ref count is 2, should be 1. Fix? yes
Unattached inode 42
Connect to /lost+found? yes
Inode 42 ref count is 2, should be 1. Fix? yes
Unattached inode 43
Connect to /lost+found? yes
Inode 43 ref count is 2, should be 1. Fix? yes
Unattached inode 44
Connect to /lost+found? yes
Inode 44 ref count is 2, should be 1. Fix? yes
Unattached inode 45
Connect to /lost+found? yes
Inode 45 ref count is 2, should be 1. Fix? yes
Unattached inode 46
Connect to /lost+found? yes
Inode 46 ref count is 2, should be 1. Fix? yes
Unattached inode 47
Connect to /lost+found? yes
Inode 47 ref count is 2, should be 1. Fix? yes
Unattached inode 48
Connect to /lost+found? yes
Inode 48 ref count is 2, should be 1. Fix? yes
Unattached inode 49
Connect to /lost+found? yes
Inode 49 ref count is 2, should be 1. Fix? yes
Unattached inode 50
Connect to /lost+found? yes
Inode 50 ref count is 2, should be 1. Fix? yes
Unattached inode 51
Connect to /lost+found? yes
Inode 51 ref count is 2, should be 1. Fix? yes
Unattached inode 52
Connect to /lost+found? yes
Inode 52 ref count is 2, should be 1. Fix? yes
Unattached inode 53
Connect to /lost+found? yes
Inode 53 ref count is 2, should be 1. Fix? yes
Unattached inode 54
Connect to /lost+found? yes
Inode 54 ref count is 2, should be 1. Fix? yes
Unattached inode 55
Connect to /lost+found? yes
Inode 55 ref count is 2, should be 1. Fix? yes
Unattached inode 56
Connect to /lost+found? yes
Inode 56 ref count is 2, should be 1. Fix? yes
Unattached inode 57
Connect to /lost+found? yes
Inode 57 ref count is 2, should be 1. Fix? yes
Unattached inode 58
Connect to /lost+found? yes
Inode 58 ref count is 2, should be 1. Fix? yes
Unattached inode 59
Connect to /lost+found? yes
Inode 59 ref count is 2, should be 1. Fix? yes
Unattached inode 60
Connect to /lost+found? yes
Inode 60 ref count is 2, should be 1. Fix? yes
Unattached inode 61
Connect to /lost+found? yes
Inode 61 ref count is 2, should be 1. Fix? yes
Unattached inode 62
Connect to /lost+found? yes
Inode 62 ref count is 2, should be 1. Fix? yes
Unattached inode 63
Connect to /lost+found? yes
Inode 63 ref count is 2, should be 1. Fix? yes
Unattached inode 64
Connect to /lost+found? yes
Inode 64 ref count is 2, should be 1. Fix? yes
Unattached zero-length inode 65. Clear? yes
Unattached inode 66
Connect to /lost+found? yes
Inode 66 ref count is 2, should be 1. Fix? yes
Unattached inode 67
Connect to /lost+found? yes
Inode 67 ref count is 2, should be 1. Fix? yes
Pass 5: Checking group summary information
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 67/512 files (1.5% non-contiguous), 1127/2048 blocks
Exit status is 1

View File

@ -0,0 +1,7 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 67/512 files (1.5% non-contiguous), 1127/2048 blocks
Exit status is 0

Binary file not shown.

View File

@ -0,0 +1 @@
force fsck to rebuild a corrupted rootdir w/ metadata_csum

View File

@ -0,0 +1,55 @@
Creating filesystem with 1024 1k blocks and 128 inodes
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
Filesystem features: ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 11/128 files (0.0% non-contiguous), 42/1024 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 128
Block count: 1024
Reserved block count: 51
Free blocks: 982
Free inodes: 117
First block: 1
Block size: 1024
Fragment size: 1024
Group descriptor size: 64
Reserved GDT blocks: 7
Blocks per group: 8192
Fragments per group: 8192
Inodes per group: 128
Inode blocks per group: 16
Flex block group size: 16
Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
First inode: 11
Inode size: 128
Default directory hash: half_md4
Group 0: (Blocks 1-1023)
Primary superblock at 1, Group descriptors at 2-2
Reserved GDT blocks at 3-9
Block bitmap at 10 (+9), Inode bitmap at 26 (+25)
Inode table at 42-57 (+41)
982 free blocks, 117 free inodes, 2 directories
Free blocks: 24-25, 28-41, 58-1023
Free inodes: 12-128

View File

@ -0,0 +1,4 @@
DESCRIPTION="mkfs with 64bit and flex_bg"
FS_SIZE=1M
MKE2FS_OPTS="-O 64bit,extents,flex_bg"
. $cmd_dir/run_mke2fs

View File

@ -64,8 +64,8 @@ then
return 1
fi
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
then
dumpe2fs $TMPFILE >> $LOG
return 1
@ -94,8 +94,8 @@ then
return 1
fi
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
then
dumpe2fs $TMPFILE >> $LOG
return 1
@ -119,8 +119,8 @@ then
return 1
fi
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
then
dumpe2fs $TMPFILE >> $LOG
return 1
@ -144,8 +144,8 @@ then
return 1
fi
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
then
dumpe2fs $TMPFILE >> $LOG
return 1

View File

@ -16,7 +16,6 @@
/In file included from/d
/In function `.*':/d
/zero-length format string/d
/warning: missing initializer/d
/warning: (near initialization for/d
/^[ ]*from/d

View File

@ -14,6 +14,9 @@
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>