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 <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
e9c3e80c58
commit
d72239d23d
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2010, Axel Dörfler, [email protected].
|
||||||
|
* 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
|
||||||
@@ -34,6 +34,7 @@ local bfsSources =
|
|||||||
Attribute.cpp
|
Attribute.cpp
|
||||||
CheckVisitor.cpp
|
CheckVisitor.cpp
|
||||||
Debug.cpp
|
Debug.cpp
|
||||||
|
DeviceOpener.cpp
|
||||||
FileSystemVisitor.cpp
|
FileSystemVisitor.cpp
|
||||||
Index.cpp
|
Index.cpp
|
||||||
Inode.cpp
|
Inode.cpp
|
||||||
@@ -56,5 +57,5 @@ SEARCH on [ FGristFiles $(bfsSources) ]
|
|||||||
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
= [ 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 ] ;
|
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "Attribute.h"
|
#include "Attribute.h"
|
||||||
#include "CheckVisitor.h"
|
#include "CheckVisitor.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
#include "file_systems/DeviceOpener.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "Journal.h"
|
#include "Journal.h"
|
||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
@@ -28,165 +29,6 @@ static const int32 kDesiredAllocationGroups = 56;
|
|||||||
// blocks).
|
// 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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ KernelAddon btrfs :
|
|||||||
Chunk.cpp
|
Chunk.cpp
|
||||||
CRCTable.cpp
|
CRCTable.cpp
|
||||||
DebugSupport.cpp
|
DebugSupport.cpp
|
||||||
|
DeviceOpener.cpp
|
||||||
DirectoryIterator.cpp
|
DirectoryIterator.cpp
|
||||||
ExtentAllocator.cpp
|
ExtentAllocator.cpp
|
||||||
Inode.cpp
|
Inode.cpp
|
||||||
@@ -31,5 +32,8 @@ KernelAddon btrfs :
|
|||||||
libuuid_kernel.a
|
libuuid_kernel.a
|
||||||
;
|
;
|
||||||
|
|
||||||
|
SEARCH on [ FGristFiles DeviceOpener.cpp ]
|
||||||
|
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles DebugSupport.cpp ]
|
SEARCH on [ FGristFiles DebugSupport.cpp ]
|
||||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "CachedBlock.h"
|
#include "CachedBlock.h"
|
||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
#include "CRCTable.h"
|
#include "CRCTable.h"
|
||||||
|
#include "DeviceOpener.h"
|
||||||
#include "ExtentAllocator.h"
|
#include "ExtentAllocator.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "Journal.h"
|
#include "Journal.h"
|
||||||
@@ -35,166 +36,6 @@
|
|||||||
#endif
|
#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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,18 @@ SubDir HAIKU_TOP src add-ons kernel file_systems exfat ;
|
|||||||
|
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UsePrivateHeaders shared storage ;
|
UsePrivateHeaders shared storage ;
|
||||||
|
UsePrivateHeaders file_systems ;
|
||||||
UsePrivateKernelHeaders ;
|
UsePrivateKernelHeaders ;
|
||||||
|
|
||||||
KernelAddon exfat :
|
KernelAddon exfat :
|
||||||
DataStream.cpp
|
DataStream.cpp
|
||||||
|
DeviceOpener.cpp
|
||||||
DirectoryIterator.cpp
|
DirectoryIterator.cpp
|
||||||
Inode.cpp
|
Inode.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
Utility.cpp
|
Utility.cpp
|
||||||
Volume.cpp
|
Volume.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
|
SEARCH on [ FGristFiles DeviceOpener.cpp ]
|
||||||
|
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
#include "CachedBlock.h"
|
#include "CachedBlock.h"
|
||||||
|
#include "DeviceOpener.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
@@ -43,170 +44,6 @@
|
|||||||
# define ERROR(x...) dprintf("\33[34mexfat:\33[0m " x)
|
# 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
|
// #pragma mark - LabelVisitor
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,29 +3,32 @@ SubDir HAIKU_TOP src add-ons kernel file_systems ext2 ;
|
|||||||
#UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
|
#UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UsePrivateHeaders shared storage ;
|
UsePrivateHeaders shared storage ;
|
||||||
|
UsePrivateHeaders file_systems ;
|
||||||
UsePrivateKernelHeaders ;
|
UsePrivateKernelHeaders ;
|
||||||
|
|
||||||
KernelAddon ext2 :
|
KernelAddon ext2 :
|
||||||
Volume.cpp
|
|
||||||
DataStream.cpp
|
|
||||||
Inode.cpp
|
|
||||||
Attribute.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
|
BitmapBlock.cpp
|
||||||
BlockAllocator.cpp
|
BlockAllocator.cpp
|
||||||
InodeAllocator.cpp
|
|
||||||
CRCTable.cpp
|
|
||||||
|
|
||||||
kernel_interface.cpp
|
|
||||||
|
|
||||||
crc32.c
|
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 ] ;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "CachedBlock.h"
|
#include "CachedBlock.h"
|
||||||
#include "CRCTable.h"
|
#include "CRCTable.h"
|
||||||
|
#include "DeviceOpener.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "InodeJournal.h"
|
#include "InodeJournal.h"
|
||||||
#include "NoJournal.h"
|
#include "NoJournal.h"
|
||||||
@@ -37,165 +38,6 @@
|
|||||||
# define FATAL(x...) dprintf("\33[34mext2:\33[0m " x)
|
# 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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -2,13 +2,13 @@ SubDir HAIKU_TOP src add-ons kernel file_systems ufs2 ;
|
|||||||
|
|
||||||
# set some additional defines
|
# set some additional defines
|
||||||
{
|
{
|
||||||
local defines =
|
local defines =
|
||||||
UFS2_DEBUGGER_COMMANDS
|
UFS2_DEBUGGER_COMMANDS
|
||||||
;
|
;
|
||||||
|
|
||||||
defines = [ FDefines $(defines) ] ;
|
defines = [ FDefines $(defines) ] ;
|
||||||
SubDirCcFlags $(defines) ;
|
SubDirCcFlags $(defines) ;
|
||||||
SubDirC++Flags $(defines) ;
|
SubDirC++Flags $(defines) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
@@ -18,19 +18,19 @@ UsePrivateKernelHeaders ;
|
|||||||
DEFINES += DEBUG_APP="\\\"ufs2\\\"" ;
|
DEFINES += DEBUG_APP="\\\"ufs2\\\"" ;
|
||||||
|
|
||||||
local ufs2Sources =
|
local ufs2Sources =
|
||||||
Volume.cpp
|
DeviceOpener.cpp
|
||||||
kernel_cpp.cpp
|
Volume.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
;
|
;
|
||||||
KernelAddon ufs2 :
|
KernelAddon ufs2 :
|
||||||
$(ufs2Sources)
|
$(ufs2Sources)
|
||||||
:
|
:
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
SEARCH on [ FGristFiles $(ufs2Sources) ]
|
SEARCH on [ FGristFiles DeviceOpener.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems ufs2 ] ;
|
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
#SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP src system kernel util ] ;
|
# = [ FDirName $(HAIKU_TOP src system kernel util ] ;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
|
#include "DeviceOpener.h"
|
||||||
|
|
||||||
//#define TRACE_UFS2
|
//#define TRACE_UFS2
|
||||||
#ifdef TRACE_UFS2
|
#ifdef TRACE_UFS2
|
||||||
# define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
|
# define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
|
||||||
@@ -12,35 +14,6 @@
|
|||||||
#endif
|
#endif
|
||||||
# define ERROR(x...) dprintf("\33[34mexfat:\33[0m " x)
|
# 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
|
bool
|
||||||
ufs2_super_block::IsValid()
|
ufs2_super_block::IsValid()
|
||||||
@@ -51,6 +24,30 @@ ufs2_super_block::IsValid()
|
|||||||
return true;
|
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
|
status_t
|
||||||
Volume::Identify(int fd, ufs2_super_block *superBlock)
|
Volume::Identify(int fd, ufs2_super_block *superBlock)
|
||||||
{
|
{
|
||||||
@@ -65,3 +62,54 @@ Volume::Identify(int fd, ufs2_super_block *superBlock)
|
|||||||
|
|
||||||
return B_OK;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
#include "ufs2.h"
|
#include "ufs2.h"
|
||||||
|
|
||||||
|
enum volume_flags {
|
||||||
|
VOLUME_READ_ONLY = 0x0001
|
||||||
|
};
|
||||||
|
|
||||||
class Volume {
|
class Volume {
|
||||||
public:
|
public:
|
||||||
Volume(fs_volume* volume);
|
Volume(fs_volume* volume);
|
||||||
@@ -27,7 +31,10 @@ class Volume {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
fs_volume* fFSVolume;
|
fs_volume* fFSVolume;
|
||||||
|
int fDevice;
|
||||||
ufs2_super_block fSuperBlock;
|
ufs2_super_block fSuperBlock;
|
||||||
|
mutex fLock;
|
||||||
|
uint32 fFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VOLUME_H
|
#endif // VOLUME_H
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
|
|||||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
||||||
|
|
||||||
local xfsSources =
|
local xfsSources =
|
||||||
|
DeviceOpener.cpp
|
||||||
xfs.cpp
|
xfs.cpp
|
||||||
Volume.cpp
|
Volume.cpp
|
||||||
kernel_cpp.cpp
|
kernel_cpp.cpp
|
||||||
@@ -34,5 +35,8 @@ KernelAddon xfs :
|
|||||||
SEARCH on [ FGristFiles $(xfsSources) ]
|
SEARCH on [ FGristFiles $(xfsSources) ]
|
||||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ;
|
= [ 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 ]
|
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||||
@@ -4,166 +4,7 @@
|
|||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
#include "DeviceOpener.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Volume::Volume(fs_volume *volume)
|
Volume::Volume(fs_volume *volume)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ local btrfsSources =
|
|||||||
Chunk.cpp
|
Chunk.cpp
|
||||||
CRCTable.cpp
|
CRCTable.cpp
|
||||||
DebugSupport.cpp
|
DebugSupport.cpp
|
||||||
|
DeviceOpener.cpp
|
||||||
DirectoryIterator.cpp
|
DirectoryIterator.cpp
|
||||||
ExtentAllocator.cpp
|
ExtentAllocator.cpp
|
||||||
Inode.cpp
|
Inode.cpp
|
||||||
@@ -75,3 +76,6 @@ SEARCH on [ FGristFiles $(utilitySources) ]
|
|||||||
+= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
+= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||||
SEARCH on [ FGristFiles DebugSupport.cpp ]
|
SEARCH on [ FGristFiles DebugSupport.cpp ]
|
||||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
+= [ 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 ] ;
|
||||||
|
|||||||
@@ -34,11 +34,13 @@ if ! $(HOST_PLATFORM_HAIKU_COMPATIBLE) {
|
|||||||
|
|
||||||
UsePrivateHeaders shared storage ;
|
UsePrivateHeaders shared storage ;
|
||||||
UsePrivateHeaders fs_shell ;
|
UsePrivateHeaders fs_shell ;
|
||||||
|
UsePrivateHeaders file_systems ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
||||||
|
|
||||||
local ufs2Source =
|
local ufs2Source =
|
||||||
Volume.cpp
|
DeviceOpener.cpp
|
||||||
|
Volume.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -63,3 +65,6 @@ BuildPlatformMain <build>ufs2_fuse
|
|||||||
|
|
||||||
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
|
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
|
||||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
+= [ 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 ] ;
|
||||||
|
|||||||
@@ -34,10 +34,12 @@ if ! $(HOST_PLATFORM_HAIKU_COMPATIBLE) {
|
|||||||
|
|
||||||
UsePrivateHeaders shared storage ;
|
UsePrivateHeaders shared storage ;
|
||||||
UsePrivateHeaders fs_shell ;
|
UsePrivateHeaders fs_shell ;
|
||||||
|
UsePrivateHeaders file_systems ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
||||||
|
|
||||||
local xfsSource =
|
local xfsSource =
|
||||||
|
DeviceOpener.cpp
|
||||||
xfs.cpp
|
xfs.cpp
|
||||||
Volume.cpp
|
Volume.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
@@ -64,3 +66,6 @@ BuildPlatformMain <build>xfs_fuse
|
|||||||
|
|
||||||
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
|
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
|
||||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
+= [ 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 ] ;
|
||||||
Reference in New Issue
Block a user