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:
parent
edd77cc706
commit
f512ce4233
@ -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,
|
||||
};
|
||||
|
||||
//**************************************
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user