Merge pull request #11517 from ukernel/wip-17562

Fix #17562 (backtrace check fails when scrubbing directory created by fsstress)

Reviewed-by: John Spray <john.spray@redhat.com>
Reviewed-by: Greg Farnum <gfarnum@redhat.com>
This commit is contained in:
John Spray 2016-10-25 12:30:42 +01:00 committed by GitHub
commit bbdfd1375e
2 changed files with 13 additions and 23 deletions

View File

@ -3845,15 +3845,11 @@ void CInode::validate_disk_state(CInode::validated_data *results,
memory_newer = memory_backtrace.compare(results->backtrace.ondisk_value,
&equivalent, &divergent);
if (equivalent) {
results->backtrace.passed = true;
if (divergent || memory_newer < 0) {
// we're divergent, or on-disk version is newer
results->backtrace.error_str << "On-disk backtrace is divergent or newer";
} else {
if (divergent || memory_newer <= 0) {
// we're divergent, or don't have a newer version to write
results->backtrace.error_str <<
"On-disk backtrace is divergent or newer";
goto next;
}
results->backtrace.passed = true;
}
next:

View File

@ -122,6 +122,7 @@ int inode_backtrace_t::compare(const inode_backtrace_t& other,
bool *equivalent, bool *divergent) const
{
int min_size = MIN(ancestors.size(),other.ancestors.size());
*equivalent = true;
*divergent = false;
if (min_size == 0)
return 0;
@ -130,6 +131,9 @@ int inode_backtrace_t::compare(const inode_backtrace_t& other,
comparator = 1;
else if (ancestors[0].version < other.ancestors[0].version)
comparator = -1;
if (ancestors[0].dirino != other.ancestors[0].dirino ||
ancestors[0].dname != other.ancestors[0].dname)
*divergent = true;
for (int i = 1; i < min_size; ++i) {
if (*divergent) {
/**
@ -138,20 +142,10 @@ int inode_backtrace_t::compare(const inode_backtrace_t& other,
*/
break;
}
if (ancestors[i].dirino != other.ancestors[i].dirino) {
if (ancestors[i].dirino != other.ancestors[i].dirino ||
ancestors[i].dname != other.ancestors[i].dname) {
*equivalent = false;
if (ancestors[i-1].version < other.ancestors[i-1].version) {
if (comparator > 0)
*divergent = true;
return -1;
} else if (ancestors[i-1].version > other.ancestors[i-1].version) {
if (comparator < 0)
*divergent = true;
return 1;
} else {
assert(ancestors[i-1].version == other.ancestors[i-1].version);
return 0;
}
return comparator;
} else if (ancestors[i].version > other.ancestors[i].version) {
if (comparator < 0)
*divergent = true;
@ -162,7 +156,7 @@ int inode_backtrace_t::compare(const inode_backtrace_t& other,
comparator = -1;
}
}
if (!*divergent)
*equivalent = true;
if (*divergent)
*equivalent = false;
return comparator;
}