-
Notifications
You must be signed in to change notification settings - Fork 1.9k
receive_freeobjects() skips freeing some objects #6695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I think it would be better to add this test. |
Codecov Report
@@ Coverage Diff @@
## master #6695 +/- ##
=========================================
Coverage ? 74.02%
=========================================
Files ? 295
Lines ? 93878
Branches ? 0
=========================================
Hits ? 69495
Misses ? 24383
Partials ? 0
Continue to review full report at Codecov.
|
904de02 to
2a0b774
Compare
|
Added test case. |
gmelikov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
behlendorf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense and looks good. Just a few nits.
|
|
||
| log_must zfs create $POOL/$sendds | ||
|
|
||
| while :; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the : here do? Why not while true; do? Or better yet put large limit on this so can can't spin forever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| touch $f1 $f2 $f3 | ||
| o1=`ls -li $f1 | awk '{print $1}'` | ||
| o2=`ls -li $f2 | awk '{print $1}'` | ||
| o3=`ls -li $f3 | awk '{print $1}'` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you switch the legacy backticks to the preferred $() syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| o3=`ls -li $f3 | awk '{print $1}'` | ||
|
|
||
| if [[ $o2 -ne $(( $o1 + 1 )) ]] || [[ $o3 -ne $(( $o2 + 1 )) ]]; then | ||
| rm $f1 $f2 $f3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add -f to handle the unlike case where one of these files failed to be created and is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| log_must zfs create $POOL/$sendds | ||
|
|
||
| tries=100 | ||
| for ((i=0; i<$tries; i++)); do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it looks like this did happen in the last test run.
Test: /usr/share/zfs/zfs-tests/tests/functional/rsend/send_freeobjects (run as root) [10:00] [KILLED]
19:19:53.38 ASSERTION: Verify FREEOBJECTS record frees sequential objects
19:19:53.42 SUCCESS: zfs create testpool/sendfo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sigh. Of course it almost always exits the loop on the first or second iteration in manual testing. I may have to push a more verbose version to debug the builders.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out SELinux xattrs were consuming the intervening object numbers. Updated test case to force xattr=sa to work around this.
When receiving a FREEOBJECTS record, receive_freeobjects() incorrectly skips a freed object in some cases. Specifically, this happens when the first object in the range to be freed doesn't exist, but the second object does. This leaves an object allocated on disk on the receiving side which is unallocated on the sending side, which may cause receiving subsequent incremental streams to fail. The bug was caused by an incorrect increment of the object index variable when current object being freed doesn't exist. The increment is incorrect because incrementing the object index is handled by a call to dmu_object_next() in the increment portion of the for loop statement. Add test case that exposes this bug. Fixes openzfs#6694 Signed-off-by: Ned Bass <bass6@llnl.gov>
When receiving a FREEOBJECTS record, receive_freeobjects() incorrectly skips a freed object in some cases. Specifically, this happens when the first object in the range to be freed doesn't exist, but the second object does. This leaves an object allocated on disk on the receiving side which is unallocated on the sending side, which may cause receiving subsequent incremental streams to fail. The bug was caused by an incorrect increment of the object index variable when current object being freed doesn't exist. The increment is incorrect because incrementing the object index is handled by a call to dmu_object_next() in the increment portion of the for loop statement. Add test case that exposes this bug. Reviewed-by: George Melikov <mail@gmelikov.ru> Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ned Bass <bass6@llnl.gov> Closes openzfs#6694 Closes openzfs#6695
When receiving a FREEOBJECTS record, receive_freeobjects() incorrectly skips a freed object in some cases. Specifically, this happens when the first object in the range to be freed doesn't exist, but the second object does. This leaves an object allocated on disk on the receiving side which is unallocated on the sending side, which may cause receiving subsequent incremental streams to fail. The bug was caused by an incorrect increment of the object index variable when current object being freed doesn't exist. The increment is incorrect because incrementing the object index is handled by a call to dmu_object_next() in the increment portion of the for loop statement. Add test case that exposes this bug. Reviewed-by: George Melikov <mail@gmelikov.ru> Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ned Bass <bass6@llnl.gov> Closes #6694 Closes #6695
When receiving a FREEOBJECTS record, receive_freeobjects() incorrectly skips a freed object in some cases. Specifically, this happens when the first object in the range to be freed doesn't exist, but the second object does. This leaves an object allocated on disk on the receiving side which is unallocated on the sending side, which may cause receiving subsequent incremental streams to fail. The bug was caused by an incorrect increment of the object index variable when current object being freed doesn't exist. The increment is incorrect because incrementing the object index is handled by a call to dmu_object_next() in the increment portion of the for loop statement. Add test case that exposes this bug. Reviewed-by: George Melikov <mail@gmelikov.ru> Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ned Bass <bass6@llnl.gov> Closes openzfs#6694 Closes openzfs#6695
Description
When receiving a FREEOBJECTS record, receive_freeobjects()
incorrectly skips a freed object in some cases. This leaves an object
allocated on disk on the receiving side which is unallocated on the
sending side, which may cause receiving subsequent incremental
streams to fail.
The bug was caused by an incorrect increment of the object index
variable when current object being freed doesn't exist. The
increment is incorrect because incrementing the object index is
handled by a call to dmu_object_next() in the increment portion of
the for loop statement.
Motivation and Context
Receive backup streams correctly.
How Has This Been Tested?
Added test case rsend/send_freeobjects.ksh.
Types of changes
Checklist:
Signed-off-by.