Move DeviceOpener class to a separate file.

It is used by several of the filesystems, so it seems a good idea to
move it to the shared/ directory.

UFS2, BFS, XFS, EXT2 and EXFAT are adjusted.

Change-Id: I493e37a1e7d3ae24251469f82befd985a3c1dbdd
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2489
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Suhel Mehta 2020-04-18 00:44:43 +05:30 committed by Adrien Destugues
parent e9c3e80c58
commit d72239d23d
19 changed files with 368 additions and 867 deletions

View File

@ -0,0 +1,43 @@
/*
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef DEVICEOPENER_H
#define DEVICEOPENER_H
#include "system_dependencies.h"
class DeviceOpener {
public:
DeviceOpener(int fd, int mode);
DeviceOpener(const char* device, int mode);
~DeviceOpener();
int Open(const char* device, int mode);
int Open(int fd, int mode);
void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites);
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const {
return _IsReadOnly(fMode); }
status_t GetSize(off_t* _size,
uint32* _blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY; }
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR; }
int fDevice;
int fMode;
void* fBlockCache;
};
#endif // DEVICEOPENER_H

View File

@ -34,6 +34,7 @@ local bfsSources =
Attribute.cpp
CheckVisitor.cpp
Debug.cpp
DeviceOpener.cpp
FileSystemVisitor.cpp
Index.cpp
Inode.cpp
@ -56,5 +57,5 @@ SEARCH on [ FGristFiles $(bfsSources) ]
SEARCH on [ FGristFiles kernel_cpp.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
SEARCH on [ FGristFiles QueryParserUtils.cpp DeviceOpener.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -10,6 +10,7 @@
#include "Attribute.h"
#include "CheckVisitor.h"
#include "Debug.h"
#include "file_systems/DeviceOpener.h"
#include "Inode.h"
#include "Journal.h"
#include "Query.h"
@ -28,165 +29,6 @@ static const int32 kDesiredAllocationGroups = 56;
// blocks).
class DeviceOpener {
public:
DeviceOpener(int fd, int mode);
DeviceOpener(const char* device, int mode);
~DeviceOpener();
int Open(const char* device, int mode);
int Open(int fd, int mode);
void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites);
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const { return _IsReadOnly(fMode); }
status_t GetSize(off_t* _size, uint32* _blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY;}
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR;}
int fDevice;
int fMode;
void* fBlockCache;
};
DeviceOpener::DeviceOpener(const char* device, int mode)
:
fBlockCache(NULL)
{
Open(device, mode);
}
DeviceOpener::DeviceOpener(int fd, int mode)
:
fBlockCache(NULL)
{
Open(fd, mode);
}
DeviceOpener::~DeviceOpener()
{
if (fDevice >= 0) {
RemoveCache(false);
close(fDevice);
}
}
int
DeviceOpener::Open(const char* device, int mode)
{
fDevice = open(device, mode | O_NOCACHE);
if (fDevice < 0)
fDevice = errno;
if (fDevice < 0 && _IsReadWrite(mode)) {
// try again to open read-only (don't rely on a specific error code)
return Open(device, O_RDONLY | O_NOCACHE);
}
if (fDevice >= 0) {
// opening succeeded
fMode = mode;
if (_IsReadWrite(mode)) {
// check out if the device really allows for read/write access
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry))) {
if (geometry.read_only) {
// reopen device read-only
close(fDevice);
return Open(device, O_RDONLY | O_NOCACHE);
}
}
}
}
return fDevice;
}
int
DeviceOpener::Open(int fd, int mode)
{
fDevice = dup(fd);
if (fDevice < 0)
return errno;
fMode = mode;
return fDevice;
}
void*
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
{
return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
IsReadOnly());
}
void
DeviceOpener::RemoveCache(bool allowWrites)
{
if (fBlockCache == NULL)
return;
block_cache_delete(fBlockCache, allowWrites);
fBlockCache = NULL;
}
void
DeviceOpener::Keep()
{
fDevice = -1;
}
/*! Returns the size of the device in bytes. It uses B_GET_GEOMETRY
to compute the size, or fstat() if that failed.
*/
status_t
DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
{
device_geometry geometry;
if (ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry)) < 0) {
// maybe it's just a file
struct stat stat;
if (fstat(fDevice, &stat) < 0)
return B_ERROR;
if (_size)
*_size = stat.st_size;
if (_blockSize) // that shouldn't cause us any problems
*_blockSize = 512;
return B_OK;
}
if (_size) {
*_size = 1LL * geometry.head_count * geometry.cylinder_count
* geometry.sectors_per_track * geometry.bytes_per_sector;
}
if (_blockSize)
*_blockSize = geometry.bytes_per_sector;
return B_OK;
}
// #pragma mark -

