Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
external_e2fsprogs
Commits
38c771d6
Commit
38c771d6
authored
11 years ago
by
Theodore Ts'o
Browse files
Options
Download
Email Patches
Plain Diff
e2image: add -c option to optimize file system copying for flash devices
Signed-off-by:
"Theodore Ts'o"
<
tytso@mit.edu
>
parent
aa2c7433
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
75 additions
and
7 deletions
+75
-7
misc/e2image.8.in
misc/e2image.8.in
+12
-3
misc/e2image.c
misc/e2image.c
+63
-4
No files found.
misc/e2image.8.in
View file @
38c771d6
...
...
@@ -8,7 +8,7 @@ e2image \- Save critical ext2/ext3/ext4 filesystem metadata to a file
.SH SYNOPSIS
.B e2image
[
.B \-rsIQ
ap
.B \-
acfp
rsIQ
]
[
.B \-o
...
...
@@ -45,7 +45,7 @@ or
options, the filesystem must be unmounted or be mounted read/only, in order
for the image file to be in a consistent state. This requirement can be
overriden using the
.B -f
.B
\
-f
option, but the resulting image file is very likely not going to be useful.
.PP
If
...
...
@@ -209,7 +209,16 @@ give an image that is suitable to use to clone the entire FS or
for backup purposes. Note that this option only works with the
raw or QCOW2 formats. The
.B \-p
switch may be given to show progress.
switch may be given to show progress. If the file system is being
cloned to a flash-based storage device (where reads are very fast and
where it is desirable to avoid unnecessary writes to reduce write wear
on the device), the
.B \-c
option which cause e2image to try reading a block from the destination
to see if it is identical to the block which
.B e2image
is about to copy. If the block is already the same, the write can be
skipped.
.PP
.SH OFFSETS
Normally a filesystem starts at the beginning of a partition, and
...
...
This diff is collapsed.
Click to expand it.
misc/e2image.c
View file @
38c771d6
...
...
@@ -68,6 +68,8 @@ static char output_is_blk;
static
blk64_t
source_offset
,
dest_offset
;
static
char
move_mode
;
static
char
show_progress
;
static
char
*
check_buf
;
static
int
skipped_blocks
;
static
blk64_t
align_offset
(
blk64_t
offset
,
unsigned
int
n
)
{
...
...
@@ -94,7 +96,8 @@ static int get_bits_from_size(size_t size)
static
void
usage
(
void
)
{
fprintf
(
stderr
,
_
(
"Usage: %s [-rsIQafp] [-o src_offset] [-O dest_offset] device image_file
\n
"
),
fprintf
(
stderr
,
_
(
"Usage: %s [-acfprsIQ] [-o src_offset] "
"[-O dest_offset]
\\\n\t
device image_file
\n
"
),
program_name
);
exit
(
1
);
}
...
...
@@ -119,6 +122,32 @@ static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
return
ret
;
}
/*
* Returns true if the block we are about to write is identical to
* what is already on the disk.
*/
static
int
check_block
(
int
fd
,
void
*
buf
,
void
*
cbuf
,
int
blocksize
)
{
char
*
cp
=
cbuf
;
int
count
=
blocksize
,
ret
;
if
(
cbuf
==
NULL
)
return
0
;
while
(
count
>
0
)
{
ret
=
read
(
fd
,
cp
,
count
);
if
(
ret
<
0
)
{
perror
(
"check_block"
);
exit
(
1
);
}
count
-=
ret
;
cp
+=
ret
;
}
ret
=
memcmp
(
buf
,
cbuf
,
blocksize
);
seek_relative
(
fd
,
-
blocksize
);
return
(
ret
==
0
)
?
1
:
0
;
}
static
void
generic_write
(
int
fd
,
void
*
buf
,
int
blocksize
,
blk64_t
block
)
{
int
count
,
free_buf
=
0
;
...
...
@@ -621,8 +650,12 @@ more_blocks:
goto
sparse_write
;
if
(
sparse
)
seek_relative
(
fd
,
sparse
);
generic_write
(
fd
,
buf
,
fs
->
blocksize
,
blk
);
sparse
=
0
;
if
(
check_block
(
fd
,
buf
,
check_buf
,
fs
->
blocksize
))
{
seek_relative
(
fd
,
fs
->
blocksize
);
skipped_blocks
++
;
}
else
generic_write
(
fd
,
buf
,
fs
->
blocksize
,
blk
);
}
else
{
sparse_write:
if
(
fd
==
1
)
{
...
...
@@ -1398,6 +1431,7 @@ int main (int argc, char ** argv)
int
fd
=
0
;
int
ret
=
0
;
int
ignore_rw_mount
=
0
;
int
check
=
0
;
struct
stat
st
;
#ifdef ENABLE_NLS
...
...
@@ -1412,7 +1446,7 @@ int main (int argc, char ** argv)
if
(
argc
&&
*
argv
)
program_name
=
*
argv
;
add_error_table
(
&
et_ext2_error_table
);
while
((
c
=
getopt
(
argc
,
argv
,
"rsIQafo:O:p"
))
!=
EOF
)
while
((
c
=
getopt
(
argc
,
argv
,
"rsIQafo:O:p
c
"
))
!=
EOF
)
switch
(
c
)
{
case
'I'
:
flags
|=
E2IMAGE_INSTALL_FLAG
;
...
...
@@ -1445,6 +1479,9 @@ int main (int argc, char ** argv)
case
'p'
:
show_progress
=
1
;
break
;
case
'c'
:
check
=
1
;
break
;
default:
usage
();
}
...
...
@@ -1522,7 +1559,7 @@ skip_device:
if
(
strcmp
(
image_fn
,
"-"
)
==
0
)
fd
=
1
;
else
{
int
o_flags
=
O_CREAT
|
O_WR
ONLY
;
int
o_flags
=
O_CREAT
|
O_
RD
WR
;
if
(
img_type
!=
E2IMAGE_RAW
)
o_flags
|=
O_TRUNC
;
...
...
@@ -1568,6 +1605,24 @@ skip_device:
goto
out
;
}
if
(
check
)
{
if
(
img_type
!=
E2IMAGE_RAW
)
{
fprintf
(
stderr
,
_
(
"The -c option only supported "
"in raw mode
\n
"
));
exit
(
1
);
}
if
(
fd
==
1
)
{
fprintf
(
stderr
,
_
(
"The -c option is not supported "
"when writing to stdout
\n
"
));
exit
(
1
);
}
retval
=
ext2fs_get_mem
(
fs
->
blocksize
,
&
check_buf
);
if
(
retval
)
{
com_err
(
program_name
,
retval
,
"while allocating check_buf"
);
exit
(
1
);
}
}
if
(
img_type
)
write_raw_image_file
(
fs
,
fd
,
img_type
,
flags
);
...
...
@@ -1575,6 +1630,10 @@ skip_device:
write_image_file
(
fs
,
fd
);
ext2fs_close
(
fs
);
if
(
check
)
printf
(
"%d blocks already contained the data to be copied.
\n
"
,
skipped_blocks
);
out:
if
(
header
)
free
(
header
);
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment