* The block allocator will no longer try to fix a missing allocation on a

read-only volume. This fixes bug #3432.
* Journal::ReplayLog() will now return an error on a read-only device, rendering
  read-only dirty volumes unmountable.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31255 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-06-26 15:03:42 +00:00
parent 5e08815985
commit 66ae5b2d99
3 changed files with 26 additions and 14 deletions
@@ -684,14 +684,20 @@ BlockAllocator::_Initialize(BlockAllocator* allocator)
uint32 reservedBlocks = volume->Log().Start() + volume->Log().Length();
if (allocator->CheckBlocks(0, reservedBlocks) != B_OK) {
Transaction transaction(volume, 0);
if (groups[0].Allocate(transaction, 0, reservedBlocks) != B_OK) {
FATAL(("could not allocate reserved space for block "
"bitmap/log!\n"));
volume->Panic();
if (volume->IsReadOnly()) {
FATAL(("Space for block bitmap or log area is not reserved "
"(volume is mounted read-only)!\n"));
} else {
transaction.Done();
FATAL(("space for block bitmap or log area was not reserved!\n"));
Transaction transaction(volume, 0);
if (groups[0].Allocate(transaction, 0, reservedBlocks) != B_OK) {
FATAL(("Could not allocate reserved space for block "
"bitmap/log!\n"));
volume->Panic();
} else {
transaction.Done();
FATAL(("Space for block bitmap or log area was not "
"reserved!\n"));
}
}
}
@@ -559,8 +559,13 @@ Journal::ReplayLog()
INFORM(("Replay log, disk was not correctly unmounted...\n"));
if (fVolume->SuperBlock().flags != SUPER_BLOCK_DISK_DIRTY)
INFORM(("log_start and log_end differ, but disk is marked clean - trying to replay log...\n"));
if (fVolume->SuperBlock().flags != SUPER_BLOCK_DISK_DIRTY) {
INFORM(("log_start and log_end differ, but disk is marked clean - "
"trying to replay log...\n"));
}
if (fVolume->IsReadOnly())
return B_READ_ONLY_DEVICE;
int32 start = fVolume->LogStart();
int32 lastStart = -1;
@@ -576,8 +581,9 @@ Journal::ReplayLog()
lastStart = start;
status_t status = _ReplayRunArray(&start);
if (status < B_OK) {
FATAL(("replaying log entry from %d failed: %s\n", (int)start, strerror(status)));
if (status != B_OK) {
FATAL(("replaying log entry from %d failed: %s\n", (int)start,
strerror(status)));
return B_ERROR;
}
start = start % fLogSize;
@@ -344,7 +344,7 @@ Volume::Mount(const char* deviceName, uint32 flags)
// check if the device size is large enough to hold the file system
off_t diskSize;
if (opener.GetSize(&diskSize) < B_OK)
if (opener.GetSize(&diskSize) != B_OK)
RETURN_ERROR(B_ERROR);
if (diskSize < (NumBlocks() << BlockShift()))
RETURN_ERROR(B_BAD_VALUE);
@@ -368,7 +368,7 @@ Volume::Mount(const char* deviceName, uint32 flags)
// replaying the log is the first thing we will do on this disk
status = fJournal->ReplayLog();
if (status < B_OK) {
if (status != B_OK) {
FATAL(("Replaying log failed, data may be corrupted, volume "
"read-only.\n"));
fFlags |= VOLUME_READ_ONLY;
@@ -379,7 +379,7 @@ Volume::Mount(const char* deviceName, uint32 flags)
}
status = fBlockAllocator.Initialize();
if (status < B_OK) {
if (status != B_OK) {
FATAL(("could not initialize block bitmap allocator!\n"));
return status;
}