btrfs: partially implement filesystem initialization
Change-Id: I7fb3340dc39b3331d30e5113b5860d936efab253 Reviewed-on: https://review.haiku-os.org/c/1395 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Jérôme Duval
parent
9d6d044fdd
commit
aa08671d9c
@@ -121,7 +121,8 @@ Inode::Create(Transaction& transaction, ino_t id, Inode* parent, int32 mode,
|
|||||||
TRACE("Inode::Create() id % " B_PRIu64 " mode %" B_PRId32 " flags %"
|
TRACE("Inode::Create() id % " B_PRIu64 " mode %" B_PRId32 " flags %"
|
||||||
B_PRIu64"\n", id, flags, mode);
|
B_PRIu64"\n", id, flags, mode);
|
||||||
|
|
||||||
Volume* volume = parent->GetVolume();
|
Volume* volume = parent != NULL ?
|
||||||
|
parent->GetVolume() : transaction.GetJournal()->GetVolume();
|
||||||
uint64 nbytes = size; // allocated size
|
uint64 nbytes = size; // allocated size
|
||||||
if (size > volume->MaxInlineSize())
|
if (size > volume->MaxInlineSize())
|
||||||
nbytes = (size / volume->SectorSize() + 1) * volume->SectorSize();
|
nbytes = (size / volume->SectorSize() + 1) * volume->SectorSize();
|
||||||
@@ -135,7 +136,8 @@ Inode::Create(Transaction& transaction, ino_t id, Inode* parent, int32 mode,
|
|||||||
inode.blockgroup = 0; // normal inode only
|
inode.blockgroup = 0; // normal inode only
|
||||||
inode.num_links = B_HOST_TO_LENDIAN_INT32(1);
|
inode.num_links = B_HOST_TO_LENDIAN_INT32(1);
|
||||||
inode.uid = B_HOST_TO_LENDIAN_INT32(geteuid());
|
inode.uid = B_HOST_TO_LENDIAN_INT32(geteuid());
|
||||||
inode.gid = B_HOST_TO_LENDIAN_INT32(parent ? parent->GroupID() : getegid());
|
inode.gid = B_HOST_TO_LENDIAN_INT32(parent != NULL ?
|
||||||
|
parent->GroupID() : getegid());
|
||||||
inode.mode = B_HOST_TO_LENDIAN_INT32(mode);;
|
inode.mode = B_HOST_TO_LENDIAN_INT32(mode);;
|
||||||
inode.rdev = 0; // normal file only
|
inode.rdev = 0; // normal file only
|
||||||
inode.flags = B_HOST_TO_LENDIAN_INT64(flags);
|
inode.flags = B_HOST_TO_LENDIAN_INT64(flags);
|
||||||
|
|||||||
@@ -1,24 +1,35 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel file_systems btrfs ;
|
SubDir HAIKU_TOP src add-ons kernel file_systems btrfs ;
|
||||||
|
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UsePrivateHeaders shared storage ;
|
UsePrivateHeaders shared storage file_systems ;
|
||||||
UsePrivateKernelHeaders ;
|
UsePrivateKernelHeaders ;
|
||||||
UseBuildFeatureHeaders zlib ;
|
UseBuildFeatureHeaders zlib ;
|
||||||
|
|
||||||
|
DEFINES += DEBUG_APP="\\\"btrfs\\\"" ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
||||||
|
|
||||||
Includes [ FGristFiles Inode.cpp ]
|
Includes [ FGristFiles Inode.cpp ]
|
||||||
: [ BuildFeatureAttribute zlib : headers ] ;
|
: [ BuildFeatureAttribute zlib : headers ] ;
|
||||||
|
|
||||||
KernelAddon btrfs :
|
KernelAddon btrfs :
|
||||||
|
btrfs_disk_system.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
Attribute.cpp
|
Attribute.cpp
|
||||||
AttributeIterator.cpp
|
AttributeIterator.cpp
|
||||||
BTree.cpp
|
BTree.cpp
|
||||||
Chunk.cpp
|
Chunk.cpp
|
||||||
CRCTable.cpp
|
CRCTable.cpp
|
||||||
|
DebugSupport.cpp
|
||||||
DirectoryIterator.cpp
|
DirectoryIterator.cpp
|
||||||
ExtentAllocator.cpp
|
ExtentAllocator.cpp
|
||||||
Inode.cpp
|
Inode.cpp
|
||||||
Journal.cpp
|
Journal.cpp
|
||||||
Volume.cpp
|
Volume.cpp
|
||||||
: kernel_libz.a
|
:
|
||||||
|
kernel_libz.a
|
||||||
|
libuuid_kernel.a
|
||||||
;
|
;
|
||||||
|
|
||||||
|
SEARCH on [ FGristFiles DebugSupport.cpp ]
|
||||||
|
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public:
|
|||||||
Transaction();
|
Transaction();
|
||||||
~Transaction();
|
~Transaction();
|
||||||
|
|
||||||
|
Journal* GetJournal() const { return fJournal; }
|
||||||
int32 ID() const { return fJournal->TransactionID(); }
|
int32 ID() const { return fJournal->TransactionID(); }
|
||||||
uint64 SystemID() const
|
uint64 SystemID() const
|
||||||
{ return fJournal->SystemTransactionID(); }
|
{ return fJournal->SystemTransactionID(); }
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2019, Les De Ridder, [email protected]
|
||||||
* Copyright 2017, Chế Vũ Gia Hy, [email protected].
|
* Copyright 2017, Chế Vũ Gia Hy, [email protected].
|
||||||
* Copyright 2011, Jérôme Duval, [email protected].
|
* Copyright 2011, Jérôme Duval, [email protected].
|
||||||
* Copyright 2008-2010, Axel Dörfler, [email protected].
|
* Copyright 2008-2010, Axel Dörfler, [email protected].
|
||||||
|
*
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -13,9 +15,11 @@
|
|||||||
#include "BTree.h"
|
#include "BTree.h"
|
||||||
#include "CachedBlock.h"
|
#include "CachedBlock.h"
|
||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
|
#include "DebugSupport.h"
|
||||||
|
#include "ExtentAllocator.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "Journal.h"
|
#include "Journal.h"
|
||||||
#include "ExtentAllocator.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_BTRFS
|
//#define TRACE_BTRFS
|
||||||
@@ -191,7 +195,7 @@ DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
btrfs_super_block::IsValid()
|
btrfs_super_block::IsValid() const
|
||||||
{
|
{
|
||||||
// TODO: check some more values!
|
// TODO: check some more values!
|
||||||
if (strncmp(magic, BTRFS_SUPER_BLOCK_MAGIC, sizeof(magic)) != 0)
|
if (strncmp(magic, BTRFS_SUPER_BLOCK_MAGIC, sizeof(magic)) != 0)
|
||||||
@@ -201,6 +205,33 @@ btrfs_super_block::IsValid()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
btrfs_super_block::Initialize(const char* name, off_t numBlocks,
|
||||||
|
uint32 blockSize, uint32 sectorSize)
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(btrfs_super_block));
|
||||||
|
|
||||||
|
uuid_generate(fsid);
|
||||||
|
blocknum = B_HOST_TO_LENDIAN_INT64(BTRFS_SUPER_BLOCK_OFFSET);
|
||||||
|
num_devices = B_HOST_TO_LENDIAN_INT64(1);
|
||||||
|
strncpy(magic, BTRFS_SUPER_BLOCK_MAGIC_TEMPORARY, sizeof(magic));
|
||||||
|
generation = B_HOST_TO_LENDIAN_INT64(1);
|
||||||
|
root = B_HOST_TO_LENDIAN_INT64(BTRFS_RESERVED_SPACE_OFFSET + blockSize);
|
||||||
|
chunk_root = B_HOST_TO_LENDIAN_INT64(Root() + blockSize);
|
||||||
|
total_size = B_HOST_TO_LENDIAN_INT64(numBlocks * blockSize);
|
||||||
|
used_size = B_HOST_TO_LENDIAN_INT64(6 * blockSize);
|
||||||
|
sector_size = B_HOST_TO_LENDIAN_INT32(sectorSize);
|
||||||
|
leaf_size = B_HOST_TO_LENDIAN_INT32(blockSize);
|
||||||
|
node_size = B_HOST_TO_LENDIAN_INT32(blockSize);
|
||||||
|
stripe_size = B_HOST_TO_LENDIAN_INT32(blockSize);
|
||||||
|
checksum_type = B_HOST_TO_LENDIAN_INT32(BTRFS_CSUM_TYPE_CRC32);
|
||||||
|
chunk_root_generation = B_HOST_TO_LENDIAN_INT64(1);
|
||||||
|
// TODO(lesderid): Support configurable filesystem features
|
||||||
|
incompat_flags = B_HOST_TO_LENDIAN_INT64(0);
|
||||||
|
strlcpy(label, name, BTRFS_LABEL_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -453,6 +484,78 @@ Volume::Mount(const char* deviceName, uint32 flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Volume::Initialize(int fd, const char* label, uint32 blockSize,
|
||||||
|
uint32 sectorSize)
|
||||||
|
{
|
||||||
|
TRACE("Volume::Initialize()\n");
|
||||||
|
|
||||||
|
// label must != NULL and may not contain '/' or '\\'
|
||||||
|
if (label == NULL
|
||||||
|
|| strchr(label, '/') != NULL || strchr(label, '\\') != NULL) {
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((blockSize != 1024 && blockSize != 2048 && blockSize != 4096
|
||||||
|
&& blockSize != 8192 && blockSize != 16384)
|
||||||
|
|| blockSize % sectorSize != 0) {
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceOpener opener(fd, O_RDWR);
|
||||||
|
if (opener.Device() < B_OK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
if (opener.IsReadOnly())
|
||||||
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
|
fDevice = opener.Device();
|
||||||
|
|
||||||
|
uint32 deviceBlockSize;
|
||||||
|
off_t deviceSize;
|
||||||
|
if (opener.GetSize(&deviceSize, &deviceBlockSize) < B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
off_t numBlocks = deviceSize / sectorSize;
|
||||||
|
|
||||||
|
// create valid superblock
|
||||||
|
|
||||||
|
fSuperBlock.Initialize(label, numBlocks, blockSize, sectorSize);
|
||||||
|
|
||||||
|
fBlockSize = fSuperBlock.BlockSize();
|
||||||
|
fSectorSize = fSuperBlock.SectorSize();
|
||||||
|
|
||||||
|
// TODO(lesderid): Initialize remaining core structures
|
||||||
|
// (extent tree, chunk tree, fs tree, etc.)
|
||||||
|
|
||||||
|
status_t status = WriteSuperBlock();
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
fBlockCache = opener.InitCache(fSuperBlock.TotalSize() / fBlockSize,
|
||||||
|
fBlockSize);
|
||||||
|
if (fBlockCache == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fJournal = new(std::nothrow) Journal(this);
|
||||||
|
if (fJournal == NULL)
|
||||||
|
RETURN_ERROR(B_ERROR);
|
||||||
|
|
||||||
|
// TODO(lesderid): Perform secondary initialization (in transactions)
|
||||||
|
// (add block groups to extent tree, create root dir, etc.)
|
||||||
|
Transaction transaction(this);
|
||||||
|
|
||||||
|
// TODO(lesderid): Write all superblocks when transactions are committed
|
||||||
|
status = transaction.Done();
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
opener.RemoveCache(true);
|
||||||
|
|
||||||
|
TRACE("Volume::Initialize(): Done\n");
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::Unmount()
|
Volume::Unmount()
|
||||||
{
|
{
|
||||||
@@ -546,6 +649,20 @@ Volume::FindBlock(off_t logical, off_t& physical)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Volume::WriteSuperBlock()
|
||||||
|
{
|
||||||
|
// TODO(lesderid): Calculate checksum
|
||||||
|
|
||||||
|
if (write_pos(fDevice, BTRFS_SUPER_BLOCK_OFFSET, &fSuperBlock,
|
||||||
|
sizeof(btrfs_super_block))
|
||||||
|
!= sizeof(btrfs_super_block))
|
||||||
|
return B_IO_ERROR;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper function for allocating new block
|
/* Wrapper function for allocating new block
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ public:
|
|||||||
|
|
||||||
status_t Mount(const char* device, uint32 flags);
|
status_t Mount(const char* device, uint32 flags);
|
||||||
status_t Unmount();
|
status_t Unmount();
|
||||||
|
status_t Initialize(int fd, const char* label,
|
||||||
|
uint32 blockSize, uint32 sectorSize);
|
||||||
|
|
||||||
bool IsValidSuperBlock();
|
bool IsValidSuperBlock();
|
||||||
bool IsReadOnly() const
|
bool IsReadOnly() const
|
||||||
@@ -58,6 +60,7 @@ public:
|
|||||||
btrfs_super_block& SuperBlock() { return fSuperBlock; }
|
btrfs_super_block& SuperBlock() { return fSuperBlock; }
|
||||||
|
|
||||||
status_t LoadSuperBlock();
|
status_t LoadSuperBlock();
|
||||||
|
status_t WriteSuperBlock();
|
||||||
|
|
||||||
// cache access
|
// cache access
|
||||||
void* BlockCache() { return fBlockCache; }
|
void* BlockCache() { return fBlockCache; }
|
||||||
|
|||||||
@@ -13,7 +13,11 @@
|
|||||||
typedef uint64 fileblock_t; // file block number
|
typedef uint64 fileblock_t; // file block number
|
||||||
typedef uint64 fsblock_t; // filesystem block number
|
typedef uint64 fsblock_t; // filesystem block number
|
||||||
|
|
||||||
#define BTRFS_SUPER_BLOCK_OFFSET 0x10000
|
#define BTRFS_LABEL_SIZE 256
|
||||||
|
|
||||||
|
#define BTRFS_SUPER_BLOCK_OFFSET 0x10000 // 64KiB
|
||||||
|
#define BTRFS_RESERVED_SPACE_OFFSET 0x100000 // 1MiB
|
||||||
|
|
||||||
#define BTRFS_NUM_ROOT_BACKUPS 4
|
#define BTRFS_NUM_ROOT_BACKUPS 4
|
||||||
|
|
||||||
|
|
||||||
@@ -93,10 +97,10 @@ struct btrfs_timespec {
|
|||||||
|
|
||||||
struct btrfs_header {
|
struct btrfs_header {
|
||||||
uint8 checksum[32];
|
uint8 checksum[32];
|
||||||
uint8 fsid[16];
|
uuid_t fsid;
|
||||||
uint64 logical_address;
|
uint64 logical_address;
|
||||||
uint64 flags;
|
uint64 flags;
|
||||||
uint8 chunk_tree_uuid[16];
|
uuid_t chunk_tree_uuid;
|
||||||
uint64 generation;
|
uint64 generation;
|
||||||
uint64 owner;
|
uint64 owner;
|
||||||
uint32 item_count;
|
uint32 item_count;
|
||||||
@@ -162,7 +166,7 @@ struct btrfs_stream {
|
|||||||
struct btrfs_stripe {
|
struct btrfs_stripe {
|
||||||
uint64 device_id;
|
uint64 device_id;
|
||||||
uint64 offset;
|
uint64 offset;
|
||||||
uint8 device_uuid[16];
|
uuid_t device_uuid;
|
||||||
uint64 DeviceID() const { return B_LENDIAN_TO_HOST_INT64(device_id); }
|
uint64 DeviceID() const { return B_LENDIAN_TO_HOST_INT64(device_id); }
|
||||||
uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
|
uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
@@ -208,14 +212,14 @@ struct btrfs_device {
|
|||||||
uint32 group;
|
uint32 group;
|
||||||
uint8 seek_speed;
|
uint8 seek_speed;
|
||||||
uint8 bandwidth;
|
uint8 bandwidth;
|
||||||
uint8 uuid[16];
|
uuid_t uuid;
|
||||||
uint8 fsid[16];
|
uuid_t fsid;
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
struct btrfs_super_block {
|
struct btrfs_super_block {
|
||||||
uint8 checksum[32];
|
uint8 checksum[32];
|
||||||
uint8 fsid[16];
|
uuid_t fsid;
|
||||||
uint64 blocknum;
|
uint64 blocknum;
|
||||||
uint64 flags;
|
uint64 flags;
|
||||||
char magic[8];
|
char magic[8];
|
||||||
@@ -242,13 +246,15 @@ struct btrfs_super_block {
|
|||||||
uint8 chunk_root_level;
|
uint8 chunk_root_level;
|
||||||
uint8 log_root_level;
|
uint8 log_root_level;
|
||||||
btrfs_device device;
|
btrfs_device device;
|
||||||
char label[256];
|
char label[BTRFS_LABEL_SIZE];
|
||||||
uint64 reserved[32];
|
uint64 reserved[32];
|
||||||
uint8 system_chunk_array[2048];
|
uint8 system_chunk_array[2048];
|
||||||
btrfs_backup_roots backup_roots[BTRFS_NUM_ROOT_BACKUPS];
|
btrfs_backup_roots backup_roots[BTRFS_NUM_ROOT_BACKUPS];
|
||||||
|
|
||||||
bool IsValid();
|
// implemented in Volume.cpp:
|
||||||
// implemented in Volume.cpp
|
bool IsValid() const;
|
||||||
|
void Initialize(const char* name, off_t numBlocks,
|
||||||
|
uint32 blockSize, uint32 sectorSize);
|
||||||
uint64 TotalSize() const { return B_LENDIAN_TO_HOST_INT64(total_size); }
|
uint64 TotalSize() const { return B_LENDIAN_TO_HOST_INT64(total_size); }
|
||||||
uint32 BlockSize() const { return B_LENDIAN_TO_HOST_INT32(node_size); }
|
uint32 BlockSize() const { return B_LENDIAN_TO_HOST_INT32(node_size); }
|
||||||
uint32 SectorSize() const { return B_LENDIAN_TO_HOST_INT32(sector_size); }
|
uint32 SectorSize() const { return B_LENDIAN_TO_HOST_INT32(sector_size); }
|
||||||
@@ -456,10 +462,13 @@ struct btrfs_extent_data_ref {
|
|||||||
uint32 RefCount() const { return B_LENDIAN_TO_HOST_INT32(ref_count); }
|
uint32 RefCount() const { return B_LENDIAN_TO_HOST_INT32(ref_count); }
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
#define BTRFS_SUPER_BLOCK_MAGIC "_BHRfS_M"
|
#define BTRFS_SUPER_BLOCK_MAGIC "_BHRfS_M"
|
||||||
|
#define BTRFS_SUPER_BLOCK_MAGIC_TEMPORARY "!BHRfS_M"
|
||||||
|
|
||||||
#define BTRFS_FIRST_SUBVOLUME 256
|
#define BTRFS_FIRST_SUBVOLUME 256
|
||||||
|
|
||||||
|
#define BTRFS_CSUM_TYPE_CRC32 0
|
||||||
|
|
||||||
#define BTRFS_OBJECT_ID_ROOT_TREE 1
|
#define BTRFS_OBJECT_ID_ROOT_TREE 1
|
||||||
#define BTRFS_OBJECT_ID_EXTENT_TREE 2
|
#define BTRFS_OBJECT_ID_EXTENT_TREE 2
|
||||||
#define BTRFS_OBJECT_ID_CHUNK_TREE 3
|
#define BTRFS_OBJECT_ID_CHUNK_TREE 3
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007-2008, Ingo Weinhold, [email protected].
|
||||||
|
* Copyright 2019, Les De Ridder, [email protected]
|
||||||
|
*
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "btrfs_disk_system.h"
|
||||||
|
|
||||||
|
#include "btrfs.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
parse_initialize_parameters(const char* parameterString,
|
||||||
|
initialize_parameters& parameters)
|
||||||
|
{
|
||||||
|
parameters.verbose = false;
|
||||||
|
|
||||||
|
void *handle = parse_driver_settings_string(parameterString);
|
||||||
|
if (handle == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (get_driver_boolean_parameter(handle, "verbose", false, true))
|
||||||
|
parameters.verbose = true;
|
||||||
|
|
||||||
|
const char *ss_string = get_driver_parameter(handle, "sector_size",
|
||||||
|
NULL, NULL);
|
||||||
|
uint32 sectorSize = B_PAGE_SIZE;
|
||||||
|
if (ss_string != NULL)
|
||||||
|
sectorSize = strtoul(ss_string, NULL, 0);
|
||||||
|
|
||||||
|
const char *bs_string = get_driver_parameter(handle, "block_size",
|
||||||
|
NULL, NULL);
|
||||||
|
uint32 blockSize = max_c(16384, B_PAGE_SIZE);
|
||||||
|
if (bs_string != NULL)
|
||||||
|
blockSize = strtoul(bs_string, NULL, 0);
|
||||||
|
|
||||||
|
// TODO(lesderid): accept more settings (allocation profiles, uuid, etc.)
|
||||||
|
|
||||||
|
delete_driver_settings(handle);
|
||||||
|
|
||||||
|
if ((blockSize != 1024 && blockSize != 2048 && blockSize != 4096
|
||||||
|
&& blockSize != 8192 && blockSize != 16384)
|
||||||
|
|| blockSize % sectorSize != 0) {
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters.sectorSize = sectorSize;
|
||||||
|
parameters.blockSize = blockSize;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
check_volume_name(const char* name)
|
||||||
|
{
|
||||||
|
if (name == NULL || strlen(name) >= BTRFS_LABEL_SIZE
|
||||||
|
|| strchr(name, '/') != NULL
|
||||||
|
|| strchr(name, '\\') != NULL) {
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Ingo Weinhold, [email protected].
|
||||||
|
* Copyright 2019, Les De Ridder, [email protected]
|
||||||
|
*
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BTRFS_DISK_SYSTEM_H
|
||||||
|
#define _BTRFS_DISK_SYSTEM_H
|
||||||
|
|
||||||
|
#include "system_dependencies.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct initialize_parameters {
|
||||||
|
uint32 blockSize;
|
||||||
|
uint32 sectorSize;
|
||||||
|
bool verbose;
|
||||||
|
};
|
||||||
|
|
||||||
|
status_t parse_initialize_parameters(const char* parameterString,
|
||||||
|
initialize_parameters& parameters);
|
||||||
|
status_t check_volume_name(const char* name);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _BTRFS_DISK_SYSTEM_H
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2019, Les De Ridder, [email protected]
|
||||||
* Copyright 2017, Chế Vũ Gia Hy, [email protected].
|
* Copyright 2017, Chế Vũ Gia Hy, [email protected].
|
||||||
* Copyright 2011, Jérôme Duval, [email protected].
|
* Copyright 2011, Jérôme Duval, [email protected].
|
||||||
* Copyright 2008, Axel Dörfler, [email protected].
|
* Copyright 2008, Axel Dörfler, [email protected].
|
||||||
|
*
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -9,6 +11,8 @@
|
|||||||
#include "Attribute.h"
|
#include "Attribute.h"
|
||||||
#include "AttributeIterator.h"
|
#include "AttributeIterator.h"
|
||||||
#include "btrfs.h"
|
#include "btrfs.h"
|
||||||
|
#include "btrfs_disk_system.h"
|
||||||
|
#include "DebugSupport.h"
|
||||||
#include "DirectoryIterator.h"
|
#include "DirectoryIterator.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
@@ -20,8 +24,6 @@
|
|||||||
#else
|
#else
|
||||||
# define TRACE(x...) ;
|
# define TRACE(x...) ;
|
||||||
#endif
|
#endif
|
||||||
#define ERROR(x...) dprintf("\33[34mbtrfs:\33[0m " x)
|
|
||||||
|
|
||||||
|
|
||||||
#define BTRFS_IO_SIZE 65536
|
#define BTRFS_IO_SIZE 65536
|
||||||
|
|
||||||
@@ -833,6 +835,85 @@ btrfs_remove_attr(fs_volume* _volume, fs_vnode* vnode,
|
|||||||
return EROFS;
|
return EROFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32
|
||||||
|
btrfs_get_supported_operations(partition_data* partition, uint32 mask)
|
||||||
|
{
|
||||||
|
// TODO: We should at least check the partition size.
|
||||||
|
return B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|
||||||
|
| B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
||||||
|
// | B_DISK_SYSTEM_SUPPORTS_WRITING
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
btrfs_initialize(int fd, partition_id partitionID, const char* name,
|
||||||
|
const char* parameterString, off_t partitionSize, disk_job_id job)
|
||||||
|
{
|
||||||
|
// check name
|
||||||
|
status_t status = check_volume_name(name);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// parse parameters
|
||||||
|
initialize_parameters parameters;
|
||||||
|
status = parse_initialize_parameters(parameterString, parameters);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
update_disk_device_job_progress(job, 0);
|
||||||
|
|
||||||
|
// initialize the volume
|
||||||
|
Volume volume(NULL);
|
||||||
|
status = volume.Initialize(fd, name, parameters.blockSize,
|
||||||
|
parameters.sectorSize);
|
||||||
|
if (status < B_OK) {
|
||||||
|
INFORM("Initializing volume failed: %s\n", strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rescan partition
|
||||||
|
status = scan_partition(partitionID);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
update_disk_device_job_progress(job, 1);
|
||||||
|
|
||||||
|
// print some info, if desired
|
||||||
|
if (parameters.verbose) {
|
||||||
|
btrfs_super_block super = volume.SuperBlock();
|
||||||
|
|
||||||
|
INFORM(("Disk was initialized successfully.\n"));
|
||||||
|
INFORM("\tlabel: \"%s\"\n", super.label);
|
||||||
|
INFORM("\tblock size: %u bytes\n", (unsigned)super.BlockSize());
|
||||||
|
INFORM("\tsector size: %u bytes\n", (unsigned)super.SectorSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
btrfs_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
|
||||||
|
uint32 blockSize, disk_job_id job)
|
||||||
|
{
|
||||||
|
if (blockSize == 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
update_disk_device_job_progress(job, 0.0);
|
||||||
|
|
||||||
|
// just overwrite the superblock
|
||||||
|
btrfs_super_block superBlock;
|
||||||
|
memset(&superBlock, 0, sizeof(superBlock));
|
||||||
|
|
||||||
|
if (write_pos(fd, BTRFS_SUPER_BLOCK_OFFSET, &superBlock,
|
||||||
|
sizeof(superBlock)) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
update_disk_device_job_progress(job, 1.0);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
@@ -842,8 +923,12 @@ btrfs_std_ops(int32 op, ...)
|
|||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT:
|
||||||
|
init_debugging();
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
|
exit_debugging();
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -943,7 +1028,13 @@ static file_system_module_info sBtrfsFileSystem = {
|
|||||||
|
|
||||||
"btrfs", // short_name
|
"btrfs", // short_name
|
||||||
"Btrfs File System", // pretty_name
|
"Btrfs File System", // pretty_name
|
||||||
0, // DDM flags
|
|
||||||
|
// DDM flags
|
||||||
|
0
|
||||||
|
| B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|
||||||
|
| B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
||||||
|
// | B_DISK_SYSTEM_SUPPORTS_WRITING
|
||||||
|
,
|
||||||
|
|
||||||
// scanning
|
// scanning
|
||||||
btrfs_identify_partition,
|
btrfs_identify_partition,
|
||||||
@@ -955,7 +1046,7 @@ static file_system_module_info sBtrfsFileSystem = {
|
|||||||
|
|
||||||
|
|
||||||
/* capability querying operations */
|
/* capability querying operations */
|
||||||
NULL,
|
&btrfs_get_supported_operations,
|
||||||
|
|
||||||
NULL, // validate_resize
|
NULL, // validate_resize
|
||||||
NULL, // validate_move
|
NULL, // validate_move
|
||||||
@@ -973,8 +1064,8 @@ static file_system_module_info sBtrfsFileSystem = {
|
|||||||
NULL, // move
|
NULL, // move
|
||||||
NULL, // set_content_name
|
NULL, // set_content_name
|
||||||
NULL, // set_content_parameters
|
NULL, // set_content_parameters
|
||||||
NULL, // initialize
|
btrfs_initialize,
|
||||||
NULL // unitialize
|
btrfs_uninitialize
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
|
#include <driver_settings.h>
|
||||||
#include <fs_cache.h>
|
#include <fs_cache.h>
|
||||||
#include <fs_interface.h>
|
#include <fs_interface.h>
|
||||||
#include <fs_info.h>
|
#include <fs_info.h>
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <uuid.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#endif // !FS_SHELL
|
#endif // !FS_SHELL
|
||||||
|
|||||||
Reference in New Issue
Block a user