From d72239d23d37436ce8e7e230056136a858c0ec79 Mon Sep 17 00:00:00 2001 From: Suhel Mehta Date: Sat, 18 Apr 2020 00:44:43 +0530 Subject: [PATCH] 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 --- headers/private/file_systems/DeviceOpener.h | 43 +++++ src/add-ons/kernel/file_systems/bfs/JamCommon | 3 +- .../kernel/file_systems/bfs/Volume.cpp | 160 +---------------- src/add-ons/kernel/file_systems/btrfs/Jamfile | 4 + .../kernel/file_systems/btrfs/Volume.cpp | 161 +---------------- src/add-ons/kernel/file_systems/exfat/Jamfile | 5 + .../kernel/file_systems/exfat/Volume.cpp | 165 +----------------- src/add-ons/kernel/file_systems/ext2/Jamfile | 39 +++-- .../kernel/file_systems/ext2/Volume.cpp | 160 +---------------- .../file_systems/shared/DeviceOpener.cpp | 131 ++++++++++++++ .../file_systems/shared/system_dependencies.h | 38 ++++ src/add-ons/kernel/file_systems/ufs2/Jamfile | 32 ++-- .../kernel/file_systems/ufs2/Volume.cpp | 106 ++++++++--- src/add-ons/kernel/file_systems/ufs2/Volume.h | 7 + src/add-ons/kernel/file_systems/xfs/Jamfile | 4 + .../kernel/file_systems/xfs/Volume.cpp | 161 +---------------- .../file_systems/btrfs/btrfs_shell/Jamfile | 4 + .../file_systems/ufs2/ufs2_shell/Jamfile | 7 +- .../kernel/file_systems/xfs/xfs_shell/Jamfile | 5 + 19 files changed, 368 insertions(+), 867 deletions(-) create mode 100644 headers/private/file_systems/DeviceOpener.h create mode 100644 src/add-ons/kernel/file_systems/shared/DeviceOpener.cpp create mode 100644 src/add-ons/kernel/file_systems/shared/system_dependencies.h diff --git a/headers/private/file_systems/DeviceOpener.h b/headers/private/file_systems/DeviceOpener.h new file mode 100644 index 0000000000..6f71aa8131 --- /dev/null +++ b/headers/private/file_systems/DeviceOpener.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/bfs/JamCommon b/src/add-ons/kernel/file_systems/bfs/JamCommon index 9996156edb..b2656e59e6 100644 --- a/src/add-ons/kernel/file_systems/bfs/JamCommon +++ b/src/add-ons/kernel/file_systems/bfs/JamCommon @@ -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 ] ; diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index 2b06068c3f..427c2b6d65 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -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 - diff --git a/src/add-ons/kernel/file_systems/btrfs/Jamfile b/src/add-ons/kernel/file_systems/btrfs/Jamfile index 7789a606cf..22c23f3a73 100644 --- a/src/add-ons/kernel/file_systems/btrfs/Jamfile +++ b/src/add-ons/kernel/file_systems/btrfs/Jamfile @@ -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 ] ; diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp index bb82094ebe..6258ad9111 100644 --- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp @@ -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 - diff --git a/src/add-ons/kernel/file_systems/exfat/Jamfile b/src/add-ons/kernel/file_systems/exfat/Jamfile index cdf366f401..5e78421082 100644 --- a/src/add-ons/kernel/file_systems/exfat/Jamfile +++ b/src/add-ons/kernel/file_systems/exfat/Jamfile @@ -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 ] ; \ No newline at end of file diff --git a/src/add-ons/kernel/file_systems/exfat/Volume.cpp b/src/add-ons/kernel/file_systems/exfat/Volume.cpp index 65dcb39c6b..6f2bc0387e 100644 --- a/src/add-ons/kernel/file_systems/exfat/Volume.cpp +++ b/src/add-ons/kernel/file_systems/exfat/Volume.cpp @@ -30,6 +30,7 @@ #include #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 diff --git a/src/add-ons/kernel/file_systems/ext2/Jamfile b/src/add-ons/kernel/file_systems/ext2/Jamfile index 21883181de..7a8ad77039 100644 --- a/src/add-ons/kernel/file_systems/ext2/Jamfile +++ b/src/add-ons/kernel/file_systems/ext2/Jamfile @@ -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 ] ; diff --git a/src/add-ons/kernel/file_systems/ext2/Volume.cpp b/src/add-ons/kernel/file_systems/ext2/Volume.cpp index f89e8173a4..7727c1f901 100644 --- a/src/add-ons/kernel/file_systems/ext2/Volume.cpp +++ b/src/add-ons/kernel/file_systems/ext2/Volume.cpp @@ -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 - diff --git a/src/add-ons/kernel/file_systems/shared/DeviceOpener.cpp b/src/add-ons/kernel/file_systems/shared/DeviceOpener.cpp new file mode 100644 index 0000000000..60833fff0d --- /dev/null +++ b/src/add-ons/kernel/file_systems/shared/DeviceOpener.cpp @@ -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; +} diff --git a/src/add-ons/kernel/file_systems/shared/system_dependencies.h b/src/add-ons/kernel/file_systems/shared/system_dependencies.h new file mode 100644 index 0000000000..a26c748c3f --- /dev/null +++ b/src/add-ons/kernel/file_systems/shared/system_dependencies.h @@ -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 + +#else // !FS_SHELL + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // !FS_SHELL + +#endif // _SYSTEM_DEPENDENCIES diff --git a/src/add-ons/kernel/file_systems/ufs2/Jamfile b/src/add-ons/kernel/file_systems/ufs2/Jamfile index 2724386e72..c9336ce597 100644 --- a/src/add-ons/kernel/file_systems/ufs2/Jamfile +++ b/src/add-ons/kernel/file_systems/ufs2/Jamfile @@ -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 ] ; diff --git a/src/add-ons/kernel/file_systems/ufs2/Volume.cpp b/src/add-ons/kernel/file_systems/ufs2/Volume.cpp index bf63bf8901..5ac6afce75 100644 --- a/src/add-ons/kernel/file_systems/ufs2/Volume.cpp +++ b/src/add-ons/kernel/file_systems/ufs2/Volume.cpp @@ -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; +} diff --git a/src/add-ons/kernel/file_systems/ufs2/Volume.h b/src/add-ons/kernel/file_systems/ufs2/Volume.h index ab35fb8150..faf421e61f 100644 --- a/src/add-ons/kernel/file_systems/ufs2/Volume.h +++ b/src/add-ons/kernel/file_systems/ufs2/Volume.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/xfs/Jamfile b/src/add-ons/kernel/file_systems/xfs/Jamfile index 79c72ddc19..228377d12c 100644 --- a/src/add-ons/kernel/file_systems/xfs/Jamfile +++ b/src/add-ons/kernel/file_systems/xfs/Jamfile @@ -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 ] ; \ No newline at end of file diff --git a/src/add-ons/kernel/file_systems/xfs/Volume.cpp b/src/add-ons/kernel/file_systems/xfs/Volume.cpp index 0c24307d5e..aa6d14ce00 100644 --- a/src/add-ons/kernel/file_systems/xfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/xfs/Volume.cpp @@ -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) diff --git a/src/tests/add-ons/kernel/file_systems/btrfs/btrfs_shell/Jamfile b/src/tests/add-ons/kernel/file_systems/btrfs/btrfs_shell/Jamfile index 2b1f37f5e9..f4fd284d21 100644 --- a/src/tests/add-ons/kernel/file_systems/btrfs/btrfs_shell/Jamfile +++ b/src/tests/add-ons/kernel/file_systems/btrfs/btrfs_shell/Jamfile @@ -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 ] ; diff --git a/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile b/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile index df68c9bb65..87ed9f0061 100644 --- a/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile +++ b/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile @@ -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 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 ] ; diff --git a/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile b/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile index 93db59e162..f4aade70ac 100644 --- a/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile +++ b/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile @@ -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 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 ] ; \ No newline at end of file