mirror of https://github.com/vitalif/e2fsprogs
Merge branch 'next'
commit
5543f45eea
|
@ -12404,7 +12404,7 @@ fi
|
||||||
done
|
done
|
||||||
|
|
||||||
fi
|
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 :
|
do :
|
||||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
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"
|
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
|
||||||
|
|
||||||
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 :
|
do :
|
||||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||||
|
|
|
@ -920,6 +920,7 @@ AC_CHECK_HEADERS(m4_flatten([
|
||||||
termio.h
|
termio.h
|
||||||
unistd.h
|
unistd.h
|
||||||
utime.h
|
utime.h
|
||||||
|
attr/xattr.h
|
||||||
linux/falloc.h
|
linux/falloc.h
|
||||||
linux/fd.h
|
linux/fd.h
|
||||||
linux/major.h
|
linux/major.h
|
||||||
|
@ -1098,6 +1099,7 @@ AC_CHECK_FUNCS(m4_flatten([
|
||||||
getrlimit
|
getrlimit
|
||||||
getrusage
|
getrusage
|
||||||
jrand48
|
jrand48
|
||||||
|
llistxattr
|
||||||
llseek
|
llseek
|
||||||
lseek64
|
lseek64
|
||||||
mallinfo
|
mallinfo
|
||||||
|
|
|
@ -2094,7 +2094,6 @@ void do_symlink(int argc, char *argv[])
|
||||||
void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[])
|
void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[])
|
||||||
{
|
{
|
||||||
#if CONFIG_MMP
|
#if CONFIG_MMP
|
||||||
struct ext2_super_block *sb;
|
|
||||||
struct mmp_struct *mmp_s;
|
struct mmp_struct *mmp_s;
|
||||||
time_t t;
|
time_t t;
|
||||||
errcode_t retval = 0;
|
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]))
|
if (check_fs_open(argv[0]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sb = current_fs->super;
|
|
||||||
|
|
||||||
if (current_fs->mmp_buf == NULL) {
|
if (current_fs->mmp_buf == NULL) {
|
||||||
retval = ext2fs_get_mem(current_fs->blocksize,
|
retval = ext2fs_get_mem(current_fs->blocksize,
|
||||||
¤t_fs->mmp_buf);
|
¤t_fs->mmp_buf);
|
||||||
|
|
|
@ -369,6 +369,9 @@ struct e2fsck_struct {
|
||||||
profile_t profile;
|
profile_t profile;
|
||||||
int blocks_per_page;
|
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
|
* For the use of callers of the e2fsck functions; not used by
|
||||||
* e2fsck functions themselves.
|
* e2fsck functions themselves.
|
||||||
|
|
|
@ -443,8 +443,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
|
||||||
if (ext_journal) {
|
if (ext_journal) {
|
||||||
blk64_t maxlen;
|
blk64_t maxlen;
|
||||||
|
|
||||||
if (ctx->fs->blocksize == 1024)
|
start = ext2fs_journal_sb_start(ctx->fs->blocksize) - 1;
|
||||||
start = 1;
|
|
||||||
bh = getblk(dev_journal, start, ctx->fs->blocksize);
|
bh = getblk(dev_journal, start, ctx->fs->blocksize);
|
||||||
if (!bh) {
|
if (!bh) {
|
||||||
retval = EXT2_ET_NO_MEMORY;
|
retval = EXT2_ET_NO_MEMORY;
|
||||||
|
@ -455,7 +454,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
goto errout;
|
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));
|
sizeof(jsuper));
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
|
141
e2fsck/pass1.c
141
e2fsck/pass1.c
|
@ -277,8 +277,7 @@ static void check_size(e2fsck_t ctx, struct problem_context *pctx)
|
||||||
if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
|
if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inode->i_size = 0;
|
ext2fs_inode_size_set(ctx->fs, inode, 0);
|
||||||
inode->i_size_high = 0;
|
|
||||||
e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
|
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;
|
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)
|
void e2fsck_pass1(e2fsck_t ctx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -935,8 +970,10 @@ void e2fsck_pass1(e2fsck_t ctx)
|
||||||
if (ino == EXT2_BAD_INO) {
|
if (ino == EXT2_BAD_INO) {
|
||||||
struct process_block_struct pb;
|
struct process_block_struct pb;
|
||||||
|
|
||||||
if ((inode->i_mode || inode->i_uid || inode->i_gid ||
|
if ((failed_csum || inode->i_mode || inode->i_uid ||
|
||||||
inode->i_links_count || inode->i_file_acl) &&
|
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)) {
|
fix_problem(ctx, PR_1_INVALID_BAD_INODE, &pctx)) {
|
||||||
memset(inode, 0, sizeof(struct ext2_inode));
|
memset(inode, 0, sizeof(struct ext2_inode));
|
||||||
e2fsck_write_inode(ctx, ino, inode,
|
e2fsck_write_inode(ctx, ino, inode,
|
||||||
|
@ -1280,6 +1317,9 @@ void e2fsck_pass1(e2fsck_t ctx)
|
||||||
ext2fs_close_inode_scan(scan);
|
ext2fs_close_inode_scan(scan);
|
||||||
scan = NULL;
|
scan = NULL;
|
||||||
|
|
||||||
|
reserve_block_for_root_repair(ctx);
|
||||||
|
reserve_block_for_lnf_repair(ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If any extended attribute blocks' reference counts need to
|
* If any extended attribute blocks' reference counts need to
|
||||||
* be adjusted, either up (ctx->refcount_extra), or down
|
* 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);
|
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,
|
static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
struct process_block_struct *pb,
|
struct process_block_struct *pb,
|
||||||
blk64_t start_block, blk64_t end_block,
|
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;
|
last_lblk = extent.e_lblk + extent.e_len - 1;
|
||||||
|
|
||||||
problem = 0;
|
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 */
|
/* Ask to clear a corrupt extent block */
|
||||||
if (try_repairs &&
|
if (try_repairs &&
|
||||||
pctx->errcode == EXT2_ET_EXTENT_CSUM_INVALID) {
|
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;
|
problem = PR_1_EXTENT_CSUM_INVALID;
|
||||||
if (fix_problem(ctx, problem, pctx))
|
if (fix_problem(ctx, problem, pctx))
|
||||||
goto fix_problem_now;
|
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))))
|
(1 << (21 - ctx->fs->super->s_log_block_size))))
|
||||||
problem = PR_1_TOOBIG_DIR;
|
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
|
* Uninitialized blocks in a directory? Clear the flag and
|
||||||
* we'll interpret the blocks later.
|
* 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 = 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) {
|
if (try_repairs && problem) {
|
||||||
report_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)) {
|
if (fix_problem(ctx, problem, pctx)) {
|
||||||
fix_problem_now:
|
fix_problem_now:
|
||||||
if (ctx->invalid_bitmaps) {
|
if (ctx->invalid_bitmaps) {
|
||||||
|
@ -2210,7 +2279,16 @@ alloc_later:
|
||||||
mark_block_used(ctx, blk);
|
mark_block_used(ctx, blk);
|
||||||
pb->num_blocks++;
|
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;
|
pb->previous_block = blk;
|
||||||
|
|
||||||
if (is_dir) {
|
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->num = (pb.last_block+1) * fs->blocksize;
|
||||||
pctx->group = bad_size;
|
pctx->group = bad_size;
|
||||||
if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
|
if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
|
||||||
inode->i_size = pctx->num;
|
if (LINUX_S_ISDIR(inode->i_mode))
|
||||||
if (!LINUX_S_ISDIR(inode->i_mode))
|
pctx->num &= 0xFFFFFFFFULL;
|
||||||
inode->i_size_high = pctx->num >> 32;
|
ext2fs_inode_size_set(fs, inode, pctx->num);
|
||||||
dirty_inode++;
|
dirty_inode++;
|
||||||
}
|
}
|
||||||
pctx->num = 0;
|
pctx->num = 0;
|
||||||
|
@ -2776,6 +2854,13 @@ static int process_block(ext2_filsys fs,
|
||||||
((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
|
((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
|
||||||
mark_block_used(ctx, blk);
|
mark_block_used(ctx, blk);
|
||||||
p->num_blocks++;
|
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)
|
if (blockcnt >= 0)
|
||||||
p->last_block = blockcnt;
|
p->last_block = blockcnt;
|
||||||
|
|
|
@ -261,7 +261,7 @@ struct process_block_struct {
|
||||||
e2fsck_t ctx;
|
e2fsck_t ctx;
|
||||||
ext2_ino_t ino;
|
ext2_ino_t ino;
|
||||||
int dup_blocks;
|
int dup_blocks;
|
||||||
blk64_t cur_cluster;
|
blk64_t cur_cluster, phys_cluster;
|
||||||
blk64_t last_blk;
|
blk64_t last_blk;
|
||||||
struct ext2_inode *inode;
|
struct ext2_inode *inode;
|
||||||
struct problem_context *pctx;
|
struct problem_context *pctx;
|
||||||
|
@ -317,6 +317,7 @@ static void pass1b(e2fsck_t ctx, char *block_buf)
|
||||||
pb.dup_blocks = 0;
|
pb.dup_blocks = 0;
|
||||||
pb.inode = &inode;
|
pb.inode = &inode;
|
||||||
pb.cur_cluster = ~0;
|
pb.cur_cluster = ~0;
|
||||||
|
pb.phys_cluster = ~0;
|
||||||
pb.last_blk = 0;
|
pb.last_blk = 0;
|
||||||
pb.pctx->blk = pb.pctx->blk2 = 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;
|
struct process_block_struct *p;
|
||||||
e2fsck_t ctx;
|
e2fsck_t ctx;
|
||||||
blk64_t lc;
|
blk64_t lc, pc;
|
||||||
problem_t op;
|
problem_t op;
|
||||||
|
|
||||||
if (HOLE_BLKADDR(*block_nr))
|
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;
|
p = (struct process_block_struct *) priv_data;
|
||||||
ctx = p->ctx;
|
ctx = p->ctx;
|
||||||
lc = EXT2FS_B2C(fs, blockcnt);
|
lc = EXT2FS_B2C(fs, blockcnt);
|
||||||
|
pc = EXT2FS_B2C(fs, *block_nr);
|
||||||
|
|
||||||
if (!ext2fs_test_block_bitmap2(ctx->block_dup_map, *block_nr))
|
if (!ext2fs_test_block_bitmap2(ctx->block_dup_map, *block_nr))
|
||||||
goto finish;
|
goto finish;
|
||||||
|
@ -389,11 +391,19 @@ static int process_pass1b_block(ext2_filsys fs EXT2FS_ATTR((unused)),
|
||||||
p->dup_blocks++;
|
p->dup_blocks++;
|
||||||
ext2fs_mark_inode_bitmap2(inode_dup_map, p->ino);
|
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);
|
add_dupe(ctx, p->ino, EXT2FS_B2C(fs, *block_nr), p->inode);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
p->cur_cluster = lc;
|
p->cur_cluster = lc;
|
||||||
|
p->phys_cluster = pc;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +573,11 @@ static void pass1d(e2fsck_t ctx, char *block_buf)
|
||||||
pctx.dir = t->dir;
|
pctx.dir = t->dir;
|
||||||
fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
|
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);
|
fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -630,7 +644,8 @@ static int delete_file_block(ext2_filsys fs,
|
||||||
_("internal error: can't find dup_blk for %llu\n"),
|
_("internal error: can't find dup_blk for %llu\n"),
|
||||||
*block_nr);
|
*block_nr);
|
||||||
} else {
|
} 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->dup_blocks++;
|
||||||
}
|
}
|
||||||
pb->cur_cluster = lc;
|
pb->cur_cluster = lc;
|
||||||
|
@ -706,9 +721,10 @@ struct clone_struct {
|
||||||
errcode_t errcode;
|
errcode_t errcode;
|
||||||
blk64_t dup_cluster;
|
blk64_t dup_cluster;
|
||||||
blk64_t alloc_block;
|
blk64_t alloc_block;
|
||||||
ext2_ino_t dir;
|
ext2_ino_t dir, ino;
|
||||||
char *buf;
|
char *buf;
|
||||||
e2fsck_t ctx;
|
e2fsck_t ctx;
|
||||||
|
struct ext2_inode *inode;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int clone_file_block(ext2_filsys fs,
|
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);
|
decrement_badcount(ctx, *block_nr, p);
|
||||||
|
|
||||||
cs->dup_cluster = c;
|
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,
|
retval = ext2fs_new_block2(fs, 0, ctx->block_found_map,
|
||||||
&new_block);
|
&new_block);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
cs->errcode = retval;
|
cs->errcode = retval;
|
||||||
return BLOCK_ABORT;
|
return BLOCK_ABORT;
|
||||||
}
|
}
|
||||||
|
cluster_alloc_ok:
|
||||||
cs->alloc_block = new_block;
|
cs->alloc_block = new_block;
|
||||||
|
|
||||||
got_block:
|
got_block:
|
||||||
|
@ -817,6 +846,8 @@ static errcode_t clone_file(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
cs.dup_cluster = ~0;
|
cs.dup_cluster = ~0;
|
||||||
cs.alloc_block = 0;
|
cs.alloc_block = 0;
|
||||||
cs.ctx = ctx;
|
cs.ctx = ctx;
|
||||||
|
cs.ino = ino;
|
||||||
|
cs.inode = &dp->inode;
|
||||||
retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
|
retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -665,7 +665,8 @@ clear_and_exit:
|
||||||
static void salvage_directory(ext2_filsys fs,
|
static void salvage_directory(ext2_filsys fs,
|
||||||
struct ext2_dir_entry *dirent,
|
struct ext2_dir_entry *dirent,
|
||||||
struct ext2_dir_entry *prev,
|
struct ext2_dir_entry *prev,
|
||||||
unsigned int *offset)
|
unsigned int *offset,
|
||||||
|
unsigned int block_len)
|
||||||
{
|
{
|
||||||
char *cp = (char *) dirent;
|
char *cp = (char *) dirent;
|
||||||
int left;
|
int left;
|
||||||
|
@ -673,7 +674,7 @@ static void salvage_directory(ext2_filsys fs,
|
||||||
unsigned int name_len = ext2fs_dirent_name_len(dirent);
|
unsigned int name_len = ext2fs_dirent_name_len(dirent);
|
||||||
|
|
||||||
(void) ext2fs_get_rec_len(fs, dirent, &rec_len);
|
(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
|
* 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.
|
* previous directory entry absorb the invalid one.
|
||||||
*/
|
*/
|
||||||
if (prev && rec_len && (rec_len % 4) == 0 &&
|
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);
|
(void) ext2fs_get_rec_len(fs, prev, &prev_rec_len);
|
||||||
prev_rec_len += rec_len;
|
prev_rec_len += rec_len;
|
||||||
(void) ext2fs_set_rec_len(fs, prev_rec_len, prev);
|
(void) ext2fs_set_rec_len(fs, prev_rec_len, prev);
|
||||||
|
@ -718,11 +719,11 @@ static void salvage_directory(ext2_filsys fs,
|
||||||
*/
|
*/
|
||||||
if (prev) {
|
if (prev) {
|
||||||
(void) ext2fs_get_rec_len(fs, prev, &prev_rec_len);
|
(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);
|
(void) ext2fs_set_rec_len(fs, prev_rec_len, prev);
|
||||||
*offset = fs->blocksize;
|
*offset = fs->blocksize;
|
||||||
} else {
|
} else {
|
||||||
rec_len = fs->blocksize - *offset;
|
rec_len = block_len - *offset;
|
||||||
(void) ext2fs_set_rec_len(fs, rec_len, dirent);
|
(void) ext2fs_set_rec_len(fs, rec_len, dirent);
|
||||||
ext2fs_dirent_set_name_len(dirent, 0);
|
ext2fs_dirent_set_name_len(dirent, 0);
|
||||||
ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN);
|
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);
|
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,
|
static int check_dir_block(ext2_filsys fs,
|
||||||
struct ext2_db_entry2 *db,
|
struct ext2_db_entry2 *db,
|
||||||
void *priv_data)
|
void *priv_data)
|
||||||
|
@ -960,8 +993,12 @@ skip_checksum:
|
||||||
(rec_len < 12) ||
|
(rec_len < 12) ||
|
||||||
((rec_len % 4) != 0) ||
|
((rec_len % 4) != 0) ||
|
||||||
((ext2fs_dirent_name_len(dirent) + 8) > rec_len)) {
|
((ext2fs_dirent_name_len(dirent) + 8) > rec_len)) {
|
||||||
if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
|
if (fix_problem(ctx, PR_2_DIR_CORRUPTED,
|
||||||
salvage_directory(fs, dirent, prev, &offset);
|
&cd->pctx)) {
|
||||||
|
salvage_directory(fs, dirent, prev,
|
||||||
|
&offset,
|
||||||
|
fs->blocksize -
|
||||||
|
de_csum_size);
|
||||||
dir_modified++;
|
dir_modified++;
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
|
@ -1275,8 +1312,12 @@ skip_checksum:
|
||||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
|
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
|
||||||
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
|
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
|
||||||
is_leaf &&
|
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);
|
e2fsck_rehash_dir_later(ctx, ino);
|
||||||
|
}
|
||||||
|
|
||||||
write_and_fix:
|
write_and_fix:
|
||||||
if (e2fsck_dir_will_be_rehashed(ctx, ino))
|
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) ||
|
if ((*block_nr < fs->super->s_first_data_block) ||
|
||||||
(*block_nr >= ext2fs_blocks_count(fs->super)))
|
(*block_nr >= ext2fs_blocks_count(fs->super)))
|
||||||
return 0;
|
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++;
|
p->num++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1577,7 +1619,7 @@ static int allocate_dir_block(e2fsck_t ctx,
|
||||||
struct problem_context *pctx)
|
struct problem_context *pctx)
|
||||||
{
|
{
|
||||||
ext2_filsys fs = ctx->fs;
|
ext2_filsys fs = ctx->fs;
|
||||||
blk64_t blk;
|
blk64_t blk = 0;
|
||||||
char *block;
|
char *block;
|
||||||
struct ext2_inode inode;
|
struct ext2_inode inode;
|
||||||
|
|
||||||
|
@ -1593,11 +1635,17 @@ static int allocate_dir_block(e2fsck_t ctx,
|
||||||
/*
|
/*
|
||||||
* First, find a free block
|
* First, find a free block
|
||||||
*/
|
*/
|
||||||
pctx->errcode = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
|
e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
|
||||||
if (pctx->errcode) {
|
pctx->errcode = ext2fs_map_cluster_block(fs, db->ino, &inode,
|
||||||
pctx->str = "ext2fs_new_block";
|
db->blockcnt, &blk);
|
||||||
fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
|
if (pctx->errcode || blk == 0) {
|
||||||
return 1;
|
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(ctx->block_found_map, blk);
|
||||||
ext2fs_mark_block_bitmap2(fs->block_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
|
* Update the inode block count
|
||||||
*/
|
*/
|
||||||
e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
|
|
||||||
ext2fs_iblk_add_blocks(fs, &inode, 1);
|
ext2fs_iblk_add_blocks(fs, &inode, 1);
|
||||||
if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
|
if (EXT2_I_SIZE(&inode) < (db->blockcnt+1) * fs->blocksize) {
|
||||||
inode.i_size = (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");
|
e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
113
e2fsck/pass3.c
113
e2fsck/pass3.c
|
@ -134,6 +134,17 @@ abort_exit:
|
||||||
inode_done_map = 0;
|
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);
|
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
|
* 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);
|
pctx.errcode = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
|
||||||
if (pctx.errcode) {
|
if (pctx.errcode) {
|
||||||
pctx.str = "ext2fs_new_block";
|
pctx.str = "ext2fs_new_block";
|
||||||
|
@ -184,31 +200,10 @@ static void check_root(e2fsck_t ctx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
|
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
|
||||||
|
skip_new_block:
|
||||||
ext2fs_mark_block_bitmap2(fs->block_map, blk);
|
ext2fs_mark_block_bitmap2(fs->block_map, blk);
|
||||||
ext2fs_mark_bb_dirty(fs);
|
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
|
* Set up the inode structure
|
||||||
*/
|
*/
|
||||||
|
@ -231,6 +226,30 @@ static void check_root(e2fsck_t ctx)
|
||||||
return;
|
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...
|
* Miscellaneous bookkeeping...
|
||||||
*/
|
*/
|
||||||
|
@ -425,6 +444,11 @@ unlink:
|
||||||
/*
|
/*
|
||||||
* First, find a free block
|
* 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);
|
retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
pctx.errcode = retval;
|
pctx.errcode = retval;
|
||||||
|
@ -432,6 +456,7 @@ unlink:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
|
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
|
||||||
|
skip_new_block:
|
||||||
ext2fs_block_alloc_stats2(fs, blk, +1);
|
ext2fs_block_alloc_stats2(fs, blk, +1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -448,24 +473,6 @@ unlink:
|
||||||
ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
|
ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
|
||||||
ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
|
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
|
* Set up the inode structure
|
||||||
*/
|
*/
|
||||||
|
@ -486,6 +493,27 @@ unlink:
|
||||||
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
|
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
|
||||||
return 0;
|
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
|
* Finally, create the directory link
|
||||||
*/
|
*/
|
||||||
|
@ -823,8 +851,9 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
sz = (es.last_block + 1) * fs->blocksize;
|
sz = (es.last_block + 1) * fs->blocksize;
|
||||||
inode.i_size = sz;
|
retval = ext2fs_inode_size_set(fs, &inode, sz);
|
||||||
inode.i_size_high = sz >> 32;
|
if (retval)
|
||||||
|
return retval;
|
||||||
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
|
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
|
||||||
quota_data_add(ctx->qctx, &inode, dir, es.newblocks * fs->blocksize);
|
quota_data_add(ctx->qctx, &inode, dir, es.newblocks * fs->blocksize);
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,6 @@ static void check_block_bitmaps(e2fsck_t ctx)
|
||||||
problem_t problem, save_problem;
|
problem_t problem, save_problem;
|
||||||
int fixit, had_problem;
|
int fixit, had_problem;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
int csum_flag;
|
|
||||||
int old_desc_blocks = 0;
|
int old_desc_blocks = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int cmp_block = 0;
|
int cmp_block = 0;
|
||||||
|
@ -374,7 +373,6 @@ static void check_block_bitmaps(e2fsck_t ctx)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
csum_flag = ext2fs_has_group_desc_csum(fs);
|
|
||||||
redo_counts:
|
redo_counts:
|
||||||
had_problem = 0;
|
had_problem = 0;
|
||||||
save_problem = 0;
|
save_problem = 0;
|
||||||
|
@ -898,7 +896,7 @@ static void check_block_end(e2fsck_t ctx)
|
||||||
clear_problem_context(&pctx);
|
clear_problem_context(&pctx);
|
||||||
|
|
||||||
end = ext2fs_get_block_bitmap_start2(fs->block_map) +
|
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,
|
pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, end,
|
||||||
&save_blocks_count);
|
&save_blocks_count);
|
||||||
if (pctx.errcode) {
|
if (pctx.errcode) {
|
||||||
|
|
|
@ -992,19 +992,17 @@ static struct e2fsck_problem problem_table[] = {
|
||||||
"extent\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
|
"extent\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
|
||||||
PROMPT_FIX, 0 },
|
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,
|
{ PR_1_EA_BLOCK_CSUM_INVALID,
|
||||||
N_("Extended attribute @a @b %b checksum for @i %i does not "
|
N_("@i %i @a @b %b checksum does not match block. "),
|
||||||
"match. "),
|
|
||||||
PROMPT_CLEAR, 0 },
|
PROMPT_CLEAR, 0 },
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extended attribute block passes checks, but checksum for inode does
|
* Inode extended attribute block passes checks, but checksum does not
|
||||||
* not match.
|
* match block.
|
||||||
*/
|
*/
|
||||||
{ PR_1_EA_BLOCK_ONLY_CSUM_INVALID,
|
{ PR_1_EA_BLOCK_ONLY_CSUM_INVALID,
|
||||||
N_("Extended attribute @a @b %b passes checks, but checksum for "
|
N_("@i %i @a @b %b passes checks, but checksum does not match @b. "),
|
||||||
"@i %i does not match. "),
|
|
||||||
PROMPT_FIX, 0 },
|
PROMPT_FIX, 0 },
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1048,6 +1046,11 @@ static struct e2fsck_problem problem_table[] = {
|
||||||
N_("@d @i %i has @x marked uninitialized at @b %c. "),
|
N_("@d @i %i has @x marked uninitialized at @b %c. "),
|
||||||
PROMPT_FIX, PR_PREEN_OK },
|
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 errors */
|
||||||
|
|
||||||
/* Pass 1B: Rescan for duplicate/bad blocks */
|
/* Pass 1B: Rescan for duplicate/bad blocks */
|
||||||
|
@ -1477,27 +1480,27 @@ static struct e2fsck_problem problem_table[] = {
|
||||||
|
|
||||||
/* htree root node fails checksum */
|
/* htree root node fails checksum */
|
||||||
{ PR_2_HTREE_ROOT_CSUM_INVALID,
|
{ 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 },
|
PROMPT_CLEAR_HTREE, PR_PREEN_OK },
|
||||||
|
|
||||||
/* htree internal node fails checksum */
|
/* htree internal node fails checksum */
|
||||||
{ PR_2_HTREE_NODE_CSUM_INVALID,
|
{ 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 },
|
PROMPT_CLEAR_HTREE, PR_PREEN_OK },
|
||||||
|
|
||||||
/* leaf node fails checksum */
|
/* leaf node fails checksum */
|
||||||
{ PR_2_LEAF_NODE_CSUM_INVALID,
|
{ 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 },
|
PROMPT_SALVAGE, PR_PREEN_OK },
|
||||||
|
|
||||||
/* leaf node has no checksum */
|
/* leaf node has no checksum */
|
||||||
{ PR_2_LEAF_NODE_MISSING_CSUM,
|
{ 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 },
|
PROMPT_FIX, PR_PREEN_OK },
|
||||||
|
|
||||||
/* leaf node passes checks but fails checksum */
|
/* leaf node passes checks but fails checksum */
|
||||||
{ PR_2_LEAF_NODE_ONLY_CSUM_INVALID,
|
{ 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 },
|
PROMPT_FIX, PR_PREEN_OK },
|
||||||
|
|
||||||
/* Pass 3 errors */
|
/* Pass 3 errors */
|
||||||
|
@ -1823,12 +1826,12 @@ static struct e2fsck_problem problem_table[] = {
|
||||||
|
|
||||||
/* Group N inode bitmap does not match checksum */
|
/* Group N inode bitmap does not match checksum */
|
||||||
{ PR_5_INODE_BITMAP_CSUM_INVALID,
|
{ 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 },
|
PROMPT_FIX, PR_LATCH_IBITMAP | PR_PREEN_OK },
|
||||||
|
|
||||||
/* Group N block bitmap does not match checksum */
|
/* Group N block bitmap does not match checksum */
|
||||||
{ PR_5_BLOCK_BITMAP_CSUM_INVALID,
|
{ 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 },
|
PROMPT_FIX, PR_LATCH_BBITMAP | PR_PREEN_OK },
|
||||||
|
|
||||||
/* Post-Pass 5 errors */
|
/* Post-Pass 5 errors */
|
||||||
|
|
|
@ -609,6 +609,9 @@ struct problem_context {
|
||||||
/* uninit directory block */
|
/* uninit directory block */
|
||||||
#define PR_1_UNINIT_DBLOCK 0x010073
|
#define PR_1_UNINIT_DBLOCK 0x010073
|
||||||
|
|
||||||
|
/* Inode logical block is misaligned */
|
||||||
|
#define PR_1_MISALIGNED_CLUSTER 0x010074
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pass 1b errors
|
* Pass 1b errors
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -771,7 +771,10 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
|
||||||
inode.i_flags &= ~EXT2_INDEX_FL;
|
inode.i_flags &= ~EXT2_INDEX_FL;
|
||||||
else
|
else
|
||||||
inode.i_flags |= EXT2_INDEX_FL;
|
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);
|
ext2fs_iblk_sub_blocks(fs, &inode, wd.cleared);
|
||||||
e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
|
e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
|
||||||
|
|
||||||
|
|
|
@ -421,7 +421,7 @@ void check_resize_inode(e2fsck_t ctx)
|
||||||
for (j = 1; j < fs->group_desc_count; j++) {
|
for (j = 1; j < fs->group_desc_count; j++) {
|
||||||
if (!ext2fs_bg_has_super(fs, j))
|
if (!ext2fs_bg_has_super(fs, j))
|
||||||
continue;
|
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)
|
if (ind_buf[ind_off] != expect)
|
||||||
goto resize_inode_invalid;
|
goto resize_inode_invalid;
|
||||||
ind_off++;
|
ind_off++;
|
||||||
|
|
|
@ -70,6 +70,9 @@
|
||||||
/* Define to 1 if you have the `asprintf' function. */
|
/* Define to 1 if you have the `asprintf' function. */
|
||||||
#undef HAVE_ASPRINTF
|
#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. */
|
/* Define to 1 if you have the `backtrace' function. */
|
||||||
#undef HAVE_BACKTRACE
|
#undef HAVE_BACKTRACE
|
||||||
|
|
||||||
|
@ -244,6 +247,9 @@
|
||||||
/* Define to 1 if you have the <linux/major.h> header file. */
|
/* Define to 1 if you have the <linux/major.h> header file. */
|
||||||
#undef HAVE_LINUX_MAJOR_H
|
#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. */
|
/* Define to 1 if you have the `llseek' function. */
|
||||||
#undef HAVE_LLSEEK
|
#undef HAVE_LLSEEK
|
||||||
|
|
||||||
|
|
|
@ -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_group_desc_csum_set(fs, group);
|
||||||
|
|
||||||
ext2fs_free_blocks_count_add(fs->super,
|
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_super_dirty(fs);
|
||||||
ext2fs_mark_bb_dirty(fs);
|
ext2fs_mark_bb_dirty(fs);
|
||||||
if (fs->block_alloc_stats)
|
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));
|
inuse*n/EXT2FS_CLUSTER_RATIO(fs));
|
||||||
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
|
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
|
||||||
ext2fs_group_desc_csum_set(fs, group);
|
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;
|
blk += n;
|
||||||
num -= n;
|
num -= n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,10 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
|
||||||
if (!inode.i_ctime)
|
if (!inode.i_ctime)
|
||||||
inode.i_ctime = fs->now ? fs->now : time(0);
|
inode.i_ctime = fs->now ? fs->now : time(0);
|
||||||
ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
|
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);
|
retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
|
||||||
if (retval)
|
if (retval)
|
||||||
|
|
|
@ -83,7 +83,7 @@ static void print_tree(struct rb_root *root)
|
||||||
|
|
||||||
static void check_tree(struct rb_root *root, const char *msg)
|
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;
|
struct bmap_rb_extent *ext, *old = NULL;
|
||||||
|
|
||||||
for (node = ext2fs_rb_first(root); node;
|
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;
|
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 = (struct ext2fs_rb_private *) bmap->private;
|
||||||
bp->rcursor = NULL;
|
bp->rcursor = NULL;
|
||||||
bp->wcursor = NULL;
|
bp->wcursor = NULL;
|
||||||
|
|
||||||
/* truncate tree to new_real_end size */
|
rb_truncate(((new_end < bmap->end) ? new_end : bmap->end) - bmap->start,
|
||||||
rb_truncate(new_real_end, &bp->root);
|
&bp->root);
|
||||||
|
|
||||||
bmap->end = new_end;
|
bmap->end = new_end;
|
||||||
bmap->real_end = new_real_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;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group)
|
||||||
{
|
{
|
||||||
return fs->super->s_first_data_block +
|
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;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 errcode_t dos_flush(io_channel channel);
|
||||||
|
|
||||||
static struct struct_io_manager struct_dos_manager = {
|
static struct struct_io_manager struct_dos_manager = {
|
||||||
EXT2_ET_MAGIC_IO_MANAGER,
|
.magic = EXT2_ET_MAGIC_IO_MANAGER,
|
||||||
"DOS I/O Manager",
|
.name = "DOS I/O Manager",
|
||||||
dos_open,
|
.open = dos_open,
|
||||||
dos_close,
|
.close = dos_close,
|
||||||
dos_set_blksize,
|
.set_blksize = dos_set_blksize,
|
||||||
dos_read_blk,
|
.read_blk = dos_read_blk,
|
||||||
dos_write_blk,
|
.write_blk = dos_write_blk,
|
||||||
dos_flush
|
.flush = dos_flush
|
||||||
};
|
};
|
||||||
|
|
||||||
io_manager dos_io_manager = &struct_dos_manager;
|
io_manager dos_io_manager = &struct_dos_manager;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -278,6 +278,11 @@ struct ext2_dx_tail {
|
||||||
#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
|
#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
|
||||||
#endif
|
#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
|
* Constants relative to the data blocks
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -39,6 +39,8 @@ extern "C" {
|
||||||
#define SUPERBLOCK_OFFSET 1024
|
#define SUPERBLOCK_OFFSET 1024
|
||||||
#define SUPERBLOCK_SIZE 1024
|
#define SUPERBLOCK_SIZE 1024
|
||||||
|
|
||||||
|
#define UUID_STR_SIZE 37
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The last ext2fs revision level that this version of the library is
|
* The last ext2fs revision level that this version of the library is
|
||||||
* able to support.
|
* able to support.
|
||||||
|
@ -894,6 +896,8 @@ extern blk64_t ext2fs_file_acl_block(ext2_filsys fs,
|
||||||
const struct ext2_inode *inode);
|
const struct ext2_inode *inode);
|
||||||
extern void ext2fs_file_acl_block_set(ext2_filsys fs,
|
extern void ext2fs_file_acl_block_set(ext2_filsys fs,
|
||||||
struct ext2_inode *inode, blk64_t blk);
|
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 */
|
/* block.c */
|
||||||
extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
|
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,
|
extern errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
|
||||||
blk64_t goal, int flags);
|
blk64_t goal, int flags);
|
||||||
extern int ext2fs_default_journal_size(__u64 num_blocks);
|
extern int ext2fs_default_journal_size(__u64 num_blocks);
|
||||||
|
extern int ext2fs_journal_sb_start(int blocksize);
|
||||||
|
|
||||||
/* openfs.c */
|
/* openfs.c */
|
||||||
extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
|
extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
|
||||||
|
|
|
@ -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) >>
|
old_truncate = ((old_size + file->fs->blocksize - 1) >>
|
||||||
EXT2_BLOCK_SIZE_BITS(file->fs->super));
|
EXT2_BLOCK_SIZE_BITS(file->fs->super));
|
||||||
|
|
||||||
/* If we're writing a large file, set the large_file flag */
|
retval = ext2fs_inode_size_set(file->fs, &file->inode, size);
|
||||||
if (LINUX_S_ISREG(file->inode.i_mode) &&
|
if (retval)
|
||||||
ext2fs_needs_large_file_feature(EXT2_I_SIZE(&file->inode)) &&
|
return retval;
|
||||||
(!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);
|
|
||||||
}
|
|
||||||
|
|
||||||
file->inode.i_size = size & 0xffffffff;
|
|
||||||
file->inode.i_size_high = (size >> 32);
|
|
||||||
if (file->ino) {
|
if (file->ino) {
|
||||||
retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
|
retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
|
||||||
if (retval)
|
if (retval)
|
||||||
|
|
|
@ -286,8 +286,8 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
|
||||||
ext2fs_generic_bitmap bmap;
|
ext2fs_generic_bitmap bmap;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
ssize_t actual;
|
ssize_t actual;
|
||||||
__u32 itr, cnt, size;
|
size_t c;
|
||||||
int c, total_size;
|
__u64 itr, cnt, size, total_size;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
if (flags & IMAGER_FLAG_INODEMAP) {
|
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;
|
bmap = fs->block_map;
|
||||||
itr = fs->super->s_first_data_block;
|
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;
|
size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
|
||||||
}
|
}
|
||||||
total_size = size * fs->group_desc_count;
|
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))
|
if (c > (int) sizeof(buf))
|
||||||
c = sizeof(buf);
|
c = sizeof(buf);
|
||||||
actual = write(fd, buf, c);
|
actual = write(fd, buf, c);
|
||||||
if (actual == -1)
|
if (actual < 0)
|
||||||
return errno;
|
return errno;
|
||||||
if (actual != c)
|
if ((size_t) actual != c)
|
||||||
return EXT2_ET_SHORT_WRITE;
|
return EXT2_ET_SHORT_WRITE;
|
||||||
size -= c;
|
size -= c;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
|
||||||
{
|
{
|
||||||
ext2fs_generic_bitmap bmap;
|
ext2fs_generic_bitmap bmap;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
__u32 itr, cnt;
|
__u64 itr, cnt;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
ssize_t actual;
|
ssize_t actual;
|
||||||
|
@ -383,7 +383,7 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
|
||||||
}
|
}
|
||||||
bmap = fs->block_map;
|
bmap = fs->block_map;
|
||||||
itr = fs->super->s_first_data_block;
|
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;
|
size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,19 +63,17 @@ static errcode_t inode_write_blk64(io_channel channel,
|
||||||
unsigned long long block, int count, const void *data);
|
unsigned long long block, int count, const void *data);
|
||||||
|
|
||||||
static struct struct_io_manager struct_inode_manager = {
|
static struct struct_io_manager struct_inode_manager = {
|
||||||
EXT2_ET_MAGIC_IO_MANAGER,
|
.magic = EXT2_ET_MAGIC_IO_MANAGER,
|
||||||
"Inode I/O Manager",
|
.name = "Inode I/O Manager",
|
||||||
inode_open,
|
.open = inode_open,
|
||||||
inode_close,
|
.close = inode_close,
|
||||||
inode_set_blksize,
|
.set_blksize = inode_set_blksize,
|
||||||
inode_read_blk,
|
.read_blk = inode_read_blk,
|
||||||
inode_write_blk,
|
.write_blk = inode_write_blk,
|
||||||
inode_flush,
|
.flush = inode_flush,
|
||||||
inode_write_byte,
|
.write_byte = inode_write_byte,
|
||||||
NULL,
|
.read_blk64 = inode_read_blk64,
|
||||||
NULL,
|
.write_blk64 = inode_write_blk64
|
||||||
inode_read_blk64,
|
|
||||||
inode_write_blk64
|
|
||||||
};
|
};
|
||||||
|
|
||||||
io_manager inode_io_manager = &struct_inode_manager;
|
io_manager inode_io_manager = &struct_inode_manager;
|
||||||
|
|
|
@ -186,6 +186,9 @@ struct journal_revoke_tail {
|
||||||
#define JFS_FLAG_LAST_TAG 8 /* last tag in this descriptor block */
|
#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.
|
* 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) */
|
__u32 s_checksum; /* crc32c(superblock) */
|
||||||
|
|
||||||
/* 0x0100 */
|
/* 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 */
|
/* 0x0400 */
|
||||||
} journal_superblock_t;
|
} journal_superblock_t;
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
journal_superblock_t *jsb;
|
journal_superblock_t *jsb;
|
||||||
|
|
||||||
if (num_blocks < 1024)
|
if (num_blocks < JFS_MIN_JOURNAL_BLOCKS)
|
||||||
return EXT2_ET_JOURNAL_TOO_SMALL;
|
return EXT2_ET_JOURNAL_TOO_SMALL;
|
||||||
|
|
||||||
if ((retval = ext2fs_get_mem(fs->blocksize, &jsb)))
|
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 &
|
if (fs->super->s_feature_incompat &
|
||||||
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
|
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
|
||||||
jsb->s_nr_users = 0;
|
jsb->s_nr_users = 0;
|
||||||
if (fs->blocksize == 1024)
|
jsb->s_first = htonl(ext2fs_journal_sb_start(fs->blocksize) + 1);
|
||||||
jsb->s_first = htonl(3);
|
|
||||||
else
|
|
||||||
jsb->s_first = htonl(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_jsb = (char *) jsb;
|
*ret_jsb = (char *) jsb;
|
||||||
|
@ -383,15 +380,13 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
inode_size = (unsigned long long)fs->blocksize * num_blocks;
|
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);
|
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
|
||||||
inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
|
inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
|
||||||
inode.i_links_count = 1;
|
inode.i_links_count = 1;
|
||||||
inode.i_mode = LINUX_S_IFREG | 0600;
|
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)))
|
if ((retval = ext2fs_write_new_inode(fs, journal_ino, &inode)))
|
||||||
goto errout;
|
goto errout;
|
||||||
|
@ -430,6 +425,13 @@ int ext2fs_default_journal_size(__u64 num_blocks)
|
||||||
return 32768;
|
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
|
* 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;
|
struct stat st;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
char buf[1024];
|
char buf[SUPERBLOCK_SIZE];
|
||||||
journal_superblock_t *jsb;
|
journal_superblock_t *jsb;
|
||||||
int start;
|
int start;
|
||||||
__u32 i, nr_users;
|
__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 */
|
return EXT2_ET_JOURNAL_NOT_BLOCK; /* Must be a block device */
|
||||||
|
|
||||||
/* Get the journal superblock */
|
/* Get the journal superblock */
|
||||||
start = 1;
|
start = ext2fs_journal_sb_start(journal_dev->blocksize);
|
||||||
if (journal_dev->blocksize == 1024)
|
if ((retval = io_channel_read_blk64(journal_dev->io, start,
|
||||||
start++;
|
-SUPERBLOCK_SIZE,
|
||||||
if ((retval = io_channel_read_blk64(journal_dev->io, start, -1024,
|
|
||||||
buf)))
|
buf)))
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
@ -479,7 +480,8 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Writeback the journal superblock */
|
/* 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;
|
return retval;
|
||||||
|
|
||||||
fs->super->s_journal_inum = 0;
|
fs->super->s_journal_inum = 0;
|
||||||
|
@ -632,7 +634,7 @@ main(int argc, char **argv)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = ext2fs_add_journal_inode(fs, 1024, 0);
|
retval = ext2fs_add_journal_inode(fs, JFS_MIN_JOURNAL_BLOCKS, 0);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
com_err(argv[0], retval, "while adding journal to %s",
|
com_err(argv[0], retval, "while adding journal to %s",
|
||||||
device_name);
|
device_name);
|
||||||
|
|
|
@ -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 errcode_t nt_flush(io_channel channel);
|
||||||
|
|
||||||
static struct struct_io_manager struct_nt_manager = {
|
static struct struct_io_manager struct_nt_manager = {
|
||||||
EXT2_ET_MAGIC_IO_MANAGER,
|
.magic = EXT2_ET_MAGIC_IO_MANAGER,
|
||||||
"NT I/O Manager",
|
.name = "NT I/O Manager",
|
||||||
nt_open,
|
.open = nt_open,
|
||||||
nt_close,
|
.close = nt_close,
|
||||||
nt_set_blksize,
|
.set_blksize = nt_set_blksize,
|
||||||
nt_read_blk,
|
.read_blk = nt_read_blk,
|
||||||
nt_write_blk,
|
.write_blk = nt_write_blk,
|
||||||
nt_flush
|
.flush = nt_flush
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// function to get API
|
// function to get API
|
||||||
//
|
//
|
||||||
|
|
|
@ -133,12 +133,9 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
|
||||||
dindir_dirty = inode_dirty = 1;
|
dindir_dirty = inode_dirty = 1;
|
||||||
inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
|
inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
|
||||||
inode_size *= fs->blocksize;
|
inode_size *= fs->blocksize;
|
||||||
inode.i_size = inode_size & 0xFFFFFFFF;
|
retval = ext2fs_inode_size_set(fs, &inode, inode_size);
|
||||||
inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
|
if (retval)
|
||||||
if(inode.i_size_high) {
|
goto out_free;
|
||||||
sb->s_feature_ro_compat |=
|
|
||||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
|
|
||||||
}
|
|
||||||
inode.i_ctime = fs->now ? fs->now : time(0);
|
inode.i_ctime = fs->now ? fs->now : time(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,8 +271,8 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
|
||||||
}
|
}
|
||||||
blk = (fs->image_header->offset_blockmap /
|
blk = (fs->image_header->offset_blockmap /
|
||||||
fs->blocksize);
|
fs->blocksize);
|
||||||
blk_cnt = (blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) *
|
blk_cnt = EXT2_GROUPS_TO_CLUSTERS(fs->super,
|
||||||
fs->group_desc_count;
|
fs->group_desc_count);
|
||||||
while (block_nbytes > 0) {
|
while (block_nbytes > 0) {
|
||||||
retval = io_channel_read_blk64(fs->image_io, blk++,
|
retval = io_channel_read_blk64(fs->image_io, blk++,
|
||||||
1, block_bitmap);
|
1, block_bitmap);
|
||||||
|
|
|
@ -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;
|
inode.i_uid = inode.i_gid = 0;
|
||||||
ext2fs_iblk_set(fs, &inode, fastlink ? 0 : 1);
|
ext2fs_iblk_set(fs, &inode, fastlink ? 0 : 1);
|
||||||
inode.i_links_count = 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() */
|
/* The time fields are set by ext2fs_write_new_inode() */
|
||||||
|
|
||||||
if (fastlink) {
|
if (fastlink) {
|
||||||
|
|
|
@ -487,20 +487,20 @@ static errcode_t test_discard(io_channel channel, unsigned long long block,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct struct_io_manager struct_test_manager = {
|
static struct struct_io_manager struct_test_manager = {
|
||||||
EXT2_ET_MAGIC_IO_MANAGER,
|
.magic = EXT2_ET_MAGIC_IO_MANAGER,
|
||||||
"Test I/O Manager",
|
.name = "Test I/O Manager",
|
||||||
test_open,
|
.open = test_open,
|
||||||
test_close,
|
.close = test_close,
|
||||||
test_set_blksize,
|
.set_blksize = test_set_blksize,
|
||||||
test_read_blk,
|
.read_blk = test_read_blk,
|
||||||
test_write_blk,
|
.write_blk = test_write_blk,
|
||||||
test_flush,
|
.flush = test_flush,
|
||||||
test_write_byte,
|
.write_byte = test_write_byte,
|
||||||
test_set_option,
|
.set_option = test_set_option,
|
||||||
test_get_stats,
|
.get_stats = test_get_stats,
|
||||||
test_read_blk64,
|
.read_blk64 = test_read_blk64,
|
||||||
test_write_blk64,
|
.write_blk64 = test_write_blk64,
|
||||||
test_discard,
|
.discard = test_discard,
|
||||||
};
|
};
|
||||||
|
|
||||||
io_manager test_io_manager = &struct_test_manager;
|
io_manager test_io_manager = &struct_test_manager;
|
||||||
|
|
|
@ -588,19 +588,19 @@ static errcode_t undo_get_stats(io_channel channel, io_stats *stats)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct struct_io_manager struct_undo_manager = {
|
static struct struct_io_manager struct_undo_manager = {
|
||||||
EXT2_ET_MAGIC_IO_MANAGER,
|
.magic = EXT2_ET_MAGIC_IO_MANAGER,
|
||||||
"Undo I/O Manager",
|
.name = "Undo I/O Manager",
|
||||||
undo_open,
|
.open = undo_open,
|
||||||
undo_close,
|
.close = undo_close,
|
||||||
undo_set_blksize,
|
.set_blksize = undo_set_blksize,
|
||||||
undo_read_blk,
|
.read_blk = undo_read_blk,
|
||||||
undo_write_blk,
|
.write_blk = undo_write_blk,
|
||||||
undo_flush,
|
.flush = undo_flush,
|
||||||
undo_write_byte,
|
.write_byte = undo_write_byte,
|
||||||
undo_set_option,
|
.set_option = undo_set_option,
|
||||||
undo_get_stats,
|
.get_stats = undo_get_stats,
|
||||||
undo_read_blk64,
|
.read_blk64 = undo_read_blk64,
|
||||||
undo_write_blk64,
|
.write_blk64 = undo_write_blk64,
|
||||||
};
|
};
|
||||||
|
|
||||||
io_manager undo_io_manager = &struct_undo_manager;
|
io_manager undo_io_manager = &struct_undo_manager;
|
||||||
|
|
|
@ -923,20 +923,20 @@ unimplemented:
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct struct_io_manager struct_unix_manager = {
|
static struct struct_io_manager struct_unix_manager = {
|
||||||
EXT2_ET_MAGIC_IO_MANAGER,
|
.magic = EXT2_ET_MAGIC_IO_MANAGER,
|
||||||
"Unix I/O Manager",
|
.name = "Unix I/O Manager",
|
||||||
unix_open,
|
.open = unix_open,
|
||||||
unix_close,
|
.close = unix_close,
|
||||||
unix_set_blksize,
|
.set_blksize = unix_set_blksize,
|
||||||
unix_read_blk,
|
.read_blk = unix_read_blk,
|
||||||
unix_write_blk,
|
.write_blk = unix_write_blk,
|
||||||
unix_flush,
|
.flush = unix_flush,
|
||||||
unix_write_byte,
|
.write_byte = unix_write_byte,
|
||||||
unix_set_option,
|
.set_option = unix_set_option,
|
||||||
unix_get_stats,
|
.get_stats = unix_get_stats,
|
||||||
unix_read_blk64,
|
.read_blk64 = unix_read_blk64,
|
||||||
unix_write_blk64,
|
.write_blk64 = unix_write_blk64,
|
||||||
unix_discard,
|
.discard = unix_discard,
|
||||||
};
|
};
|
||||||
|
|
||||||
io_manager unix_io_manager = &struct_unix_manager;
|
io_manager unix_io_manager = &struct_unix_manager;
|
||||||
|
|
|
@ -580,7 +580,6 @@ out:
|
||||||
errcode_t quota_compare_and_update(quota_ctx_t qctx, int qtype,
|
errcode_t quota_compare_and_update(quota_ctx_t qctx, int qtype,
|
||||||
int *usage_inconsistent)
|
int *usage_inconsistent)
|
||||||
{
|
{
|
||||||
ext2_filsys fs = qctx->fs;
|
|
||||||
struct quota_handle qh;
|
struct quota_handle qh;
|
||||||
struct scan_dquots_data scan_data;
|
struct scan_dquots_data scan_data;
|
||||||
struct dquot *dq;
|
struct dquot *dq;
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <limits.h> /* for PATH_MAX */
|
#include <limits.h> /* for PATH_MAX */
|
||||||
|
#ifdef HAVE_ATTR_XATTR_H
|
||||||
|
#include <attr/xattr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "create_inode.h"
|
#include "create_inode.h"
|
||||||
|
|
||||||
|
@ -103,6 +106,94 @@ static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t cwd,
|
||||||
return retval;
|
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 */
|
/* 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,
|
errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
|
||||||
struct stat *st)
|
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 =
|
inode.i_atime = inode.i_ctime = inode.i_mtime =
|
||||||
fs->now ? fs->now : time(0);
|
fs->now ? fs->now : time(0);
|
||||||
inode.i_links_count = 1;
|
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,
|
if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
|
||||||
EXT4_FEATURE_INCOMPAT_INLINE_DATA)) {
|
EXT4_FEATURE_INCOMPAT_INLINE_DATA)) {
|
||||||
inode.i_flags |= EXT4_INLINE_DATA_FL;
|
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;
|
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 */
|
/* Save the hardlink ino */
|
||||||
if (save_inode) {
|
if (save_inode) {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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_physical = block * st->st_blksize;
|
||||||
fm_ext.fe_length = 0;
|
fm_ext.fe_length = 0;
|
||||||
(*num_extents)++;
|
(*num_extents)++;
|
||||||
} else if (verbose && last_block && (block != last_block + 1)) {
|
} else if (last_block && (block != last_block + 1)) {
|
||||||
printf("Discontinuity: Block %ld is at %lu (was %lu)\n",
|
if (verbose)
|
||||||
i, block, last_block + 1);
|
printf("Discontinuity: Block %ld is at %lu (was "
|
||||||
|
"%lu)\n", i, block, last_block + 1);
|
||||||
(*num_extents)++;
|
(*num_extents)++;
|
||||||
}
|
}
|
||||||
fm_ext.fe_length += st->st_blksize;
|
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 int frag_report(const char *filename)
|
||||||
{
|
{
|
||||||
static struct statfs fsinfo;
|
static struct statfs fsinfo;
|
||||||
|
static unsigned int blksize;
|
||||||
ext2fs_struct_stat st;
|
ext2fs_struct_stat st;
|
||||||
int blk_shift;
|
int blk_shift;
|
||||||
long fd;
|
long fd;
|
||||||
|
@ -380,22 +382,22 @@ static int frag_report(const char *filename)
|
||||||
#endif
|
#endif
|
||||||
rc = -errno;
|
rc = -errno;
|
||||||
perror("stat");
|
perror("stat");
|
||||||
close(fd);
|
goto out_close;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_device != st.st_dev) {
|
if (last_device != st.st_dev) {
|
||||||
if (fstatfs(fd, &fsinfo) < 0) {
|
if (fstatfs(fd, &fsinfo) < 0) {
|
||||||
rc = -errno;
|
rc = -errno;
|
||||||
perror("fstatfs");
|
perror("fstatfs");
|
||||||
close(fd);
|
goto out_close;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
if (ioctl(fd, FIGETBSZ, &blksize) < 0)
|
||||||
|
blksize = fsinfo.f_bsize;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("Filesystem type is: %lx\n",
|
printf("Filesystem type is: %lx\n",
|
||||||
(unsigned long)fsinfo.f_type);
|
(unsigned long)fsinfo.f_type);
|
||||||
}
|
}
|
||||||
st.st_blksize = fsinfo.f_bsize;
|
st.st_blksize = blksize;
|
||||||
if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
|
if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if (!(flags & EXT4_EXTENTS_FL) &&
|
if (!(flags & EXT4_EXTENTS_FL) &&
|
||||||
|
@ -404,13 +406,13 @@ static int frag_report(const char *filename)
|
||||||
is_ext2++;
|
is_ext2++;
|
||||||
|
|
||||||
if (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)
|
if (verbose && last_device != st.st_dev)
|
||||||
printf("Filesystem cylinder groups approximately %ld\n",
|
printf("Filesystem cylinder groups approximately %ld\n",
|
||||||
cylgroups);
|
cylgroups);
|
||||||
|
|
||||||
data_blocks_per_cyl = fsinfo.f_bsize * 8 -
|
data_blocks_per_cyl = blksize * 8 -
|
||||||
(fsinfo.f_files / 8 / cylgroups) - 3;
|
(fsinfo.f_files / 8 / cylgroups) - 3;
|
||||||
}
|
}
|
||||||
last_device = st.st_dev;
|
last_device = st.st_dev;
|
||||||
|
@ -419,11 +421,11 @@ static int frag_report(const char *filename)
|
||||||
if (width > physical_width)
|
if (width > physical_width)
|
||||||
physical_width = 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)
|
if (blocksize != 0)
|
||||||
blk_shift = int_log2(blocksize);
|
blk_shift = int_log2(blocksize);
|
||||||
else
|
else
|
||||||
blk_shift = int_log2(fsinfo.f_bsize);
|
blk_shift = int_log2(blksize);
|
||||||
|
|
||||||
width = int_log10(numblocks);
|
width = int_log10(numblocks);
|
||||||
if (width > logical_width)
|
if (width > logical_width)
|
||||||
|
@ -431,7 +433,7 @@ static int frag_report(const char *filename)
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("File size of %s is %llu (%llu block%s of %d bytes)\n",
|
printf("File size of %s is %llu (%llu block%s of %d bytes)\n",
|
||||||
filename, (unsigned long long)st.st_size,
|
filename, (unsigned long long)st.st_size,
|
||||||
numblocks * fsinfo.f_bsize >> blk_shift,
|
numblocks * blksize >> blk_shift,
|
||||||
numblocks == 1 ? "" : "s", 1 << blk_shift);
|
numblocks == 1 ? "" : "s", 1 << blk_shift);
|
||||||
|
|
||||||
if (!force_bmap) {
|
if (!force_bmap) {
|
||||||
|
@ -439,7 +441,7 @@ static int frag_report(const char *filename)
|
||||||
expected = 0;
|
expected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0) {
|
if (force_bmap || rc < 0) {
|
||||||
expected = filefrag_fibmap(fd, blk_shift, &num_extents,
|
expected = filefrag_fibmap(fd, blk_shift, &num_extents,
|
||||||
&st, numblocks, is_ext2);
|
&st, numblocks, is_ext2);
|
||||||
if (expected < 0) {
|
if (expected < 0) {
|
||||||
|
|
|
@ -357,8 +357,9 @@ static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout;
|
goto errout;
|
||||||
size = (__u64) count * fs->blocksize;
|
size = (__u64) count * fs->blocksize;
|
||||||
inode.i_size = size & 0xffffffff;
|
retval = ext2fs_inode_size_set(fs, &inode, size);
|
||||||
inode.i_size_high = (size >> 32);
|
if (retval)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
retval = ext2fs_write_new_inode(fs, *ino, &inode);
|
retval = ext2fs_write_new_inode(fs, *ino, &inode);
|
||||||
if (retval)
|
if (retval)
|
||||||
|
@ -468,7 +469,7 @@ errcode_t mk_hugefiles(ext2_filsys fs, const char *device_name)
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
ext2_ino_t dir;
|
ext2_ino_t dir;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
blk64_t fs_blocks, part_offset;
|
blk64_t fs_blocks, part_offset = 0;
|
||||||
unsigned long align;
|
unsigned long align;
|
||||||
int d, dsize;
|
int d, dsize;
|
||||||
char *t;
|
char *t;
|
||||||
|
|
168
misc/tune2fs.c
168
misc/tune2fs.c
|
@ -180,6 +180,50 @@ static __u32 clear_ok_features[3] = {
|
||||||
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
|
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
|
* Remove an external journal from the filesystem
|
||||||
*/
|
*/
|
||||||
|
@ -187,12 +231,13 @@ static int remove_journal_device(ext2_filsys fs)
|
||||||
{
|
{
|
||||||
char *journal_path;
|
char *journal_path;
|
||||||
ext2_filsys jfs;
|
ext2_filsys jfs;
|
||||||
char buf[1024];
|
char buf[SUPERBLOCK_SIZE];
|
||||||
journal_superblock_t *jsb;
|
journal_superblock_t *jsb;
|
||||||
int i, nr_users;
|
int i, nr_users;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
int commit_remove_journal = 0;
|
int commit_remove_journal = 0;
|
||||||
io_manager io_ptr;
|
io_manager io_ptr;
|
||||||
|
int start;
|
||||||
|
|
||||||
if (f_flag)
|
if (f_flag)
|
||||||
commit_remove_journal = 1; /* force removal even if error */
|
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"));
|
_("while trying to open external journal"));
|
||||||
goto no_valid_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 = get_journal_sb(jfs, buf))) {
|
||||||
if ((retval = io_channel_read_blk64(jfs->io, 1, -1024, buf))) {
|
if (retval == EXT2_ET_UNSUPP_FEATURE)
|
||||||
com_err(program_name, retval, "%s",
|
fprintf(stderr, _("%s is not a journal device.\n"),
|
||||||
_("while reading journal superblock"));
|
journal_path);
|
||||||
goto no_valid_journal;
|
goto no_valid_journal;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsb = (journal_superblock_t *) buf;
|
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 */
|
/* Find the filesystem UUID */
|
||||||
nr_users = ntohl(jsb->s_nr_users);
|
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)
|
if (!journal_user(fs->super->s_uuid, jsb->s_users, nr_users)) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i >= nr_users) {
|
|
||||||
fputs(_("Filesystem's UUID not found on journal device.\n"),
|
fputs(_("Filesystem's UUID not found on journal device.\n"),
|
||||||
stderr);
|
stderr);
|
||||||
commit_remove_journal = 1;
|
commit_remove_journal = 1;
|
||||||
|
@ -261,7 +291,8 @@ static int remove_journal_device(ext2_filsys fs)
|
||||||
jsb->s_nr_users = htonl(nr_users);
|
jsb->s_nr_users = htonl(nr_users);
|
||||||
|
|
||||||
/* Write back the journal superblock */
|
/* 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,
|
com_err(program_name, retval,
|
||||||
"while writing journal superblock.");
|
"while writing journal superblock.");
|
||||||
goto no_valid_journal;
|
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;
|
blk64_t start_blk, end_blk;
|
||||||
start_blk = fs->super->s_first_data_block +
|
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
|
* 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
|
* 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;
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
|
@ -2691,6 +2784,8 @@ retry_open:
|
||||||
if (U_flag) {
|
if (U_flag) {
|
||||||
int set_csum = 0;
|
int set_csum = 0;
|
||||||
dgrp_t i;
|
dgrp_t i;
|
||||||
|
char buf[SUPERBLOCK_SIZE];
|
||||||
|
char old_uuid[UUID_SIZE];
|
||||||
|
|
||||||
if (ext2fs_has_group_desc_csum(fs)) {
|
if (ext2fs_has_group_desc_csum(fs)) {
|
||||||
/*
|
/*
|
||||||
|
@ -2717,6 +2812,8 @@ retry_open:
|
||||||
if (i >= fs->group_desc_count)
|
if (i >= fs->group_desc_count)
|
||||||
set_csum = 1;
|
set_csum = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(old_uuid, sb->s_uuid, UUID_SIZE);
|
||||||
if ((strcasecmp(new_UUID, "null") == 0) ||
|
if ((strcasecmp(new_UUID, "null") == 0) ||
|
||||||
(strcasecmp(new_UUID, "clear") == 0)) {
|
(strcasecmp(new_UUID, "clear") == 0)) {
|
||||||
uuid_clear(sb->s_uuid);
|
uuid_clear(sb->s_uuid);
|
||||||
|
@ -2736,6 +2833,29 @@ retry_open:
|
||||||
ext2fs_group_desc_csum_set(fs, i);
|
ext2fs_group_desc_csum_set(fs, i);
|
||||||
fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
|
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);
|
ext2fs_mark_super_dirty(fs);
|
||||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
|
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
|
||||||
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
|
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
|
||||||
|
|
|
@ -36,6 +36,7 @@ extern int optind;
|
||||||
#include "uuid/uuid.h"
|
#include "uuid/uuid.h"
|
||||||
#include "uuid/uuidd.h"
|
#include "uuid/uuidd.h"
|
||||||
#include "nls-enable.h"
|
#include "nls-enable.h"
|
||||||
|
#include "ext2fs/ext2fs.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define CODE_ATTR(x) __attribute__(x)
|
#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;
|
uuid_t uu;
|
||||||
mode_t save_umask;
|
mode_t save_umask;
|
||||||
char reply_buf[1024], *cp;
|
char reply_buf[1024], *cp;
|
||||||
char op, str[37];
|
char op, str[UUID_STR_SIZE];
|
||||||
int i, s, ns, len, num;
|
int i, s, ns, len, num;
|
||||||
int fd_pidfile, ret;
|
int fd_pidfile, ret;
|
||||||
|
|
||||||
|
|
|
@ -318,6 +318,7 @@ int main (int argc, char ** argv)
|
||||||
printf("%s", _("Couldn't find valid filesystem superblock.\n"));
|
printf("%s", _("Couldn't find valid filesystem superblock.\n"));
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
|
||||||
|
|
||||||
if (!(mount_flags & EXT2_MF_MOUNTED)) {
|
if (!(mount_flags & EXT2_MF_MOUNTED)) {
|
||||||
if (!force && ((fs->super->s_lastcheck < fs->super->s_mtime) ||
|
if (!force && ((fs->super->s_lastcheck < fs->super->s_mtime) ||
|
||||||
|
|
|
@ -435,8 +435,7 @@ retry:
|
||||||
fs->inode_map);
|
fs->inode_map);
|
||||||
if (retval) goto errout;
|
if (retval) goto errout;
|
||||||
|
|
||||||
real_end = (((blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super) *
|
real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 +
|
||||||
fs->group_desc_count)) - 1 +
|
|
||||||
fs->super->s_first_data_block;
|
fs->super->s_first_data_block;
|
||||||
retval = ext2fs_resize_block_bitmap2(new_size - 1,
|
retval = ext2fs_resize_block_bitmap2(new_size - 1,
|
||||||
real_end, fs->block_map);
|
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;
|
fs->super->s_free_inodes_count;
|
||||||
blks_needed = ext2fs_div_ceil(inode_count,
|
blks_needed = ext2fs_div_ceil(inode_count,
|
||||||
fs->super->s_inodes_per_group) *
|
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,
|
groups = ext2fs_div64_ceil(blks_needed,
|
||||||
EXT2_BLOCKS_PER_GROUP(fs->super));
|
EXT2_BLOCKS_PER_GROUP(fs->super));
|
||||||
#ifdef RESIZE2FS_DEBUG
|
#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
|
* figure out how many data blocks we have given the number of groups
|
||||||
* we need for our inodes
|
* 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;
|
last_start = 0;
|
||||||
for (grp = 0; grp < flex_groups; grp++) {
|
for (grp = 0; grp < flex_groups; grp++) {
|
||||||
overhead = calc_group_overhead(fs, grp, old_desc_blocks);
|
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,
|
extra_grps = ext2fs_div64_ceil(remainder,
|
||||||
EXT2_BLOCKS_PER_GROUP(fs->super));
|
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 */
|
/* ok we have to account for the last group */
|
||||||
overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
|
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
|
* blocks needed to handle the group descriptor metadata+data
|
||||||
* that we need
|
* 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;
|
blks_needed += overhead;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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:
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
test alignment problems with bigalloc clusters
|
||||||
|
|
|
@ -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
|
|
@ -2,11 +2,6 @@ Pass 1: Checking inodes, blocks, and sizes
|
||||||
Inode 12, i_size is 61440, should be 4398050758656. Fix? yes
|
Inode 12, i_size is 61440, should be 4398050758656. Fix? yes
|
||||||
|
|
||||||
Pass 2: Checking directory structure
|
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 3: Checking directory connectivity
|
||||||
Pass 4: Checking reference counts
|
Pass 4: Checking reference counts
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
|
|
|
@ -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
|
|
@ -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.
|
@ -0,0 +1 @@
|
||||||
|
rebuild a directory with corrupt dirent tail
|
|
@ -12,7 +12,7 @@ Relocate? yes
|
||||||
../e2fsck/e2fsck: A block group is missing an inode table while reading bad blocks inode
|
../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...
|
This doesn't bode well, but we'll try to go on...
|
||||||
Pass 1: Checking inodes, blocks, and sizes
|
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...
|
Restarting e2fsck from the beginning...
|
||||||
Pass 1: Checking inodes, blocks, and sizes
|
Pass 1: Checking inodes, blocks, and sizes
|
||||||
Root inode is not a directory. Clear? yes
|
Root inode is not a directory. Clear? yes
|
||||||
|
|
|
@ -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
|
|
@ -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.
|
@ -0,0 +1 @@
|
||||||
|
force fsck to rebuild a corrupted rootdir w/ metadata_csum
|
|
@ -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
|
|
@ -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
|
|
@ -64,8 +64,8 @@ then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
|
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
|
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
then
|
then
|
||||||
dumpe2fs $TMPFILE >> $LOG
|
dumpe2fs $TMPFILE >> $LOG
|
||||||
return 1
|
return 1
|
||||||
|
@ -94,8 +94,8 @@ then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
|
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
|
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
then
|
then
|
||||||
dumpe2fs $TMPFILE >> $LOG
|
dumpe2fs $TMPFILE >> $LOG
|
||||||
return 1
|
return 1
|
||||||
|
@ -119,8 +119,8 @@ then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
|
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
|
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
then
|
then
|
||||||
dumpe2fs $TMPFILE >> $LOG
|
dumpe2fs $TMPFILE >> $LOG
|
||||||
return 1
|
return 1
|
||||||
|
@ -144,8 +144,8 @@ then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $FSCK -fp $TMPFILE >> $LOG 2>&1
|
echo $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
if ! $FSCK -fp $TMPFILE >> $LOG 2>&1
|
if ! $FSCK -fy $TMPFILE >> $LOG 2>&1
|
||||||
then
|
then
|
||||||
dumpe2fs $TMPFILE >> $LOG
|
dumpe2fs $TMPFILE >> $LOG
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
/In file included from/d
|
/In file included from/d
|
||||||
/In function `.*':/d
|
/In function `.*':/d
|
||||||
/zero-length format string/d
|
/zero-length format string/d
|
||||||
/warning: missing initializer/d
|
|
||||||
/warning: (near initialization for/d
|
/warning: (near initialization for/d
|
||||||
/^[ ]*from/d
|
/^[ ]*from/d
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
Loading…
Reference in New Issue