View File

@ -21,6 +21,7 @@ KernelAddon btrfs :
Chunk.cpp
CRCTable.cpp
DebugSupport.cpp
DeviceOpener.cpp
DirectoryIterator.cpp
ExtentAllocator.cpp
Inode.cpp
@ -31,5 +32,8 @@ KernelAddon btrfs :
libuuid_kernel.a
;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
SEARCH on [ FGristFiles DebugSupport.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -16,6 +16,7 @@
#include "CachedBlock.h"
#include "Chunk.h"
#include "CRCTable.h"
#include "DeviceOpener.h"
#include "ExtentAllocator.h"
#include "Inode.h"
#include "Journal.h"
@ -35,166 +36,6 @@
#endif
class DeviceOpener {
public:
DeviceOpener(int fd, int mode);
DeviceOpener(const char* device, int mode);
~DeviceOpener();
int Open(const char* device, int mode);
int Open(int fd, int mode);
void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites);
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const
{ return _IsReadOnly(fMode); }
status_t GetSize(off_t* _size, uint32* _blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY;}
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR;}
int fDevice;
int fMode;
void* fBlockCache;
};
DeviceOpener::DeviceOpener(const char* device, int mode)
:
fBlockCache(NULL)
{
Open(device, mode);
}
DeviceOpener::DeviceOpener(int fd, int mode)
:
fBlockCache(NULL)
{
Open(fd, mode);
}
DeviceOpener::~DeviceOpener()
{
if (fDevice >= 0) {
RemoveCache(false);
close(fDevice);
}
}
int
DeviceOpener::Open(const char* device, int mode)
{
fDevice = open(device, mode | O_NOCACHE);
if (fDevice < 0)
fDevice = errno;
if (fDevice < 0 && _IsReadWrite(mode)) {
// try again to open read-only (don't rely on a specific error code)
return Open(device, O_RDONLY | O_NOCACHE);
}
if (fDevice >= 0) {
// opening succeeded
fMode = mode;
if (_IsReadWrite(mode)) {
// check out if the device really allows for read/write access
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry))) {
if (geometry.read_only) {
// reopen device read-only
close(fDevice);
return Open(device, O_RDONLY | O_NOCACHE);
}
}
}
}
return fDevice;
}
int
DeviceOpener::Open(int fd, int mode)
{
fDevice = dup(fd);
if (fDevice < 0)
return errno;
fMode = mode;
return fDevice;
}
void*
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
{
return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
IsReadOnly());
}
void
DeviceOpener::RemoveCache(bool allowWrites)
{
if (fBlockCache == NULL)
return;
block_cache_delete(fBlockCache, allowWrites);
fBlockCache = NULL;
}
void
DeviceOpener::Keep()
{
fDevice = -1;
}
/*! Returns the size of the device in bytes. It uses B_GET_GEOMETRY
to compute the size, or fstat() if that failed.
*/
status_t
DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
{
device_geometry geometry;
if (ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry)) < 0) {
// maybe it's just a file
struct stat stat;
if (fstat(fDevice, &stat) < 0)
return B_ERROR;
if (_size)
*_size = stat.st_size;
if (_blockSize) // that shouldn't cause us any problems
*_blockSize = 512;
return B_OK;
}
if (_size) {
*_size = 1ULL * geometry.head_count * geometry.cylinder_count
* geometry.sectors_per_track * geometry.bytes_per_sector;
}
if (_blockSize)
*_blockSize = geometry.bytes_per_sector;
return B_OK;
}
// #pragma mark -

