From 2d4d5317317a2b16d5a5c90aa2b00437f2cb2ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 13 Jun 2020 18:36:18 +0200 Subject: [PATCH] bfs: CheckVisitor only deletes nodes on specific errors * This should prevent erroneously deleting any files in low memory situations. Change-Id: I21b1d042e5f7e03a5abfaaa567b6c679b95e3188 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2914 Reviewed-by: Adrien Destugues --- .../kernel/file_systems/bfs/CheckVisitor.cpp | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp b/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp index 63bafa5cc9..40b4635660 100644 --- a/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp +++ b/src/add-ons/kernel/file_systems/bfs/CheckVisitor.cpp @@ -336,7 +336,8 @@ status_t CheckVisitor::OpenInodeFailed(status_t reason, ino_t id, Inode* parent, char* treeName, TreeIterator* iterator) { - FATAL(("Could not open inode at %" B_PRIdOFF "\n", id)); + FATAL(("Could not open inode at %" B_PRIdOFF ": %s\n", id, + strerror(reason))); if (treeName != NULL) strlcpy(Control().name, treeName, B_FILE_NAME_LENGTH); @@ -346,13 +347,19 @@ CheckVisitor::OpenInodeFailed(status_t reason, ino_t id, Inode* parent, Control().inode = id; Control().errors = BFS_COULD_NOT_OPEN; - // remove inode from the tree if we can - if (parent != NULL && iterator != NULL - && (Control().flags & BFS_REMOVE_INVALID) != 0) { - Control().status = _RemoveInvalidNode(parent, iterator->Tree(), NULL, - treeName); - } else - Control().status = B_ERROR; + // TODO: check other error codes; B_IO_ERROR might be a temporary + // issue, so it should be guarded by a force mode + if (reason == B_BAD_VALUE || reason == B_BAD_DATA || reason == B_IO_ERROR) { + // Remove inode from the tree if we can + if (parent != NULL && iterator != NULL + && (Control().flags & BFS_REMOVE_INVALID) != 0) { + Control().status = _RemoveInvalidNode(parent, iterator->Tree(), + NULL, treeName); + } else + Control().status = B_ERROR; + } else { + Control().status = B_OK; + } return B_OK; }