* Volume::Unmount() never put the root node, and never deleted the volume's

block cache.
* Some cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35069 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-01-14 12:36:14 +00:00
parent 50b6d555c2
commit 82e4f70df1
2 changed files with 81 additions and 71 deletions
+32 -30
View File
@@ -1,9 +1,10 @@
/* /*
* Copyright 2008, Axel Dörfler, [email protected]. * Copyright 2008-2010, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
//! super block, mounting, etc.
//! Super block, mounting, etc.
#include "Volume.h" #include "Volume.h"
@@ -31,37 +32,37 @@
class DeviceOpener { class DeviceOpener {
public: public:
DeviceOpener(int fd, int mode); DeviceOpener(int fd, int mode);
DeviceOpener(const char *device, int mode); DeviceOpener(const char* device, int mode);
~DeviceOpener(); ~DeviceOpener();
int Open(const char *device, int mode); int Open(const char* device, int mode);
int Open(int fd, int mode); int Open(int fd, int mode);
void *InitCache(off_t numBlocks, uint32 blockSize); void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites); void RemoveCache(bool allowWrites);
void Keep(); void Keep();
int Device() const { return fDevice; } int Device() const { return fDevice; }
int Mode() const { return fMode; } int Mode() const { return fMode; }
bool IsReadOnly() const { return _IsReadOnly(fMode); } bool IsReadOnly() const { return _IsReadOnly(fMode); }
status_t GetSize(off_t *_size, uint32 *_blockSize = NULL); status_t GetSize(off_t* _size, uint32* _blockSize = NULL);
private: private:
static bool _IsReadOnly(int mode) static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY;} { return (mode & O_RWMASK) == O_RDONLY;}
static bool _IsReadWrite(int mode) static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR;} { return (mode & O_RWMASK) == O_RDWR;}
int fDevice; int fDevice;
int fMode; int fMode;
void *fBlockCache; void* fBlockCache;
}; };
DeviceOpener::DeviceOpener(const char *device, int mode) DeviceOpener::DeviceOpener(const char* device, int mode)
: :
fBlockCache(NULL) fBlockCache(NULL)
{ {
@@ -87,7 +88,7 @@ DeviceOpener::~DeviceOpener()
int int
DeviceOpener::Open(const char *device, int mode) DeviceOpener::Open(const char* device, int mode)
{ {
fDevice = open(device, mode | O_NOCACHE); fDevice = open(device, mode | O_NOCACHE);
if (fDevice < 0) if (fDevice < 0)
@@ -131,7 +132,7 @@ DeviceOpener::Open(int fd, int mode)
} }
void * void*
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize) DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
{ {
return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize, return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
@@ -161,7 +162,7 @@ DeviceOpener::Keep()
to compute the size, or fstat() if that failed. to compute the size, or fstat() if that failed.
*/ */
status_t status_t
DeviceOpener::GetSize(off_t *_size, uint32 *_blockSize) DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
{ {
device_geometry geometry; device_geometry geometry;
if (ioctl(fDevice, B_GET_GEOMETRY, &geometry) < 0) { if (ioctl(fDevice, B_GET_GEOMETRY, &geometry) < 0) {
@@ -304,7 +305,8 @@ Volume::Mount(const char* deviceName, uint32 flags)
if (diskSize < (NumBlocks() << BlockShift())) if (diskSize < (NumBlocks() << BlockShift()))
return B_BAD_VALUE; return B_BAD_VALUE;
if ((fBlockCache = opener.InitCache(NumBlocks(), fBlockSize)) == NULL) fBlockCache = opener.InitCache(NumBlocks(), fBlockSize);
if (fBlockCache == NULL)
return B_ERROR; return B_ERROR;
status = get_vnode(fFSVolume, EXT2_ROOT_NODE, (void**)&fRootNode); status = get_vnode(fFSVolume, EXT2_ROOT_NODE, (void**)&fRootNode);
@@ -339,8 +341,8 @@ Volume::Mount(const char* deviceName, uint32 flags)
status_t status_t
Volume::Unmount() Volume::Unmount()
{ {
//put_vnode(fVolume, ToVnode(Root())); put_vnode(fFSVolume, RootNode()->ID());
//block_cache_delete(fBlockCache, !IsReadOnly()); block_cache_delete(fBlockCache, !IsReadOnly());
close(fDevice); close(fDevice);
return B_OK; return B_OK;
+49 -41
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2008-2009, Axel Dörfler, [email protected]. * Copyright 2008-2010, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
#ifndef VOLUME_H #ifndef VOLUME_H
@@ -12,67 +12,75 @@
class Inode; class Inode;
enum volume_flags { enum volume_flags {
VOLUME_READ_ONLY = 0x0001 VOLUME_READ_ONLY = 0x0001
}; };
class Volume { class Volume {
public: public:
Volume(fs_volume* volume); Volume(fs_volume* volume);
~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
{ return (fFlags & VOLUME_READ_ONLY) != 0; }
Inode* RootNode() const { return fRootNode; } Inode* RootNode() const { return fRootNode; }
int Device() const { return fDevice; } int Device() const { return fDevice; }
dev_t ID() const { return fFSVolume ? fFSVolume->id : -1; } dev_t ID() const
fs_volume* FSVolume() const { return fFSVolume; } { return fFSVolume ? fFSVolume->id : -1; }
const char* Name() const; fs_volume* FSVolume() const { return fFSVolume; }
const char* Name() const;
off_t NumBlocks() const { return fSuperBlock.NumBlocks(); } off_t NumBlocks() const
off_t FreeBlocks() const { return fSuperBlock.FreeBlocks(); } { return fSuperBlock.NumBlocks(); }
off_t FreeBlocks() const
{ return fSuperBlock.FreeBlocks(); }
uint32 BlockSize() const { return fBlockSize; } uint32 BlockSize() const { return fBlockSize; }
uint32 BlockShift() const { return fBlockShift; } uint32 BlockShift() const { return fBlockShift; }
uint32 InodeSize() const { return fSuperBlock.InodeSize(); } uint32 InodeSize() const
ext2_super_block& SuperBlock() { return fSuperBlock; } { return fSuperBlock.InodeSize(); }
ext2_super_block& SuperBlock() { return fSuperBlock; }
status_t GetInodeBlock(ino_t id, uint32& block); status_t GetInodeBlock(ino_t id, uint32& block);
uint32 InodeBlockIndex(ino_t id) const; uint32 InodeBlockIndex(ino_t id) const;
status_t GetBlockGroup(int32 index, ext2_block_group** _group); status_t GetBlockGroup(int32 index,
ext2_block_group** _group);
// cache access // cache access
void* BlockCache() { return fBlockCache; } void* BlockCache() { return fBlockCache; }
static status_t Identify(int fd, ext2_super_block* superBlock); static status_t Identify(int fd, ext2_super_block* superBlock);
private: private:
static uint32 _UnsupportedIncompatibleFeatures( static uint32 _UnsupportedIncompatibleFeatures(
ext2_super_block& superBlock); ext2_super_block& superBlock);
off_t _GroupBlockOffset(uint32 blockIndex); off_t _GroupBlockOffset(uint32 blockIndex);
private: private:
mutex fLock; mutex fLock;
fs_volume* fFSVolume; fs_volume* fFSVolume;
int fDevice; int fDevice;
ext2_super_block fSuperBlock; ext2_super_block fSuperBlock;
char fName[32]; char fName[32];
uint32 fFlags; uint32 fFlags;
uint32 fBlockSize; uint32 fBlockSize;
uint32 fBlockShift; uint32 fBlockShift;
uint32 fFirstDataBlock; uint32 fFirstDataBlock;
uint32 fNumGroups; uint32 fNumGroups;
uint32 fGroupsPerBlock; uint32 fGroupsPerBlock;
ext2_block_group** fGroupBlocks; ext2_block_group** fGroupBlocks;
uint32 fInodesPerBlock; uint32 fInodesPerBlock;
void* fBlockCache; void* fBlockCache;
Inode* fRootNode; Inode* fRootNode;
}; };
#endif // VOLUME_H #endif // VOLUME_H