View File

@ -2,13 +2,18 @@ SubDir HAIKU_TOP src add-ons kernel file_systems exfat ;
UsePrivateHeaders [ FDirName kernel util ] ;
UsePrivateHeaders shared storage ;
UsePrivateHeaders file_systems ;
UsePrivateKernelHeaders ;
KernelAddon exfat :
DataStream.cpp
DeviceOpener.cpp
DirectoryIterator.cpp
Inode.cpp
kernel_interface.cpp
Utility.cpp
Volume.cpp
;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -30,6 +30,7 @@
#include <util/AutoLock.h>
#include "CachedBlock.h"
#include "DeviceOpener.h"
#include "Inode.h"
#include "Utility.h"
@ -43,170 +44,6 @@
# define ERROR(x...) dprintf("\33[34mexfat:\33[0m " x)
class DeviceOpener {
public:
DeviceOpener(int fd, int mode);
DeviceOpener(const char* device, int mode);
~DeviceOpener();
int Open(const char* device, int mode);
int Open(int fd, int mode);
void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites);
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const
{ return _IsReadOnly(fMode); }
status_t GetSize(off_t* _size,
uint32* _blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY;}
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR;}
int fDevice;
int fMode;
void* fBlockCache;
};
// #pragma mark - DeviceOpener
DeviceOpener::DeviceOpener(const char* device, int mode)
:
fBlockCache(NULL)
{
Open(device, mode);
}
DeviceOpener::DeviceOpener(int fd, int mode)
:
fBlockCache(NULL)
{
Open(fd, mode);
}
DeviceOpener::~DeviceOpener()
{
if (fDevice >= 0) {
RemoveCache(false);
close(fDevice);
}
}
int
DeviceOpener::Open(const char* device, int mode)
{
fDevice = open(device, mode | O_NOCACHE);
if (fDevice < 0)
fDevice = errno;
if (fDevice < 0 && _IsReadWrite(mode)) {
// try again to open read-only (don't rely on a specific error code)
return Open(device, O_RDONLY | O_NOCACHE);
}
if (fDevice >= 0) {
// opening succeeded
fMode = mode;
if (_IsReadWrite(mode)) {
// check out if the device really allows for read/write access
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry))) {
if (geometry.read_only) {
// reopen device read-only
close(fDevice);
return Open(device, O_RDONLY | O_NOCACHE);
}
}
}
}
return fDevice;
}
int
DeviceOpener::Open(int fd, int mode)
{
fDevice = dup(fd);
if (fDevice < 0)
return errno;
fMode = mode;
return fDevice;
}
void*
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
{
return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
IsReadOnly());
}
void
DeviceOpener::RemoveCache(bool allowWrites)
{
if (fBlockCache == NULL)
return;
block_cache_delete(fBlockCache, allowWrites);
fBlockCache = NULL;
}
void
DeviceOpener::Keep()
{
fDevice = -1;
}
/*! Returns the size of the device in bytes. It uses B_GET_GEOMETRY
to compute the size, or fstat() if that failed.
*/
status_t
DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
{
device_geometry geometry;
if (ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry)) < 0) {
// maybe it's just a file
struct stat stat;
if (fstat(fDevice, &stat) < 0)
return B_ERROR;
if (_size)
*_size = stat.st_size;
if (_blockSize) // that shouldn't cause us any problems
*_blockSize = 512;
return B_OK;
}
if (_size) {
*_size = 1ULL * geometry.head_count * geometry.cylinder_count
* geometry.sectors_per_track * geometry.bytes_per_sector;
}
if (_blockSize)
*_blockSize = geometry.bytes_per_sector;
return B_OK;
}
// #pragma mark - LabelVisitor

View File

