Don't skip parts of a file when calling fiemap
A mis-incremented offset in the fiemap-processing code meant that non-sparse portions of files were missed.
This commit is contained in:
@@ -140,8 +140,11 @@ void write_not_zeroes(struct client* client, uint64_t from, int len)
|
|||||||
* and memcpy being fast, rather than try to
|
* and memcpy being fast, rather than try to
|
||||||
* hand-optimized something specific.
|
* hand-optimized something specific.
|
||||||
*/
|
*/
|
||||||
if (zerobuffer[0] != 0 ||
|
|
||||||
memcmp(zerobuffer, zerobuffer + 1, blockrun - 1)) {
|
int all_zeros = (zerobuffer[0] == 0) &&
|
||||||
|
(0 == memcmp( zerobuffer, zerobuffer+1, blockrun-1 ));
|
||||||
|
|
||||||
|
if ( !all_zeros ) {
|
||||||
memcpy(client->mapped+from, zerobuffer, blockrun);
|
memcpy(client->mapped+from, zerobuffer, blockrun);
|
||||||
bitset_set_range(map, from, blockrun);
|
bitset_set_range(map, from, blockrun);
|
||||||
server_dirty(client->serve, from, blockrun);
|
server_dirty(client->serve, from, blockrun);
|
||||||
|
@@ -64,7 +64,7 @@ int build_allocation_map(struct bitset_mapping* allocation_map, int fd)
|
|||||||
struct fiemap_extent *last = &fiemap->fm_extents[
|
struct fiemap_extent *last = &fiemap->fm_extents[
|
||||||
fiemap->fm_mapped_extents-1
|
fiemap->fm_mapped_extents-1
|
||||||
];
|
];
|
||||||
offset += last->fe_logical + last->fe_length;
|
offset = last->fe_logical + last->fe_length;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
offset += fiemap->fm_length;
|
offset += fiemap->fm_length;
|
||||||
|
@@ -78,6 +78,10 @@ class Environment
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def write1( data )
|
||||||
|
@nbd1.write( 0, data )
|
||||||
|
end
|
||||||
|
|
||||||
def writefile1(data)
|
def writefile1(data)
|
||||||
@file1 = FileWriter.new(@filename1, @blocksize).write(data)
|
@file1 = FileWriter.new(@filename1, @blocksize).write(data)
|
||||||
end
|
end
|
||||||
|
@@ -129,5 +129,32 @@ class TestHappyPath < Test::Unit::TestCase
|
|||||||
assert_no_match( /^(F|E):/, stderr )
|
assert_no_match( /^(F|E):/, stderr )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def test_write_more_than_one_run
|
||||||
|
one_mb = 2**20
|
||||||
|
data = "\0" * 256 * one_mb
|
||||||
|
|
||||||
|
File.open(@env.filename1, "wb") do |f| f.write( "1" * 256 * one_mb ) end
|
||||||
|
|
||||||
|
@env.serve1
|
||||||
|
sleep 5
|
||||||
|
@env.write1( data )
|
||||||
|
@env.nbd1.can_die(0)
|
||||||
|
@env.nbd1.kill
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
File.open(@env.filename1, "rb") do |f|
|
||||||
|
while mb = f.read( one_mb )
|
||||||
|
unless "\0"*one_mb == mb
|
||||||
|
msg = "Read non-zeros after offset %x:\n"%(i * one_mb)
|
||||||
|
msg += `hexdump #{@env.filename1} | head -n5`
|
||||||
|
fail msg
|
||||||
|
end
|
||||||
|
i += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
p i
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user