From 72e9c2846a06d5861f4bff9963fbe1a42f214eed Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 20 Jul 2010 16:59:53 +0000 Subject: [PATCH] * Added flags for removing/unremoving the node. * Added more optional notification parameters to Commit(). * Added some handy methods. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37623 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_corruption/fs/Transaction.cpp | 73 ++++++++++++++++--- .../kernel/file_corruption/fs/Transaction.h | 23 +++++- 2 files changed, 83 insertions(+), 13 deletions(-) diff --git a/src/tests/system/kernel/file_corruption/fs/Transaction.cpp b/src/tests/system/kernel/file_corruption/fs/Transaction.cpp index 04993f5ef5..43db8110b6 100644 --- a/src/tests/system/kernel/file_corruption/fs/Transaction.cpp +++ b/src/tests/system/kernel/file_corruption/fs/Transaction.cpp @@ -71,7 +71,9 @@ Transaction::StartAndAddNode(Node* node, uint32 flags = 0) status_t -Transaction::Commit(const PostCommitNotification* notification) +Transaction::Commit(const PostCommitNotification* notification1, + const PostCommitNotification* notification2, + const PostCommitNotification* notification3) { ASSERT(fID >= 0); @@ -94,8 +96,12 @@ Transaction::Commit(const PostCommitNotification* notification) } // send notifications - if (notification != NULL) - notification->NotifyPostCommit(); + if (notification1 != NULL) + notification1->NotifyPostCommit(); + if (notification2 != NULL) + notification2->NotifyPostCommit(); + if (notification3 != NULL) + notification3->NotifyPostCommit(); // clean up _DeleteNodeInfosAndUnlock(false); @@ -135,6 +141,8 @@ Transaction::Abort() status_t Transaction::AddNode(Node* node, uint32 flags) { + ASSERT(fID >= 0); + NodeInfo* info = _GetNodeInfo(node); if (info != NULL) return B_OK; @@ -159,6 +167,8 @@ Transaction::AddNode(Node* node, uint32 flags) status_t Transaction::AddNodes(Node* node1, Node* node2, Node* node3) { + ASSERT(fID >= 0); + // sort the nodes swap_if_greater(node1, node2); if (node3 != NULL && swap_if_greater(node2, node3)) @@ -175,9 +185,41 @@ Transaction::AddNodes(Node* node1, Node* node2, Node* node3) } +bool +Transaction::RemoveNode(Node* node) +{ + ASSERT(fID >= 0); + + NodeInfo* info = _GetNodeInfo(node); + if (info == NULL) + return false; + + fNodeInfos.Remove(info); + + _DeleteNodeInfoAndUnlock(info, false); + + return true; +} + + +void +Transaction::UpdateNodeFlags(Node* node, uint32 flags) +{ + ASSERT(fID >= 0); + + NodeInfo* info = _GetNodeInfo(node); + if (info == NULL) + return; + + info->flags = flags; +} + + void Transaction::KeepNode(Node* node) { + ASSERT(fID >= 0); + NodeInfo* info = _GetNodeInfo(node); if (info == NULL) return; @@ -202,13 +244,26 @@ Transaction::_GetNodeInfo(Node* node) const void Transaction::_DeleteNodeInfosAndUnlock(bool failed) { - while (NodeInfo* info = fNodeInfos.RemoveHead()) { - if ((info->flags & TRANSACTION_DELETE_NODE) != 0) - delete info->node; - else if ((info->flags & TRANSACTION_KEEP_NODE_LOCKED) == 0) - info->node->WriteUnlock(); - delete info; + while (NodeInfo* info = fNodeInfos.RemoveHead()) + _DeleteNodeInfoAndUnlock(info, failed); +} + + +void +Transaction::_DeleteNodeInfoAndUnlock(NodeInfo* info, bool failed) +{ + if (failed) { + if ((info->flags & TRANSACTION_REMOVE_NODE_ON_ERROR) != 0) + fVolume->RemoveNode(info->node); + else if ((info->flags & TRANSACTION_UNREMOVE_NODE_ON_ERROR) != 0) + fVolume->UnremoveNode(info->node); } + + if ((info->flags & TRANSACTION_DELETE_NODE) != 0) + delete info->node; + else if ((info->flags & TRANSACTION_KEEP_NODE_LOCKED) == 0) + info->node->WriteUnlock(); + delete info; } diff --git a/src/tests/system/kernel/file_corruption/fs/Transaction.h b/src/tests/system/kernel/file_corruption/fs/Transaction.h index 36029b61a7..6e66fc0da0 100644 --- a/src/tests/system/kernel/file_corruption/fs/Transaction.h +++ b/src/tests/system/kernel/file_corruption/fs/Transaction.h @@ -18,9 +18,11 @@ class Volume; enum { - TRANSACTION_DELETE_NODE = 0x1, - TRANSACTION_NODE_ALREADY_LOCKED = 0x2, - TRANSACTION_KEEP_NODE_LOCKED = 0x4 + TRANSACTION_DELETE_NODE = 0x01, + TRANSACTION_NODE_ALREADY_LOCKED = 0x02, + TRANSACTION_KEEP_NODE_LOCKED = 0x04, + TRANSACTION_REMOVE_NODE_ON_ERROR = 0x08, + TRANSACTION_UNREMOVE_NODE_ON_ERROR = 0x10 }; @@ -34,18 +36,29 @@ public: status_t Start(); status_t StartAndAddNode(Node* node, uint32 flags = 0); status_t Commit( - const PostCommitNotification* notification + const PostCommitNotification* notification1 + = NULL, + const PostCommitNotification* notification2 + = NULL, + const PostCommitNotification* notification3 = NULL); inline status_t Commit( const PostCommitNotification& notification); void Abort(); + inline bool IsActive() const { return fID >= 0; } + status_t AddNode(Node* node, uint32 flags = 0); status_t AddNodes(Node* node1, Node* node2, Node* node3 = NULL); + bool RemoveNode(Node* node); + void UpdateNodeFlags(Node* node, uint32 flags); void KeepNode(Node* node); + bool IsNodeLocked(Node* node) const + { return _GetNodeInfo(node) != NULL; } + private: struct NodeInfo : DoublyLinkedListLinkImpl { Node* node; @@ -58,6 +71,8 @@ private: private: NodeInfo* _GetNodeInfo(Node* node) const; void _DeleteNodeInfosAndUnlock(bool failed); + void _DeleteNodeInfoAndUnlock(NodeInfo* info, + bool failed); private: Volume* fVolume;