@ -3,29 +3,32 @@ SubDir HAIKU_TOP src add-ons kernel file_systems ext2 ;
#UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
UsePrivateHeaders [ FDirName kernel util ] ;
UsePrivateHeaders shared storage ;
UsePrivateHeaders file_systems ;
UsePrivateKernelHeaders ;
KernelAddon ext2 :
Volume.cpp
DataStream.cpp
Inode.cpp
Attribute.cpp
DirectoryIterator.cpp
ExtentStream.cpp
HTree.cpp
HTreeEntryIterator.cpp
RevokeManager.cpp
HashRevokeManager.cpp
Journal.cpp
NoJournal.cpp
InodeJournal.cpp
Transaction.cpp
BitmapBlock.cpp
BlockAllocator.cpp
InodeAllocator.cpp
CRCTable.cpp
kernel_interface.cpp
crc32.c
CRCTable.cpp
DataStream.cpp
DeviceOpener.cpp
DirectoryIterator.cpp
ExtentStream.cpp
HashRevokeManager.cpp
HTree.cpp
HTreeEntryIterator.cpp
Inode.cpp
InodeAllocator.cpp
InodeJournal.cpp
Journal.cpp
kernel_interface.cpp
NoJournal.cpp
RevokeManager.cpp
Transaction.cpp
Volume.cpp
;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -23,6 +23,7 @@
#include "CachedBlock.h"
#include "CRCTable.h"
#include "DeviceOpener.h"
#include "Inode.h"
#include "InodeJournal.h"
#include "NoJournal.h"
@ -37,165 +38,6 @@
# define FATAL(x...) dprintf("\33[34mext2:\33[0m " x)
class DeviceOpener {
public:
DeviceOpener(int fd, int mode);
DeviceOpener(const char* device, int mode);
~DeviceOpener();
int Open(const char* device, int mode);
int Open(int fd, int mode);
void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites);
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const { return _IsReadOnly(fMode); }
status_t GetSize(off_t* _size, uint32* _blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY;}
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR;}
int fDevice;
int fMode;
void* fBlockCache;
};
DeviceOpener::DeviceOpener(const char* device, int mode)
:
fBlockCache(NULL)
{
Open(device, mode);
}
DeviceOpener::DeviceOpener(int fd, int mode)
:
fBlockCache(NULL)
{
Open(fd, mode);
}
DeviceOpener::~DeviceOpener()
{
if (fDevice >= 0) {
RemoveCache(false);
close(fDevice);
}
}
int
DeviceOpener::Open(const char* device, int mode)
{
fDevice = open(device, mode | O_NOCACHE);
if (fDevice < 0)
fDevice = errno;
if (fDevice < 0 && _IsReadWrite(mode)) {
// try again to open read-only (don't rely on a specific error code)
return Open(device, O_RDONLY | O_NOCACHE);
}
if (fDevice >= 0) {
// opening succeeded
fMode = mode;
if (_IsReadWrite(mode)) {
// check out if the device really allows for read/write access
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry))) {
if (geometry.read_only) {
// reopen device read-only
close(fDevice);
return Open(device, O_RDONLY | O_NOCACHE);
}
}
}
}
return fDevice;
}
int
DeviceOpener::Open(int fd, int mode)
{
fDevice = dup(fd);
if (fDevice < 0)
return errno;
fMode = mode;
return fDevice;
}
void*
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
{
return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
IsReadOnly());
}
void
DeviceOpener::RemoveCache(bool allowWrites)
{
if (fBlockCache == NULL)
return;
block_cache_delete(fBlockCache, allowWrites);
fBlockCache = NULL;
}
void
DeviceOpener::Keep()
{
fDevice = -1;
}
/*! Returns the size of the device in bytes. It uses B_GET_GEOMETRY
to compute the size, or fstat() if that failed.
*/
status_t
DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
{
device_geometry geometry;
if (ioctl(fDevice, B_GET_GEOMETRY, &geometry, sizeof(device_geometry)) < 0) {
// maybe it's just a file
struct stat stat;
if (fstat(fDevice, &stat) < 0)
return B_ERROR;
if (_size)
*_size = stat.st_size;
if (_blockSize) // that shouldn't cause us any problems
*_blockSize = 512;
return B_OK;
}
if (_size) {
*_size = 1ULL * geometry.head_count * geometry.cylinder_count
* geometry.sectors_per_track * geometry.bytes_per_sector;
}
if (_blockSize)
*_blockSize = geometry.bytes_per_sector;
return B_OK;
}
// #pragma mark -

