Author: axeld Date: 2010-03-09 21:08:25 +0100 (Tue, 09 Mar 2010) New Revision: 35794 Changeset: http://dev.haiku-os.org/changeset/35794/haiku Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp Log: * BlockAllocator::CheckNextNode() did enter an endless loop if it experienced problems iterating over a B+tree (due to corruption). * For now, it will stop the check process when this happens, but we definitely need to be able to fix broken B+trees in the future. Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp 2010-03-09 14:50:41 UTC (rev 35793) +++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp 2010-03-09 20:08:25 UTC (rev 35794) @@ -1374,13 +1374,13 @@ fTarget(userTarget) { } - + ~CopyControlOnExit() { if (fTarget != NULL) user_memcpy(fTarget, fSource, sizeof(check_control)); } - + private: check_control* fSource; check_control* fTarget; @@ -1451,8 +1451,8 @@ status_t status = fCheckCookie->iterator->GetNextEntry(name, &length, B_FILE_NAME_LENGTH, &id); - if (status == B_ENTRY_NOT_FOUND) { - // there are no more entries in this iterator, free it and go on + if (status != B_OK) { + // we no longer need this iterator delete fCheckCookie->iterator; fCheckCookie->iterator = NULL; @@ -1460,8 +1460,18 @@ put_vnode(fVolume->FSVolume(), fVolume->ToVnode(fCheckCookie->current)); - continue; - } else if (status == B_OK) { + if (status == B_ENTRY_NOT_FOUND) { + // We iterated over all entries already, just go on to the next + continue; + } + + // Iterating over the B+tree failed - we let the checkfs run + // fail completely, as we would delete all files we cannot + // access. + // TODO: maybe have a force parameter that actually does that. + // TODO: we also need to be able to repair broken B+trees! + return status; + } else { // ignore "." and ".." entries if (!strcmp(name, ".") || !strcmp(name, "..")) continue;