#include "Volume.h"
#include "DeviceOpener.h"
#include "Inode.h"
#define TRACE_UFS2
#ifdef TRACE_UFS2
#define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x);
#else
#define TRACE(x...) ;
#endif
#define ERROR(x...) dprintf("\33[34mufs2:\33[0m " x)
bool
ufs2_super_block::IsMagicValid()
{
return fs_magic == FS_UFS2_MAGIC;
}
bool
ufs2_super_block::IsValid()
{
return IsMagicValid();
}
const char*
Volume::Name() const
{
return fSuperBlock.fs_volname;
}
bool
Volume::IsValidSuperBlock()
{
return fSuperBlock.IsValid();
}
Volume::Volume(fs_volume *volume)
: fFSVolume(volume),
fRootNode(NULL)
{
fFlags = 0;
mutex_init(&fLock, "ufs2 volume");
TRACE("Volume::Volume() : Initialising volume\n");
}
Volume::~Volume()
{
mutex_destroy(&fLock);
TRACE("Volume::Destructor : Removing Volume\n");
}
status_t
Volume::Identify(int fd, ufs2_super_block *superBlock)
{
if (read_pos(fd, SBLOCK_UFS2, superBlock,
sizeof(ufs2_super_block)) != sizeof(ufs2_super_block))
return B_IO_ERROR;
if (!superBlock->IsMagicValid())
return B_BAD_VALUE;
if (!superBlock->IsValid()) {
ERROR("Invalid superblock! Identify failed!!\n");
return B_BAD_VALUE;
}
return B_OK;
}
status_t
Volume::Mount(const char *deviceName, uint32 flags)
{
TRACE("Mounting volume... Please wait.\n");
flags |= B_MOUNT_READ_ONLY;
if ((flags & B_MOUNT_READ_ONLY) != 0)
{
TRACE("Volume is read only\n");
}
else
{
TRACE("Volume is read write\n");
}
DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0
? O_RDONLY:O_RDWR);
fDevice = opener.Device();
if (fDevice < B_OK) {
ERROR("Could not open device\n");
return fDevice;
}
if (opener.IsReadOnly())
fFlags |= VOLUME_READ_ONLY;
status_t status = Identify(fDevice, &fSuperBlock);
if (status != B_OK) {
ERROR("Invalid super block\n");
return status;
}
TRACE("Valid super block\n");
fRootNode = new(std::nothrow) Inode(this, UFS2_ROOT);
status = publish_vnode(this->FSVolume(), UFS2_ROOT, (void*)fRootNode,
&gufs2VnodeOps, fRootNode->Mode(), 0);
opener.Keep();
return B_OK;
}
status_t
Volume::Unmount()
{
TRACE("Unmounting the volume");
TRACE("Closing device");
close(fDevice);
return B_OK;
}