View File

@ -0,0 +1,131 @@
/*
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "system_dependencies.h"
#include "file_systems/DeviceOpener.h"
DeviceOpener::DeviceOpener(const char* device, int mode)
:
fBlockCache(NULL)
{
Open(device, mode);
}
DeviceOpener::DeviceOpener(int fd, int mode)
:
fBlockCache(NULL)
{
Open(fd, mode);
}
DeviceOpener::~DeviceOpener()
{
if (fDevice >= 0){
RemoveCache(false);
close(fDevice);
}
}
int
DeviceOpener::Open(const char* device, int mode)
{
fDevice = open(device, mode | O_NOCACHE);
if (fDevice < 0)
fDevice = errno;
if (fDevice < 0 && _IsReadWrite(mode)) {
return Open(device, O_RDONLY | O_NOCACHE);
}
if (fDevice >= 0) {
fMode = mode;
if (_IsReadWrite(mode)) {
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry,
sizeof(device_geometry)))
{
if (geometry.read_only) {
close(fDevice);
return Open(device, O_RDONLY | O_NOCACHE);
}
}
}
}
return fDevice;
}
int
DeviceOpener::Open(int fd, int mode)
{
fDevice = dup(fd);
if (fDevice < 0)
return errno;
fMode = mode;
return fDevice;
}
void*
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
{
return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
IsReadOnly());
}
void
DeviceOpener::RemoveCache(bool allowWrites)
{
if (fBlockCache == NULL)
return;
block_cache_delete(fBlockCache, allowWrites);
fBlockCache = NULL;
}
void
DeviceOpener::Keep()
{
fDevice = -1;
}
status_t
DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
{
device_geometry geometry;
if (ioctl(fDevice, B_GET_GEOMETRY, &geometry,
sizeof(device_geometry)) < 0) {
// maybe it's just a file
struct stat stat;
if (fstat(fDevice, &stat) < 0)
return B_ERROR;
if (_size)
*_size = stat.st_size;
if (_blockSize) // that shouldn't cause us any problems
*_blockSize = 512;
return B_OK;
}
if (_size) {
*_size = 1ULL * geometry.head_count * geometry.cylinder_count
* geometry.sectors_per_track * geometry.bytes_per_sector;
}
if (_blockSize)
*_blockSize = geometry.bytes_per_sector;
return B_OK;
}

View File

@ -0,0 +1,38 @@
#ifndef _SYSTEM_DEPENDENCIES_H
#define _SYSTEM_DEPENDENCIES_H
#ifdef FS_SHELL
// This needs to be included before the fs_shell wrapper
#include "fssh_api_wrapper.h"
#include "fssh_auto_deleter.h"
//#include <new>
#else // !FS_SHELL
#include <AutoDeleter.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
#include <util/SinglyLinkedList.h>
#include <util/Stack.h>
#include <ByteOrder.h>
#include <tracing.h>
#include <driver_settings.h>
#include <fs_attr.h>
#include <fs_cache.h>
#include <fs_index.h>
#include <fs_info.h>
#include <fs_interface.h>
#include <fs_query.h>
#include <fs_volume.h>
#include <Drivers.h>
#include <errno.h>
#include <KernelExport.h>
#include <NodeMonitor.h>
#include <SupportDefs.h>
#include <TypeConstants.h>
#endif // !FS_SHELL
#endif // _SYSTEM_DEPENDENCIES

View File

@ -2,13 +2,13 @@ SubDir HAIKU_TOP src add-ons kernel file_systems ufs2 ;
# set some additional defines
{
local defines =
UFS2_DEBUGGER_COMMANDS
;
local defines =
UFS2_DEBUGGER_COMMANDS
;
defines = [ FDefines $(defines) ] ;
SubDirCcFlags $(defines) ;
SubDirC++Flags $(defines) ;
defines = [ FDefines $(defines) ] ;
SubDirCcFlags $(defines) ;
SubDirC++Flags $(defines) ;
}
UsePrivateHeaders [ FDirName kernel util ] ;
@ -18,19 +18,19 @@ UsePrivateKernelHeaders ;
DEFINES += DEBUG_APP="\\\"ufs2\\\"" ;
local ufs2Sources =
Volume.cpp
kernel_cpp.cpp
kernel_interface.cpp
;
DeviceOpener.cpp
Volume.cpp
kernel_interface.cpp
;
KernelAddon ufs2 :
$(ufs2Sources)
:
$(ufs2Sources)
:
;
SEARCH on [ FGristFiles $(ufs2Sources) ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems ufs2 ] ;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
SEARCH on [ FGristFiles kernel_cpp.cpp ]
= [ FDirName $(HAIKU_TOP src system kernel util ] ;
#SEARCH on [ FGristFiles kernel_cpp.cpp ]
# = [ FDirName $(HAIKU_TOP src system kernel util ] ;

View File

@ -4,6 +4,8 @@
*/
#include "Volume.h"
#include "DeviceOpener.h"
//#define TRACE_UFS2
#ifdef TRACE_UFS2
# define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
@ -12,35 +14,6 @@
#endif
# define ERROR(x...) dprintf("\33[34mexfat:\33[0m " x)
class DeviceOpner {
public:
DeviceOpner(int fd, int mode);
DeviceOpner(const char* device, int mode);
~DeviceOpner();
int Open(const char* device, int mode);
int Open(int fd, int mode);
void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites);
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const { return _IsReadOnly(fMode); }
status_t GetSize(off_t* _size, uint32* _blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY; }
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR; }
int fDevice;
int fMode;
void* fBlockCache;
};
bool
ufs2_super_block::IsValid()
@ -51,6 +24,30 @@ ufs2_super_block::IsValid()
return true;
}
bool
Volume::IsValidSuperBlock()
{
return fSuperBlock.IsValid();
}
Volume::Volume(fs_volume *volume)
: fFSVolume(volume)
{
fFlags = 0;
mutex_init(&fLock, "ufs2 volume");
TRACE("Volume::Volume() : Initialising volume");
}
Volume::~Volume()
{
mutex_destroy(&fLock);
TRACE("Volume::Destructor : Removing Volume");
}
status_t
Volume::Identify(int fd, ufs2_super_block *superBlock)
{
@ -65,3 +62,54 @@ Volume::Identify(int fd, ufs2_super_block *superBlock)
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");
opener.Keep();
return B_OK;
}
status_t
Volume::Unmount()
{
TRACE("Unmounting the volume");
TRACE("Closing device");
close(fDevice);
return B_OK;
}

