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:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user