Skip to content

Commit

Permalink
reflink: Fix EOF check
Browse files Browse the repository at this point in the history
There were two EOF checks in rm_reflink_type_from_fd. One of them caused
the last extent to be ignored in files with at least two extents. The
other mishandled files that end with a hole.

In rm_offset_get_from_fd, always warn about no extents at a nonzero file
offset, since calling code should stop after the last extent.

Fixes sahib#528
  • Loading branch information
cebtenzzre authored and intelfx committed Mar 9, 2023
1 parent 0e5a675 commit 96e696c
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 13 deletions.
10 changes: 2 additions & 8 deletions lib/reflink.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
#endif


RmLinkType rm_reflink_type_from_fd(int fd1, int fd2, guint64 file_size) {
RmLinkType rm_reflink_type_from_fd(int fd1, int fd2) {
#if HAVE_FIEMAP

RmOff logical_current = 0;
Expand All @@ -92,7 +92,6 @@ RmLinkType rm_reflink_type_from_fd(int fd1, int fd2, guint64 file_size) {
bool is_last_2 = false;
bool is_inline_1 = false;
bool is_inline_2 = false;
bool at_least_one_checked = false;

while(!rm_session_was_aborted()) {
RmOff logical_next_1 = 0;
Expand All @@ -113,10 +112,6 @@ RmLinkType rm_reflink_type_from_fd(int fd1, int fd2, guint64 file_size) {
return RM_LINK_NONE;
}

if(is_last_1 && is_last_2 && at_least_one_checked) {
return RM_LINK_REFLINK;
}

if(physical_1 != physical_2) {
#if _RM_OFFSET_DEBUG
rm_log_debug_line("Physical offsets differ at byte %" G_GUINT64_FORMAT
Expand Down Expand Up @@ -150,7 +145,7 @@ RmLinkType rm_reflink_type_from_fd(int fd1, int fd2, guint64 file_size) {
return RM_LINK_ERROR;
}

if(logical_next_1 >= (guint64)file_size) {
if(is_last_1) {
/* phew, we got to the end */
#if _RM_OFFSET_DEBUG
rm_log_debug_line("Files are clones (share same data)")
Expand All @@ -159,7 +154,6 @@ RmLinkType rm_reflink_type_from_fd(int fd1, int fd2, guint64 file_size) {
}

logical_current = logical_next_1;
at_least_one_checked = true;
}

return RM_LINK_ERROR;
Expand Down
2 changes: 1 addition & 1 deletion lib/reflink.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ int rm_dedupe_main(int argc, const char **argv);
**/
int rm_is_reflink_main(int argc, const char **argv);

RmLinkType rm_reflink_type_from_fd(int fd1, int fd2, guint64 file_size);
RmLinkType rm_reflink_type_from_fd(int fd1, int fd2);

#endif /* end of include guard */
8 changes: 4 additions & 4 deletions lib/utilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -1213,9 +1213,9 @@ RmOff rm_offset_get_from_fd(int fd, RmOff file_offset, RmOff *file_offset_next,
}

if(fm->fm_mapped_extents == 0) {
#if _RM_OFFSET_DEBUG
rm_log_info_line(_("rm_offset_get_fiemap: got no extents for %d"), fd);
#endif
if(file_offset != 0) {
rm_log_warning_line(_("rm_offset_get_fiemap: got no extents for %d at offset %" G_GUINT64_FORMAT), fd, file_offset);
}
done = TRUE;
} else {
/* retrieve data from fiemap */
Expand Down Expand Up @@ -1411,7 +1411,7 @@ RmLinkType rm_util_link_type(const char *path1, const char *path2, bool use_fiem
}

if(use_fiemap) {
RmLinkType reflink_type = rm_reflink_type_from_fd(fd1, fd2, stat1.st_size);
RmLinkType reflink_type = rm_reflink_type_from_fd(fd1, fd2);
RM_RETURN(reflink_type);
}
RM_RETURN(RM_LINK_NONE);
Expand Down

0 comments on commit 96e696c

Please sign in to comment.