View File

@ -7,6 +7,10 @@
#include "ufs2.h"
enum volume_flags {
VOLUME_READ_ONLY = 0x0001
};
class Volume {
public:
Volume(fs_volume* volume);
@ -27,7 +31,10 @@ class Volume {
private:
fs_volume* fFSVolume;
int fDevice;
ufs2_super_block fSuperBlock;
mutex fLock;
uint32 fFlags;
};
#endif // VOLUME_H

View File

@ -20,6 +20,7 @@ DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
local xfsSources =
DeviceOpener.cpp
xfs.cpp
Volume.cpp
kernel_cpp.cpp
@ -34,5 +35,8 @@ KernelAddon xfs :
SEARCH on [ FGristFiles $(xfsSources) ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
SEARCH on [ FGristFiles kernel_cpp.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;

View File

@ -4,166 +4,7 @@
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "Volume.h"
class DeviceOpener
{
public:
DeviceOpener(int fd, int mode);
DeviceOpener(const char *device, int mode);
~DeviceOpener();
int Open(const char *device, int mode);
int Open(int fd, int mode);
void* InitCache(off_t numBlocks, uint32 blockSize);
void RemoveCache(bool allowWrites);
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const
{ return _IsReadOnly(fMode); }
status_t GetSize(off_t* _size, uint32* _blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY; }
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR; }
int fDevice;
int fMode;
void* fBlockCache;
};
DeviceOpener::DeviceOpener(const char *device, int mode)
: fBlockCache(NULL)
{
Open(device, mode);
}
DeviceOpener::DeviceOpener(int fd, int mode)
: fBlockCache(NULL)
{
Open(fd, mode);
}
DeviceOpener::~DeviceOpener()
{
if (fDevice >= 0) {
RemoveCache(false);
close(fDevice);
}
}
int
DeviceOpener::Open(const char *device, int mode)
{
fDevice = open(device, mode | O_NOCACHE);
if (fDevice < 0)
fDevice = errno;
if (fDevice < 0 && _IsReadWrite(mode)){
// try again to open read-only (don't rely on a specific error code)
return Open(device, O_RDONLY | O_NOCACHE);
}
if (fDevice >= 0) {
// opening succeeded
fMode = mode;
if (_IsReadWrite(mode)) {
// check out if the device really allows for read/write access
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry)) {
if (geometry.read_only) {
// reopen device read-only
close(fDevice);
return Open(device, O_RDONLY | O_NOCACHE);
}
}
}
}
return fDevice;
}
int
DeviceOpener::Open(int fd, int mode)
{
fDevice = dup(fd);
if (fDevice < 0)
return errno;
fMode = mode;
return fDevice;
}
void*
DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
{
return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
IsReadOnly());
}
void
DeviceOpener::RemoveCache(bool allowWrites)
{
if (fBlockCache == NULL)
return;
block_cache_delete(fBlockCache, allowWrites);
fBlockCache = NULL;
}
void
DeviceOpener::Keep()
{
fDevice = -1;
}
/*! Returns the size of the device in bytes. It uses B_GET_GEOMETRY
to compute the size, or fstat() if that failed.
*/
status_t
DeviceOpener::GetSize(off_t *_size, uint32 *_blockSize)
{
device_geometry geometry;
if (ioctl(fDevice, B_GET_GEOMETRY, &geometry) < 0) {
// maybe it's just a file
struct stat stat;
if (fstat(fDevice, &stat) < 0)
return B_ERROR;
if (_size)
*_size = stat.st_size;
if (_blockSize) // that shouldn't cause us any problems
*_blockSize = 512;
return B_OK;
}
if (_size) {
*_size = 1LL * geometry.head_count * geometry.cylinder_count
* geometry.sectors_per_track * geometry.bytes_per_sector;
}
if (_blockSize)
*_blockSize = geometry.bytes_per_sector;
return B_OK;
}
#include "DeviceOpener.h"
Volume::Volume(fs_volume *volume)

