Volume::Ummount() now use the NO_WRITES mode for remove_cached_device_blocks()

if the volume is read-only.
Some style changes.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1600 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2002-10-22 17:46:12 +00:00
parent 4c7e1fff2f
commit 05f02d9b9a
2 changed files with 93 additions and 43 deletions
+21 -18
View File
@@ -65,12 +65,14 @@ Volume::Panic()
fFlags |= VOLUME_READ_ONLY; fFlags |= VOLUME_READ_ONLY;
#ifdef USER #ifdef USER
debugger("BFS panics!"); debugger("BFS panics!");
#elif defined(DEBUG)
kernel_debugger("BFS panics!");
#endif #endif
} }
status_t status_t
Volume::Mount(const char *deviceName,uint32 flags) Volume::Mount(const char *deviceName, uint32 flags)
{ {
if (flags & B_MOUNT_READ_ONLY) if (flags & B_MOUNT_READ_ONLY)
fFlags |= VOLUME_READ_ONLY; fFlags |= VOLUME_READ_ONLY;
@@ -79,7 +81,7 @@ Volume::Mount(const char *deviceName,uint32 flags)
// if we couldn't open the device, try read-only (don't rely on a specific error code) // if we couldn't open the device, try read-only (don't rely on a specific error code)
if (fDevice < B_OK && (flags & B_MOUNT_READ_ONLY) == 0) { if (fDevice < B_OK && (flags & B_MOUNT_READ_ONLY) == 0) {
fDevice = open(deviceName,O_RDONLY); fDevice = open(deviceName, O_RDONLY);
fFlags |= VOLUME_READ_ONLY; fFlags |= VOLUME_READ_ONLY;
} }
@@ -89,11 +91,11 @@ Volume::Mount(const char *deviceName,uint32 flags)
// check if it's a regular file, and if so, disable the cache for the // check if it's a regular file, and if so, disable the cache for the
// underlaying file system // underlaying file system
struct stat stat; struct stat stat;
if (fstat(fDevice,&stat) < 0) if (fstat(fDevice, &stat) < 0)
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
//#ifndef USER //#ifndef USER
if (stat.st_mode & S_FILE && ioctl(fDevice,IOCTL_FILE_UNCACHED_IO,NULL) < 0) { if (stat.st_mode & S_FILE && ioctl(fDevice, IOCTL_FILE_UNCACHED_IO, NULL) < 0) {
// mount read-only if the cache couldn't be disabled // mount read-only if the cache couldn't be disabled
# ifdef DEBUG # ifdef DEBUG
FATAL(("couldn't disable cache for image file - system may dead-lock!\n")); FATAL(("couldn't disable cache for image file - system may dead-lock!\n"));
@@ -106,14 +108,14 @@ Volume::Mount(const char *deviceName,uint32 flags)
// read the super block // read the super block
char buffer[1024]; char buffer[1024];
if (read_pos(fDevice,0,buffer,sizeof(buffer)) != sizeof(buffer)) if (read_pos(fDevice, 0, buffer, sizeof(buffer)) != sizeof(buffer))
return B_IO_ERROR; return B_IO_ERROR;
status_t status = B_OK; status_t status = B_OK;
// Note: that does work only for x86, for PowerPC, the super block // Note: that does work only for x86, for PowerPC, the super block
// is located at offset 0! // is located at offset 0!
memcpy(&fSuperBlock,buffer + 512,sizeof(disk_super_block)); memcpy(&fSuperBlock, buffer + 512, sizeof(disk_super_block));
if (IsValidSuperBlock()) { if (IsValidSuperBlock()) {
// set the current log pointers, so that journaling will work correctly // set the current log pointers, so that journaling will work correctly
@@ -125,10 +127,10 @@ Volume::Mount(const char *deviceName,uint32 flags)
// replaying the log is the first thing we will do on this disk // replaying the log is the first thing we will do on this disk
if (fJournal && fJournal->InitCheck() == B_OK if (fJournal && fJournal->InitCheck() == B_OK
&& fBlockAllocator.Initialize() == B_OK) { && fBlockAllocator.Initialize() == B_OK) {
fRootNode = new Inode(this,ToVnode(Root())); fRootNode = new Inode(this, ToVnode(Root()));
if (fRootNode && fRootNode->InitCheck() == B_OK) { if (fRootNode && fRootNode->InitCheck() == B_OK) {
if (new_vnode(fID,ToVnode(Root()),(void *)fRootNode) == B_OK) { if (new_vnode(fID, ToVnode(Root()),(void *)fRootNode) == B_OK) {
// try to get indices root dir // try to get indices root dir
// question: why doesn't get_vnode() work here?? // question: why doesn't get_vnode() work here??
@@ -136,7 +138,7 @@ Volume::Mount(const char *deviceName,uint32 flags)
// volume in bfs_mount(), so bfs_read_vnode() can't get it. // volume in bfs_mount(), so bfs_read_vnode() can't get it.
// But it's not needed to do that anyway. // But it's not needed to do that anyway.
fIndicesNode = new Inode(this,ToVnode(Indices())); fIndicesNode = new Inode(this, ToVnode(Indices()));
if (fIndicesNode == NULL if (fIndicesNode == NULL
|| fIndicesNode->InitCheck() < B_OK || fIndicesNode->InitCheck() < B_OK
|| !fIndicesNode->IsDirectory()) { || !fIndicesNode->IsDirectory()) {
@@ -164,7 +166,7 @@ Volume::Mount(const char *deviceName,uint32 flags)
FATAL(("could not initialize journal/block bitmap allocator!\n")); FATAL(("could not initialize journal/block bitmap allocator!\n"));
} }
remove_cached_device_blocks(fDevice,NO_WRITES); remove_cached_device_blocks(fDevice, NO_WRITES);
} else { } else {
FATAL(("could not initialize cache!\n")); FATAL(("could not initialize cache!\n"));
status = B_IO_ERROR; status = B_IO_ERROR;
@@ -189,7 +191,7 @@ Volume::Unmount()
delete fIndicesNode; delete fIndicesNode;
remove_cached_device_blocks(fDevice,ALLOW_WRITES); remove_cached_device_blocks(fDevice, IsReadOnly() ? NO_WRITES : ALLOW_WRITES);
close(fDevice); close(fDevice);
return B_OK; return B_OK;
@@ -211,7 +213,7 @@ Volume::IsValidBlockRun(block_run run)
|| run.length == 0 || run.length == 0
|| (uint32)run.length + run.start > (1LL << AllocationGroupShift())) { || (uint32)run.length + run.start > (1LL << AllocationGroupShift())) {
Panic(); Panic();
FATAL(("*** invalid run(%ld,%d,%d)\n",run.allocation_group,run.start,run.length)); FATAL(("*** invalid run(%ld,%d,%d)\n", run.allocation_group, run.start, run.length));
return B_BAD_DATA; return B_BAD_DATA;
} }
return B_OK; return B_OK;
@@ -233,8 +235,8 @@ status_t
Volume::CreateIndicesRoot(Transaction *transaction) Volume::CreateIndicesRoot(Transaction *transaction)
{ {
off_t id; off_t id;
status_t status = Inode::Create(transaction,NULL,NULL, status_t status = Inode::Create(transaction, NULL, NULL,
S_INDEX_DIR | S_STR_INDEX | S_DIRECTORY | 0700,0,0,&id); S_INDEX_DIR | S_STR_INDEX | S_DIRECTORY | 0700, 0, 0, &id);
if (status < B_OK) if (status < B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
@@ -251,14 +253,14 @@ Volume::CreateIndicesRoot(Transaction *transaction)
status_t status_t
Volume::AllocateForInode(Transaction *transaction, const Inode *parent, mode_t type, block_run &run) Volume::AllocateForInode(Transaction *transaction, const Inode *parent, mode_t type, block_run &run)
{ {
return fBlockAllocator.AllocateForInode(transaction,&parent->BlockRun(),type,run); return fBlockAllocator.AllocateForInode(transaction, &parent->BlockRun(), type, run);
} }
status_t status_t
Volume::WriteSuperBlock() Volume::WriteSuperBlock()
{ {
if (write_pos(fDevice,512,&fSuperBlock,sizeof(disk_super_block)) != sizeof(disk_super_block)) if (write_pos(fDevice, 512, &fSuperBlock, sizeof(disk_super_block)) != sizeof(disk_super_block))
return B_IO_ERROR; return B_IO_ERROR;
return B_OK; return B_OK;
@@ -266,14 +268,15 @@ Volume::WriteSuperBlock()
void void
Volume::UpdateLiveQueries(Inode *inode,const char *attribute,int32 type,const uint8 *oldKey,size_t oldLength,const uint8 *newKey,size_t newLength) Volume::UpdateLiveQueries(Inode *inode, const char *attribute, int32 type, const uint8 *oldKey,
size_t oldLength, const uint8 *newKey, size_t newLength)
{ {
if (fQueryLock.Lock() < B_OK) if (fQueryLock.Lock() < B_OK)
return; return;
Query *query = NULL; Query *query = NULL;
while ((query = fQueries.Next(query)) != NULL) while ((query = fQueries.Next(query)) != NULL)
query->LiveUpdate(inode,attribute,type,oldKey,oldLength,newKey,newLength); query->LiveUpdate(inode, attribute, type, oldKey, oldLength, newKey, newLength);
fQueryLock.Unlock(); fQueryLock.Unlock();
} }
+72 -25
View File
@@ -37,13 +37,13 @@ class Volume {
Volume(nspace_id id); Volume(nspace_id id);
~Volume(); ~Volume();
status_t Mount(const char *device,uint32 flags); status_t Mount(const char *device, uint32 flags);
status_t Unmount(); status_t Unmount();
bool IsValidSuperBlock(); bool IsValidSuperBlock();
bool IsReadOnly() const { return fFlags & VOLUME_READ_ONLY; } bool IsReadOnly() const;
void Panic(); void Panic();
Benaphore &Lock() { return fLock; } Benaphore &Lock();
block_run Root() const { return fSuperBlock.root_dir; } block_run Root() const { return fSuperBlock.root_dir; }
Inode *RootNode() const { return fRootNode; } Inode *RootNode() const { return fRootNode; }
@@ -79,30 +79,35 @@ class Volume {
status_t CreateIndicesRoot(Transaction *transaction); status_t CreateIndicesRoot(Transaction *transaction);
status_t AllocateForInode(Transaction *transaction,const Inode *parent,mode_t type,block_run &run); // block bitmap
status_t AllocateForInode(Transaction *transaction,const block_run *parent,mode_t type,block_run &run); BlockAllocator &Allocator();
status_t Allocate(Transaction *transaction,const Inode *inode,off_t numBlocks,block_run &run,uint16 minimum = 1); status_t AllocateForInode(Transaction *transaction, const Inode *parent,
mode_t type, block_run &run);
status_t AllocateForInode(Transaction *transaction, const block_run *parent,
mode_t type, block_run &run);
status_t Allocate(Transaction *transaction,const Inode *inode,
off_t numBlocks, block_run &run, uint16 minimum = 1);
status_t Free(Transaction *transaction, block_run run); status_t Free(Transaction *transaction, block_run run);
#ifdef DEBUG // cache access
BlockAllocator &Allocator() { return fBlockAllocator; }
#endif
BufferPool &Pool() { return fBufferPool; }
status_t Sync();
Journal *GetJournal(off_t /*refBlock*/) const { return fJournal; }
status_t WriteSuperBlock(); status_t WriteSuperBlock();
status_t WriteBlocks(off_t blockNumber,const uint8 *block,uint32 numBlocks); status_t WriteBlocks(off_t blockNumber, const uint8 *block, uint32 numBlocks);
void WriteCachedBlocksIfNecessary(); void WriteCachedBlocksIfNecessary();
status_t FlushDevice(); status_t FlushDevice();
void UpdateLiveQueries(Inode *inode,const char *attribute,int32 type,const uint8 *oldKey,size_t oldLength,const uint8 *newKey,size_t newLength); // queries
void UpdateLiveQueries(Inode *inode, const char *attribute, int32 type,
const uint8 *oldKey, size_t oldLength,
const uint8 *newKey, size_t newLength);
void AddQuery(Query *query); void AddQuery(Query *query);
void RemoveQuery(Query *query); void RemoveQuery(Query *query);
uint32 GetUniqueID() { return atomic_add(&fUniqueID,1); } status_t Sync();
Journal *GetJournal(off_t refBlock) const;
BufferPool &Pool();
uint32 GetUniqueID();
protected: protected:
nspace_id fID; nspace_id fID;
@@ -111,7 +116,7 @@ class Volume {
BlockAllocator fBlockAllocator; BlockAllocator fBlockAllocator;
Benaphore fLock; Benaphore fLock;
Journal *fJournal; Journal *fJournal;
vint32 fLogStart,fLogEnd; vint32 fLogStart, fLogEnd;
Inode *fRootNode; Inode *fRootNode;
Inode *fIndicesNode; Inode *fIndicesNode;
@@ -127,19 +132,41 @@ class Volume {
BufferPool fBufferPool; BufferPool fBufferPool;
}; };
// inline functions // inline functions
inline bool
Volume::IsReadOnly() const
{
return fFlags & VOLUME_READ_ONLY;
}
inline Benaphore &
Volume::Lock()
{
return fLock;
}
inline BlockAllocator &
Volume::Allocator()
{
return fBlockAllocator;
}
inline status_t inline status_t
Volume::AllocateForInode(Transaction *transaction, const block_run *parent, mode_t type, block_run &run) Volume::AllocateForInode(Transaction *transaction, const block_run *parent, mode_t type, block_run &run)
{ {
return fBlockAllocator.AllocateForInode(transaction,parent,type,run); return fBlockAllocator.AllocateForInode(transaction, parent, type, run);
} }
inline status_t inline status_t
Volume::Allocate(Transaction *transaction, const Inode *inode, off_t numBlocks, block_run &run, uint16 minimum) Volume::Allocate(Transaction *transaction, const Inode *inode, off_t numBlocks, block_run &run, uint16 minimum)
{ {
return fBlockAllocator.Allocate(transaction,inode,numBlocks,run,minimum); return fBlockAllocator.Allocate(transaction, inode, numBlocks, run, minimum);
} }
@@ -153,8 +180,8 @@ Volume::Free(Transaction *transaction, block_run run)
inline status_t inline status_t
Volume::WriteBlocks(off_t blockNumber, const uint8 *block, uint32 numBlocks) Volume::WriteBlocks(off_t blockNumber, const uint8 *block, uint32 numBlocks)
{ {
atomic_add(&fDirtyCachedBlocks,numBlocks); atomic_add(&fDirtyCachedBlocks, numBlocks);
return cached_write(fDevice,blockNumber,block,numBlocks,fSuperBlock.block_size); return cached_write(fDevice, blockNumber, block, numBlocks, fSuperBlock.block_size);
} }
@@ -163,8 +190,8 @@ Volume::WriteCachedBlocksIfNecessary()
{ {
// the specific values are only valid for the current BeOS cache // the specific values are only valid for the current BeOS cache
if (fDirtyCachedBlocks > 128) { if (fDirtyCachedBlocks > 128) {
force_cache_flush(fDevice,false); force_cache_flush(fDevice, false);
atomic_add(&fDirtyCachedBlocks,-64); atomic_add(&fDirtyCachedBlocks, -64);
} }
} }
@@ -173,8 +200,28 @@ inline status_t
Volume::FlushDevice() Volume::FlushDevice()
{ {
fDirtyCachedBlocks = 0; fDirtyCachedBlocks = 0;
return flush_device(fDevice,0); return flush_device(fDevice, 0);
} }
inline Journal *
Volume::GetJournal(off_t /*refBlock*/) const
{
return fJournal;
}
inline BufferPool &
Volume::Pool()
{
return fBufferPool;
}
inline uint32
Volume::GetUniqueID()
{
return atomic_add(&fUniqueID, 1);
}
#endif /* VOLUME_H */ #endif /* VOLUME_H */