Added a new inode flag INODE_CHKBFS_RUNNING to detect aborted chkbfs processes.

bfs_read_vnode() will now wait for half a second at maximum until it returns
the B_BUSY error (so that live queries will like it better).


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2058 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2002-11-22 03:31:34 +00:00
parent edd77cc706
commit f512ce4233
2 changed files with 36 additions and 8 deletions

View File

@ -172,6 +172,7 @@ enum inode_flags
INODE_NO_TRANSACTION = 0x00040000,
INODE_DONT_FREE_SPACE = 0x00080000, // only used by the "chkbfs" functionality
INODE_NOT_READY = 0x00100000, // used during construction
INODE_CHKBFS_RUNNING = 0x00200000,
};
//**************************************

View File

@ -375,13 +375,27 @@ bfs_read_vnode(void *_ns, vnode_id id, char reenter, void **_node)
if (inode == NULL)
return B_NO_MEMORY;
status_t status = inode->InitCheck();
if (status == B_OK) {
*_node = (void *)inode;
return B_OK;
}
status_t status;
int32 tries = 0;
// ToDo: if "status" is B_BUSY, we could wait a bit and try again
while (true) {
if ((status = inode->InitCheck()) == B_OK) {
*_node = (void *)inode;
return B_OK;
}
// if "status" is B_BUSY, we wait a bit and try again
if (status == B_BUSY) {
// wait for half a second at maximum
if (tries++ < 100) {
snooze(5000);
continue;
}
FATAL(("inode is not becoming unbusy (id = %Ld)\n", id));
}
break;
}
delete inode;
RETURN_ERROR(status);
@ -584,7 +598,11 @@ bfs_ioctl(void *_ns, void *_node, void *_cookie, int cmd, void *buffer, size_t b
BlockAllocator &allocator = volume->Allocator();
check_control *control = (check_control *)buffer;
return allocator.StartChecking(control);
status_t status = allocator.StartChecking(control);
if (status == B_OK && inode != NULL)
inode->Node()->flags |= INODE_CHKBFS_RUNNING;
return status;
}
case BFS_IOCTL_STOP_CHECKING:
{
@ -592,7 +610,11 @@ bfs_ioctl(void *_ns, void *_node, void *_cookie, int cmd, void *buffer, size_t b
BlockAllocator &allocator = volume->Allocator();
check_control *control = (check_control *)buffer;
return allocator.StopChecking(control);
status_t status = allocator.StopChecking(control);
if (status == B_OK && inode != NULL)
inode->Node()->flags &= ~INODE_CHKBFS_RUNNING;
return status;
}
case BFS_IOCTL_CHECK_NEXT_NODE:
{
@ -1292,6 +1314,11 @@ bfs_close(void *_ns, void *_node, void *_cookie)
// non-permanent flag which will be removed when the inode is loaded
// into memory.
}
if (inode->Flags() & INODE_CHKBFS_RUNNING) {
// "chkbfs" exited abnormally, so we have to stop it here...
FATAL(("check process was aborted!\n"));
volume->Allocator().StopChecking(NULL);
}
return B_OK;
}