View File

@ -47,6 +47,7 @@ local btrfsSources =
Chunk.cpp
CRCTable.cpp
DebugSupport.cpp
DeviceOpener.cpp
DirectoryIterator.cpp
ExtentAllocator.cpp
Inode.cpp
@ -75,3 +76,6 @@ SEARCH on [ FGristFiles $(utilitySources) ]
+= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles DebugSupport.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -34,11 +34,13 @@ if ! $(HOST_PLATFORM_HAIKU_COMPATIBLE) {
UsePrivateHeaders shared storage ;
UsePrivateHeaders fs_shell ;
UsePrivateHeaders file_systems ;
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
local ufs2Source =
Volume.cpp
DeviceOpener.cpp
Volume.cpp
kernel_interface.cpp
;
@ -63,3 +65,6 @@ BuildPlatformMain <build>ufs2_fuse
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

View File

@ -34,10 +34,12 @@ if ! $(HOST_PLATFORM_HAIKU_COMPATIBLE) {
UsePrivateHeaders shared storage ;
UsePrivateHeaders fs_shell ;
UsePrivateHeaders file_systems ;
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
local xfsSource =
DeviceOpener.cpp
xfs.cpp
Volume.cpp
kernel_interface.cpp
@ -64,3 +66,6 @@ BuildPlatformMain <build>xfs_fuse
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
SEARCH on [ FGristFiles DeviceOpener.cpp ]
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;