mirror of
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
synced 2024-11-23 18:14:25 +08:00
AOSP: e2fsck: Add an extended option for unsharing blocks.
Add an -E unshare_blocks flag for unsharing blocks that were created for a filesystem with block sharing enabled. If the filesystem does not have this feature enabled, the flag has no effect. If the filesystem does not have free space, e2fsck will error. Signed-off-by: Theodore Ts'o <tytso@mit.edu> Google-Bug-Id: 64109868 Test: f_unshare_blocks_no_space, f_unshare_blocks_ok Change-Id: I8821353e9e6200c6c0c71dd22f4f43d796fc720c From AOSP commit: 8ba190e3135d61501d3a694b6960c2fbee98e7a6
This commit is contained in:
parent
9c5413b1ae
commit
91327df457
@ -266,6 +266,15 @@ Convert block-mapped files to extent-mapped files.
|
||||
Only fix damaged metadata; do not optimize htree directories or compress
|
||||
extent trees. This option is incompatible with the -D and -E bmap2extent
|
||||
options.
|
||||
.TP
|
||||
.BI unshare_blocks
|
||||
If the filesystem has shared blocks, with the shared blocks read-only feature
|
||||
enabled, then this will unshare all shared blocks and unset the read-only
|
||||
feature bit. If there is not enough free space then the operation will fail.
|
||||
If the filesystem does not have the read-only feature bit, but has shared
|
||||
blocks anyway, then this option will have no effect. Note when using this
|
||||
option, if there is no free space to clone blocks, there is no prompt to
|
||||
delete files and instead the operation will fail.
|
||||
.RE
|
||||
.TP
|
||||
.B \-f
|
||||
|
@ -172,6 +172,7 @@ struct resource_track {
|
||||
#define E2F_OPT_FIXES_ONLY 0x8000 /* skip all optimizations */
|
||||
#define E2F_OPT_NOOPT_EXTENTS 0x10000 /* don't optimize extents */
|
||||
#define E2F_OPT_ICOUNT_FULLMAP 0x20000 /* use an array for inode counts */
|
||||
#define E2F_OPT_UNSHARE_BLOCKS 0x40000
|
||||
|
||||
/*
|
||||
* E2fsck flags
|
||||
|
@ -2261,8 +2261,10 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
|
||||
clear_problem_context(&pctx);
|
||||
|
||||
if (ext2fs_fast_test_block_bitmap2(ctx->block_found_map, block)) {
|
||||
if (ext2fs_has_feature_shared_blocks(ctx->fs->super))
|
||||
if (ext2fs_has_feature_shared_blocks(ctx->fs->super) &&
|
||||
!(ctx->options & E2F_OPT_UNSHARE_BLOCKS)) {
|
||||
return;
|
||||
}
|
||||
if (!ctx->block_dup_map) {
|
||||
pctx.errcode = e2fsck_allocate_block_bitmap(ctx->fs,
|
||||
_("multiply claimed block map"),
|
||||
|
@ -245,6 +245,24 @@ void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
|
||||
pass1d(ctx, block_buf);
|
||||
print_resource_track(ctx, "Pass 1d", &rtrack, ctx->fs->io);
|
||||
|
||||
if (ext2fs_has_feature_shared_blocks(ctx->fs->super) &&
|
||||
(ctx->options & E2F_OPT_UNSHARE_BLOCKS)) {
|
||||
/*
|
||||
* If we successfully managed to unshare all blocks, unset the
|
||||
* shared block feature.
|
||||
*/
|
||||
blk64_t next;
|
||||
int result = ext2fs_find_first_set_block_bitmap2(
|
||||
ctx->block_dup_map,
|
||||
ctx->fs->super->s_first_data_block,
|
||||
ext2fs_blocks_count(ctx->fs->super) - 1,
|
||||
&next);
|
||||
if (result == ENOENT) {
|
||||
ext2fs_clear_feature_shared_blocks(ctx->fs->super);
|
||||
ext2fs_mark_super_dirty(ctx->fs);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Time to free all of the accumulated data structures that we
|
||||
* don't need anymore.
|
||||
@ -582,14 +600,21 @@ static void pass1d(e2fsck_t ctx, char *block_buf)
|
||||
fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
|
||||
continue;
|
||||
}
|
||||
if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
|
||||
if ((ctx->options & E2F_OPT_UNSHARE_BLOCKS) ||
|
||||
fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
|
||||
pctx.errcode = clone_file(ctx, ino, p, block_buf);
|
||||
if (pctx.errcode)
|
||||
fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
|
||||
/*
|
||||
* Note: When unsharing blocks, we don't prompt to delete
|
||||
* files. If the clone operation fails than the unshare
|
||||
* operation should fail too.
|
||||
*/
|
||||
if (!(ctx->options & E2F_OPT_UNSHARE_BLOCKS) &&
|
||||
fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
|
||||
delete_file(ctx, ino, p, block_buf);
|
||||
else
|
||||
ext2fs_unmark_valid(fs);
|
||||
@ -820,6 +845,13 @@ static int clone_file_block(ext2_filsys fs,
|
||||
cs->errcode = retval;
|
||||
return BLOCK_ABORT;
|
||||
}
|
||||
if (ext2fs_has_feature_shared_blocks(fs->super)) {
|
||||
/*
|
||||
* Update the block stats so we don't get a prompt to fix block
|
||||
* counts in the final pass.
|
||||
*/
|
||||
ext2fs_block_alloc_stats2(fs, new_block, +1);
|
||||
}
|
||||
cluster_alloc_ok:
|
||||
cs->alloc_block = new_block;
|
||||
|
||||
|
@ -740,6 +740,9 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
|
||||
} else if (strcmp(token, "fixes_only") == 0) {
|
||||
ctx->options |= E2F_OPT_FIXES_ONLY;
|
||||
continue;
|
||||
} else if (strcmp(token, "unshare_blocks") == 0) {
|
||||
ctx->options |= E2F_OPT_UNSHARE_BLOCKS;
|
||||
continue;
|
||||
} else {
|
||||
fprintf(stderr, _("Unknown extended option: %s\n"),
|
||||
token);
|
||||
@ -764,6 +767,7 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
|
||||
fputs("\tno_inode_count_fullmap\n", stderr);
|
||||
fputs(_("\treadahead_kb=<buffer size>\n"), stderr);
|
||||
fputs("\tbmap2extent\n", stderr);
|
||||
fputs("\tunshare_blocks\n", stderr);
|
||||
fputs("\tfixes_only\n", stderr);
|
||||
fputc('\n', stderr);
|
||||
exit(1);
|
||||
|
136
tests/f_unshare_blocks_no_space/expect.1
Normal file
136
tests/f_unshare_blocks_no_space/expect.1
Normal file
@ -0,0 +1,136 @@
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
|
||||
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 24: 10
|
||||
Multiply-claimed block(s) in inode 25: 9 9 9--10
|
||||
Multiply-claimed block(s) in inode 26: 9 9 9--10
|
||||
Multiply-claimed block(s) in inode 27: 9 9 9--10
|
||||
Multiply-claimed block(s) in inode 28: 9 9 9--10
|
||||
Multiply-claimed block(s) in inode 29: 9 9 9--10
|
||||
Multiply-claimed block(s) in inode 30: 9 9 9--10
|
||||
Multiply-claimed block(s) in inode 31: 9 9 9--10
|
||||
Multiply-claimed block(s) in inode 32: 9 9 9--10
|
||||
Pass 1C: Scanning directories for inodes with multiply-claimed blocks
|
||||
Pass 1D: Reconciling multiply-claimed blocks
|
||||
(There are 9 inodes containing multiply-claimed blocks.)
|
||||
|
||||
File /file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 1 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
File /file18.txt (inode #32, mod time Mon Mar 5 20:30:04 2018)
|
||||
has 4 multiply-claimed block(s), shared with 8 file(s):
|
||||
/file6.txt (inode #31, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file12.txt (inode #30, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file3.txt (inode #29, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file9.txt (inode #28, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file8.txt (inode #27, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file15.txt (inode #26, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file20.txt (inode #25, mod time Mon Mar 5 20:30:04 2018)
|
||||
/file4.txt (inode #24, mod time Mon Mar 5 20:30:04 2018)
|
||||
clone_file: Could not allocate block in ext2 filesystem returned from clone_file_block
|
||||
Couldn't clone file: Could not allocate block in ext2 filesystem
|
||||
Pass 2: Checking directory structure
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
|
||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||
|
||||
test_filesys: ********** WARNING: Filesystem still has errors **********
|
||||
|
||||
test_filesys: 32/32 files (34.4% non-contiguous), 64/64 blocks
|
||||
Exit status is 4
|
7
tests/f_unshare_blocks_no_space/expect.2
Normal file
7
tests/f_unshare_blocks_no_space/expect.2
Normal file
@ -0,0 +1,7 @@
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Pass 2: Checking directory structure
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
test_filesys: 32/32 files (34.4% non-contiguous), 64/64 blocks
|
||||
Exit status is 1
|
BIN
tests/f_unshare_blocks_no_space/image.gz
Normal file
BIN
tests/f_unshare_blocks_no_space/image.gz
Normal file
Binary file not shown.
1
tests/f_unshare_blocks_no_space/name
Normal file
1
tests/f_unshare_blocks_no_space/name
Normal file
@ -0,0 +1 @@
|
||||
unshare blocks should fail with no free space
|
2
tests/f_unshare_blocks_no_space/script
Normal file
2
tests/f_unshare_blocks_no_space/script
Normal file
@ -0,0 +1,2 @@
|
||||
FSCK_OPT="-yf -E unshare_blocks"
|
||||
. $cmd_dir/run_e2fsck
|
26
tests/f_unshare_blocks_ok/expect.1
Normal file
26
tests/f_unshare_blocks_ok/expect.1
Normal file
@ -0,0 +1,26 @@
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
|
||||
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: 9
|
||||
Multiply-claimed block(s) in inode 13: 9
|
||||
Pass 1C: Scanning directories for inodes with multiply-claimed blocks
|
||||
Pass 1D: Reconciling multiply-claimed blocks
|
||||
(There are 2 inodes containing multiply-claimed blocks.)
|
||||
|
||||
File /file2.txt (inode #12, mod time Sat Mar 3 02:12:33 2018)
|
||||
has 1 multiply-claimed block(s), shared with 1 file(s):
|
||||
/file1.txt (inode #13, mod time Sat Mar 3 02:12:15 2018)
|
||||
File /file1.txt (inode #13, mod time Sat Mar 3 02:12:15 2018)
|
||||
has 1 multiply-claimed block(s), shared with 1 file(s):
|
||||
/file2.txt (inode #12, mod time Sat Mar 3 02:12:33 2018)
|
||||
Multiply-claimed blocks already reassigned or cloned.
|
||||
|
||||
Pass 2: Checking directory structure
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
|
||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||
test_filesys: 13/32 files (0.0% non-contiguous), 13/64 blocks
|
||||
Exit status is 0
|
7
tests/f_unshare_blocks_ok/expect.2
Normal file
7
tests/f_unshare_blocks_ok/expect.2
Normal file
@ -0,0 +1,7 @@
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Pass 2: Checking directory structure
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
test_filesys: 13/32 files (0.0% non-contiguous), 13/64 blocks
|
||||
Exit status is 0
|
BIN
tests/f_unshare_blocks_ok/image.gz
Normal file
BIN
tests/f_unshare_blocks_ok/image.gz
Normal file
Binary file not shown.
1
tests/f_unshare_blocks_ok/name
Normal file
1
tests/f_unshare_blocks_ok/name
Normal file
@ -0,0 +1 @@
|
||||
unshare blocks successfully
|
2
tests/f_unshare_blocks_ok/script
Normal file
2
tests/f_unshare_blocks_ok/script
Normal file
@ -0,0 +1,2 @@
|
||||
FSCK_OPT="-yf -E unshare_blocks"
|
||||
. $cmd_dir/run_e2fsck
|
Loading…
Reference in New Issue
Block a user