rmlint icon indicating copy to clipboard operation
rmlint copied to clipboard

--is-reflink detects EOF poorly

Open cebtenzzre opened this issue 2 years ago • 0 comments

Description

rmlint --is-reflink ignores the physical offset of the last extent in a file, as long as there are at least two extents total, even if a fix for #527 is applied.

Steps to reproduce

Build rmlint from the develop branch with _RM_OFFSET_DEBUG=1 and a fix for #527 applied.

For testcase 1, run these commands:

$ dd if=/dev/urandom of=foo bs=100K oflag=sync count=1
$ dd if=/dev/urandom of=foo bs=100K oflag=sync count=1 seek=1
$ cp --reflink foo bar
$ dd if=/dev/urandom of=bar bs=100K oflag=sync count=1 seek=1
$ filefrag -vb1 foo bar
Filesystem type is: 9123683e
File size of foo is 204800 (204800 blocks of 1 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..  102399: 694036611072..694036713471: 102400:             shared
   1:   102400..  204799: 694077128704..694077231103: 102400: 694036713472: last,eof
foo: 2 extents found
File size of bar is 204800 (204800 blocks of 1 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..  102399: 694036611072..694036713471: 102400:             shared
   1:   102400..  204799: 694103236608..694103339007: 102400: 694036713472: last,eof
bar: 2 extents found
$ cmp foo bar
foo bar differ: byte 102401, line 408
$ rmlint --is-reflink -vv foo bar
DEBUG: Testing if foo is clone of bar
DEBUG: Checking link type for foo vs bar
DEBUG: rm_offset_get_fiemap: fd=3, n_extents=1, file_offset=0
DEBUG: rm_offset_get_fiemap: fd=3, n_extents=1, file_offset=102400
DEBUG: rm_offset_get_fiemap: fd=4, n_extents=1, file_offset=0
DEBUG: rm_offset_get_fiemap: fd=4, n_extents=1, file_offset=102400
DEBUG: Offsets match at fd1=3, fd2=4, logical=0, physical=694036611072
DEBUG: Files are clones (share same data)
Link type for 'foo' and 'bar', result:
Reflink
$ echo $?
0

For testcase 2, run these commands:

$ dd if=/dev/urandom of=foo bs=100K oflag=sync count=1
$ truncate -s 200K foo
$ cp --reflink foo bar
$ filefrag -vb1 foo bar
Filesystem type is: 9123683e
File size of foo is 204800 (204800 blocks of 1 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..  102399: 676477960192..676478062591: 102400:             last,shared
foo: 1 extent found
File size of bar is 204800 (204800 blocks of 1 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..  102399: 676477960192..676478062591: 102400:             last,shared
bar: 1 extent found
$ rmlint --is-reflink -vv foo bar
DEBUG: Testing if foo is clone of bar
DEBUG: Checking link type for foo vs bar
DEBUG: rm_offset_get_fiemap: fd=3, n_extents=1, file_offset=0
DEBUG: rm_offset_get_fiemap: fd=4, n_extents=1, file_offset=0
DEBUG: Offsets match at fd1=3, fd2=4, logical=0, physical=676477960192
DEBUG: rm_offset_get_fiemap: fd=3, n_extents=1, file_offset=102400
INFO: rm_offset_get_fiemap: got no extents for 3
DEBUG: rm_offset_get_fiemap: fd=4, n_extents=1, file_offset=102400
INFO: rm_offset_get_fiemap: got no extents for 4
DEBUG: Can't determine whether files are clones
Link type for 'foo' and 'bar', result:
An error occurred during checking
$ echo $?
1

Actual result

Testcase 1

rmlint prints "Reflink" and exits with status 0. It checks the first extent's offset, but ignores the second.

Testcase 2

rmlint prints "An error occurred during checking" and exits with status 1. It reports "got no extents" twice.

Expected result

Testcase 1

rmlint prints "Not linked" and exits with status 11. There should be a message like DEBUG: Physical offsets differ at byte 102400: 694077128704<> 694103236608.

Testcase 2

DEBUG: Testing if foo is clone of bar
DEBUG: Checking link type for foo vs bar
DEBUG: rm_offset_get_fiemap: fd=3, n_extents=1, file_offset=0
DEBUG: rm_offset_get_fiemap: fd=4, n_extents=1, file_offset=0
DEBUG: Offsets match at fd1=3, fd2=4, logical=0, physical=676477960192
DEBUG: Files are clones (share same data)
Link type for 'foo' and 'bar', result:
Reflink
$ echo $?
0

rmlint prints "Reflink" and exits with status 0. There should be only one rm_offset_get_fiemap call per file.

Versions

rmlint version 2.10.1 built from develop commit bdb591f4, with _RM_OFFSET_DEBUG=1 and a fix for #527 applied.

cebtenzzre avatar Sep 16 '21 18:09 cebtenzzre