Adding superblock, types, xfs_mount and volume
Superblock work is done. A valid superblock is now detected. xfs_shell will fail though, because the filesystem does not own it's root node. Change-Id: I78e3c21c4d0dd8e535fd24df4a0c107ed5fb201c Reviewed-on: https://review.haiku-os.org/c/haiku/+/2286 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
0d2645e44f
commit
2deffe2f3f
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _DEBUG_H_
|
||||||
|
#define _DEBUG_H_
|
||||||
|
|
||||||
|
#define TRACE_XFS
|
||||||
|
#ifdef TRACE_XFS
|
||||||
|
#define TRACE(x...) dprintf("\n\33[34mxfs:\33[0m " x)
|
||||||
|
#else
|
||||||
|
#define TRACE(x...) ;
|
||||||
|
#endif
|
||||||
|
#define ERROR(x...) dprintf("\n\33[34mxfs:\33[0m " x)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,6 +20,8 @@ DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
|
|||||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
||||||
|
|
||||||
local xfsSources =
|
local xfsSources =
|
||||||
|
xfs.cpp
|
||||||
|
Volume.cpp
|
||||||
kernel_cpp.cpp
|
kernel_cpp.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2001 - 2017, Axel Dörfler, axeld @pinc - software.de.
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Volume::Volume(fs_volume *volume)
|
||||||
|
: fFSVolume(volume)
|
||||||
|
{
|
||||||
|
fFlags = 0;
|
||||||
|
mutex_init(&fLock, "xfs volume");
|
||||||
|
TRACE("Volume::Volume() : Initialising volume");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Volume::~Volume()
|
||||||
|
{
|
||||||
|
mutex_destroy(&fLock);
|
||||||
|
TRACE("Volume::Destructor : Removing Volume");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Volume::IsValidSuperBlock()
|
||||||
|
{
|
||||||
|
return fSuperBlock.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Volume::Identify(int fd, XfsSuperBlock *superBlock)
|
||||||
|
{
|
||||||
|
|
||||||
|
TRACE("Volume::Identify() : Identifying Volume in progress");
|
||||||
|
|
||||||
|
if (read_pos(fd, 0, superBlock, sizeof(XfsSuperBlock))
|
||||||
|
!= sizeof(XfsSuperBlock))
|
||||||
|
return B_IO_ERROR;
|
||||||
|
|
||||||
|
superBlock->SwapEndian();
|
||||||
|
|
||||||
|
if (!superBlock->IsValid()) {
|
||||||
|
ERROR("Volume::Identify(): Invalid Superblock!\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Volume::Mount(const char *deviceName, uint32 flags)
|
||||||
|
{
|
||||||
|
TRACE("Volume::Mount() : Mounting in progress");
|
||||||
|
|
||||||
|
flags |= B_MOUNT_READ_ONLY;
|
||||||
|
|
||||||
|
if ((flags & B_MOUNT_READ_ONLY) != 0) {
|
||||||
|
TRACE("Volume::Mount(): Read only\n");
|
||||||
|
} else {
|
||||||
|
TRACE("Volume::Mount(): Read write\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0
|
||||||
|
? O_RDONLY
|
||||||
|
: O_RDWR);
|
||||||
|
fDevice = opener.Device();
|
||||||
|
if (fDevice < B_OK) {
|
||||||
|
ERROR("Volume::Mount(): couldn't open device\n");
|
||||||
|
return fDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opener.IsReadOnly())
|
||||||
|
fFlags |= VOLUME_READ_ONLY;
|
||||||
|
|
||||||
|
// read the superblock
|
||||||
|
status_t status = Identify(fDevice, &fSuperBlock);
|
||||||
|
if (status != B_OK) {
|
||||||
|
ERROR("Volume::Mount(): Invalid super block!\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Volume::Mount(): Valid SuperBlock.\n");
|
||||||
|
|
||||||
|
// check if the device size is large enough to hold the file system
|
||||||
|
off_t diskSize;
|
||||||
|
if (opener.GetSize(&diskSize) != B_OK) {
|
||||||
|
ERROR("Volume:Mount() Unable to get diskSize");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
opener.Keep();
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Volume::Unmount()
|
||||||
|
{
|
||||||
|
TRACE("Volume::Unmount(): Unmounting");
|
||||||
|
|
||||||
|
TRACE("Volume::Unmount(): Closing device");
|
||||||
|
close(fDevice);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VOLUME_H_
|
||||||
|
#define _VOLUME_H_
|
||||||
|
|
||||||
|
#include "xfs.h"
|
||||||
|
|
||||||
|
extern fs_volume_ops gxfsVolumeOps;
|
||||||
|
enum volume_flags {
|
||||||
|
VOLUME_READ_ONLY = 0x0001
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Volume {
|
||||||
|
public:
|
||||||
|
Volume(fs_volume *volume);
|
||||||
|
~Volume();
|
||||||
|
|
||||||
|
status_t Mount(const char *device, uint32 flags);
|
||||||
|
status_t Unmount();
|
||||||
|
status_t Initialize(int fd, const char *label,
|
||||||
|
uint32 blockSize, uint32 sectorSize);
|
||||||
|
|
||||||
|
bool IsValidSuperBlock();
|
||||||
|
bool IsReadOnly() const
|
||||||
|
{ return (fFlags & VOLUME_READ_ONLY) != 0; }
|
||||||
|
|
||||||
|
dev_t ID() const
|
||||||
|
{ return fFSVolume ? fFSVolume->id : -1; }
|
||||||
|
fs_volume* FSVolume() const
|
||||||
|
{ return fFSVolume; }
|
||||||
|
char* Name()
|
||||||
|
{ return fSuperBlock.Name(); }
|
||||||
|
|
||||||
|
XfsSuperBlock& SuperBlock() { return fSuperBlock; }
|
||||||
|
int Device() const { return fDevice; }
|
||||||
|
|
||||||
|
static status_t Identify(int fd, XfsSuperBlock *superBlock);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
off_t NumBlocks() const
|
||||||
|
{ return fSuperBlock.NumBlocks(); }
|
||||||
|
|
||||||
|
off_t Root() const { return fSuperBlock.rootino; }
|
||||||
|
|
||||||
|
static status_t Identify(int fd, SuperBlock *superBlock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
fs_volume* fFSVolume;
|
||||||
|
int fDevice;
|
||||||
|
XfsSuperBlock fSuperBlock;
|
||||||
|
char fName[32]; /* filesystem name */
|
||||||
|
|
||||||
|
uint32 fDeviceBlockSize;
|
||||||
|
mutex fLock;
|
||||||
|
|
||||||
|
uint32 fFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 Shubham Bhagat, [email protected]
|
* Copyright 2001-2017, Axel Dörfler, [email protected].
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#include "system_dependencies.h"
|
#include "system_dependencies.h"
|
||||||
|
#include "Volume.h"
|
||||||
#ifdef TRACE_XFS
|
|
||||||
#define TRACE(x...) dprintf("\33[34mxfs:\33[0m " x)
|
|
||||||
#else
|
|
||||||
#define TRACE(x...) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct identify_cookie
|
struct identify_cookie
|
||||||
@@ -23,7 +19,7 @@ struct identify_cookie
|
|||||||
//! xfs_io() callback hook
|
//! xfs_io() callback hook
|
||||||
static status_t
|
static status_t
|
||||||
iterative_io_get_vecs_hook(void *cookie, io_request *request, off_t offset,
|
iterative_io_get_vecs_hook(void *cookie, io_request *request, off_t offset,
|
||||||
size_t size, struct file_io_vec *vecs, size_t *_count)
|
size_t size, struct file_io_vec *vecs, size_t *_count)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -32,13 +28,15 @@ iterative_io_get_vecs_hook(void *cookie, io_request *request, off_t offset,
|
|||||||
//! xfs_io() callback hook
|
//! xfs_io() callback hook
|
||||||
static status_t
|
static status_t
|
||||||
iterative_io_finished_hook(void *cookie, io_request *request, status_t status,
|
iterative_io_finished_hook(void *cookie, io_request *request, status_t status,
|
||||||
bool partialTransfer, size_t bytesTransferred)
|
bool partialTransfer, size_t bytesTransferred)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Scanning
|
// #pragma mark - Scanning
|
||||||
|
|
||||||
|
|
||||||
static float
|
static float
|
||||||
xfs_identify_partition(int fd, partition_data *partition, void **_cookie)
|
xfs_identify_partition(int fd, partition_data *partition, void **_cookie)
|
||||||
{
|
{
|
||||||
@@ -62,18 +60,48 @@ xfs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
|
|||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_mount(fs_volume *_volume, const char *device, uint32 flags,
|
xfs_mount(fs_volume *_volume, const char *device, uint32 flags,
|
||||||
const char *args, ino_t *_rootID)
|
const char *args, ino_t *_rootID)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
TRACE("xfs_mount(): Trying to mount\n");
|
||||||
|
|
||||||
|
Volume *volume = new (std::nothrow) Volume(_volume);
|
||||||
|
if (volume == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
_volume->private_volume = volume;
|
||||||
|
_volume->ops = &gxfsVolumeOps;
|
||||||
|
|
||||||
|
status_t status = volume->Mount(device, flags);
|
||||||
|
if (status != B_OK) {
|
||||||
|
ERROR("Failed mounting the volume. Error: %s\n", strerror(status));
|
||||||
|
delete volume;
|
||||||
|
_volume->private_volume = NULL;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't have Inodes yet */
|
||||||
|
#if 0
|
||||||
|
*_rootID = volume->Root()->ID();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_unmount(fs_volume *_volume)
|
xfs_unmount(fs_volume *_volume)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
Volume* volume = (Volume*) _volume->private_volume;
|
||||||
|
|
||||||
|
status_t status = volume->Unmount();
|
||||||
|
delete volume;
|
||||||
|
|
||||||
|
TRACE("xfs_unmount(): Deleted volume");
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -86,9 +114,10 @@ xfs_read_fs_info(fs_volume *_volume, struct fs_info *info)
|
|||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_node, int *_type,
|
xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_node, int *_type,
|
||||||
uint32 *_flags, bool reenter)
|
uint32 *_flags, bool reenter)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -110,7 +139,7 @@ xfs_can_page(fs_volume *_volume, fs_vnode *_node, void *_cookie)
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_read_pages(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
xfs_read_pages(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||||
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes)
|
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -118,7 +147,7 @@ xfs_read_pages(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_io(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
xfs_io(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||||
io_request *request)
|
io_request *request)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -126,7 +155,7 @@ xfs_io(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_get_file_map(fs_volume *_volume, fs_vnode *_node, off_t offset,
|
xfs_get_file_map(fs_volume *_volume, fs_vnode *_node, off_t offset,
|
||||||
size_t size, struct file_io_vec *vecs, size_t *_count)
|
size_t size, struct file_io_vec *vecs, size_t *_count)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -134,9 +163,10 @@ xfs_get_file_map(fs_volume *_volume, fs_vnode *_node, off_t offset,
|
|||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
|
xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
|
||||||
ino_t *_vnodeID)
|
ino_t *_vnodeID)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -144,7 +174,7 @@ xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd,
|
xfs_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd,
|
||||||
void *buffer, size_t bufferLength)
|
void *buffer, size_t bufferLength)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -159,7 +189,7 @@ xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_open(fs_volume * /*_volume*/, fs_vnode *_node, int openMode,
|
xfs_open(fs_volume * /*_volume*/, fs_vnode *_node, int openMode,
|
||||||
void **_cookie)
|
void **_cookie)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -167,7 +197,7 @@ xfs_open(fs_volume * /*_volume*/, fs_vnode *_node, int openMode,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
|
xfs_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
|
||||||
void *buffer, size_t *_length)
|
void *buffer, size_t *_length)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -186,6 +216,7 @@ xfs_free_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
|
|||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
|
xfs_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
|
||||||
{
|
{
|
||||||
@@ -195,7 +226,7 @@ xfs_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer,
|
xfs_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer,
|
||||||
size_t *_bufferSize)
|
size_t *_bufferSize)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -210,9 +241,10 @@ xfs_unlink(fs_volume *_volume, fs_vnode *_directory, const char *name)
|
|||||||
|
|
||||||
// #pragma mark - Directory functions
|
// #pragma mark - Directory functions
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_create_dir(fs_volume *_volume, fs_vnode *_directory, const char *name,
|
xfs_create_dir(fs_volume *_volume, fs_vnode *_directory, const char *name,
|
||||||
int mode)
|
int mode)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -234,7 +266,7 @@ xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||||
struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -249,7 +281,7 @@ xfs_rewind_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/, void *_cookie)
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_close_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/,
|
xfs_close_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/,
|
||||||
void * /*_cookie*/)
|
void * /*_cookie*/)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -285,7 +317,7 @@ xfs_free_attr_dir_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_read_attr_dir(fs_volume *_volume, fs_vnode *_node,
|
xfs_read_attr_dir(fs_volume *_volume, fs_vnode *_node,
|
||||||
void *_cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
void *_cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -301,7 +333,7 @@ xfs_rewind_attr_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie)
|
|||||||
/* attribute operations */
|
/* attribute operations */
|
||||||
static status_t
|
static status_t
|
||||||
xfs_create_attr(fs_volume *_volume, fs_vnode *_node,
|
xfs_create_attr(fs_volume *_volume, fs_vnode *_node,
|
||||||
const char *name, uint32 type, int openMode, void **_cookie)
|
const char *name, uint32 type, int openMode, void **_cookie)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -309,7 +341,7 @@ xfs_create_attr(fs_volume *_volume, fs_vnode *_node,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_open_attr(fs_volume *_volume, fs_vnode *_node, const char *name,
|
xfs_open_attr(fs_volume *_volume, fs_vnode *_node, const char *name,
|
||||||
int openMode, void **_cookie)
|
int openMode, void **_cookie)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -317,15 +349,14 @@ xfs_open_attr(fs_volume *_volume, fs_vnode *_node, const char *name,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_close_attr(fs_volume *_volume, fs_vnode *_node,
|
xfs_close_attr(fs_volume *_volume, fs_vnode *_node,
|
||||||
void *cookie)
|
void *cookie)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_free_attr_cookie(fs_volume *_volume, fs_vnode *_node,
|
xfs_free_attr_cookie(fs_volume *_volume, fs_vnode *_node, void *cookie)
|
||||||
void *cookie)
|
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -333,7 +364,7 @@ xfs_free_attr_cookie(fs_volume *_volume, fs_vnode *_node,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_read_attr(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
xfs_read_attr(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||||
off_t pos, void *buffer, size_t *_length)
|
off_t pos, void *buffer, size_t *_length)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -341,7 +372,7 @@ xfs_read_attr(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_write_attr(fs_volume *_volume, fs_vnode *_node, void *cookie,
|
xfs_write_attr(fs_volume *_volume, fs_vnode *_node, void *cookie,
|
||||||
off_t pos, const void *buffer, size_t *length)
|
off_t pos, const void *buffer, size_t *length)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -349,7 +380,7 @@ xfs_write_attr(fs_volume *_volume, fs_vnode *_node, void *cookie,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_read_attr_stat(fs_volume *_volume, fs_vnode *_node,
|
xfs_read_attr_stat(fs_volume *_volume, fs_vnode *_node,
|
||||||
void *_cookie, struct stat *stat)
|
void *_cookie, struct stat *stat)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -357,7 +388,7 @@ xfs_read_attr_stat(fs_volume *_volume, fs_vnode *_node,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_write_attr_stat(fs_volume *_volume, fs_vnode *_node,
|
xfs_write_attr_stat(fs_volume *_volume, fs_vnode *_node,
|
||||||
void *cookie, const struct stat *stat, int statMask)
|
void *cookie, const struct stat *stat, int statMask)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -365,7 +396,7 @@ xfs_write_attr_stat(fs_volume *_volume, fs_vnode *_node,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_rename_attr(fs_volume *_volume, fs_vnode *fromVnode,
|
xfs_rename_attr(fs_volume *_volume, fs_vnode *fromVnode,
|
||||||
const char *fromName, fs_vnode *toVnode, const char *toName)
|
const char *fromName, fs_vnode *toVnode, const char *toName)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -373,7 +404,7 @@ xfs_rename_attr(fs_volume *_volume, fs_vnode *fromVnode,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_remove_attr(fs_volume *_volume, fs_vnode *vnode,
|
xfs_remove_attr(fs_volume *_volume, fs_vnode *vnode,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -388,7 +419,7 @@ xfs_get_supported_operations(partition_data *partition, uint32 mask)
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_initialize(int fd, partition_id partitionID, const char *name,
|
xfs_initialize(int fd, partition_id partitionID, const char *name,
|
||||||
const char *parameterString, off_t partitionSize, disk_job_id job)
|
const char *parameterString, off_t partitionSize, disk_job_id job)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -396,7 +427,7 @@ xfs_initialize(int fd, partition_id partitionID, const char *name,
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
|
xfs_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
|
||||||
uint32 blockSize, disk_job_id job)
|
uint32 blockSize, disk_job_id job)
|
||||||
{
|
{
|
||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -404,6 +435,7 @@ xfs_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
|
|||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
xfs_std_ops(int32 op, ...)
|
xfs_std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
@@ -427,57 +459,59 @@ xfs_std_ops(int32 op, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fs_volume_ops gxfsVolumeOps = {
|
fs_volume_ops gxfsVolumeOps = {
|
||||||
&xfs_unmount,
|
&xfs_unmount,
|
||||||
&xfs_read_fs_info,
|
&xfs_read_fs_info,
|
||||||
NULL, // write_fs_info()
|
NULL, // write_fs_info()
|
||||||
NULL, // fs_sync,
|
NULL, // fs_sync,
|
||||||
&xfs_get_vnode,
|
&xfs_get_vnode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
fs_vnode_ops gxfsVnodeOps = {
|
fs_vnode_ops gxfsVnodeOps = {
|
||||||
/* vnode operations */
|
/* vnode operations */
|
||||||
&xfs_lookup,
|
&xfs_lookup,
|
||||||
NULL, // xfs_get_vnode_name - optional, and we can't do better than the
|
NULL, // xfs_get_vnode_name- optional, and we can't do better
|
||||||
// fallback implementation, so leave as NULL.
|
// than the fallback implementation, so leave as NULL.
|
||||||
&xfs_put_vnode,
|
&xfs_put_vnode,
|
||||||
NULL, // xfs_remove_vnode,
|
NULL, // xfs_remove_vnode,
|
||||||
|
|
||||||
/* VM file access */
|
/* VM file access */
|
||||||
&xfs_can_page,
|
&xfs_can_page,
|
||||||
&xfs_read_pages,
|
&xfs_read_pages,
|
||||||
NULL, // xfs_write_pages,
|
NULL, // xfs_write_pages,
|
||||||
|
|
||||||
&xfs_io, // io()
|
&xfs_io, // io()
|
||||||
NULL, // cancel_io()
|
NULL, // cancel_io()
|
||||||
|
|
||||||
&xfs_get_file_map,
|
&xfs_get_file_map,
|
||||||
|
|
||||||
&xfs_ioctl,
|
&xfs_ioctl,
|
||||||
NULL,
|
NULL,
|
||||||
NULL, // fs_select
|
NULL, // fs_select
|
||||||
NULL, // fs_deselect
|
NULL, // fs_deselect
|
||||||
NULL, // fs_fsync,
|
NULL, // fs_fsync,
|
||||||
|
|
||||||
&xfs_read_link,
|
&xfs_read_link,
|
||||||
NULL, // fs_create_symlink,
|
NULL, // fs_create_symlink,
|
||||||
|
|
||||||
NULL, // fs_link,
|
NULL, // fs_link,
|
||||||
&xfs_unlink,
|
&xfs_unlink,
|
||||||
NULL, // fs_rename,
|
NULL, // fs_rename,
|
||||||
|
|
||||||
&xfs_access,
|
&xfs_access,
|
||||||
&xfs_read_stat,
|
&xfs_read_stat,
|
||||||
NULL, // fs_write_stat,
|
NULL, // fs_write_stat,
|
||||||
NULL, // fs_preallocate
|
NULL, // fs_preallocate
|
||||||
|
|
||||||
/* file operations */
|
/* file operations */
|
||||||
NULL, // fs_create,
|
NULL, // fs_create,
|
||||||
&xfs_open,
|
&xfs_open,
|
||||||
&xfs_close,
|
&xfs_close,
|
||||||
&xfs_free_cookie,
|
&xfs_free_cookie,
|
||||||
&xfs_read,
|
&xfs_read,
|
||||||
NULL, // fs_write,
|
NULL, // fs_write,
|
||||||
|
|
||||||
/* directory operations */
|
/* directory operations */
|
||||||
&xfs_create_dir,
|
&xfs_create_dir,
|
||||||
@@ -509,18 +543,19 @@ fs_vnode_ops gxfsVnodeOps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static file_system_module_info sxfsFileSystem = {
|
static
|
||||||
|
file_system_module_info sxfsFileSystem = {
|
||||||
{
|
{
|
||||||
"file_systems/xfs" B_CURRENT_FS_API_VERSION,
|
"file_systems/xfs" B_CURRENT_FS_API_VERSION,
|
||||||
0,
|
0,
|
||||||
xfs_std_ops,
|
xfs_std_ops,
|
||||||
},
|
},
|
||||||
|
|
||||||
"xfs", // short_name
|
"xfs", // short_name
|
||||||
"XFS File System", // pretty_name
|
"XFS File System", // pretty_name
|
||||||
|
|
||||||
// DDM flags
|
// DDM flags
|
||||||
0| B_DISK_SYSTEM_SUPPORTS_INITIALIZING |B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
0 |B_DISK_SYSTEM_SUPPORTS_INITIALIZING |B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_WRITING
|
// | B_DISK_SYSTEM_SUPPORTS_WRITING
|
||||||
,
|
,
|
||||||
|
|
||||||
@@ -528,29 +563,29 @@ static file_system_module_info sxfsFileSystem = {
|
|||||||
xfs_identify_partition,
|
xfs_identify_partition,
|
||||||
xfs_scan_partition,
|
xfs_scan_partition,
|
||||||
xfs_free_identify_partition_cookie,
|
xfs_free_identify_partition_cookie,
|
||||||
NULL, // free_partition_content_cookie()
|
NULL, // free_partition_content_cookie()
|
||||||
|
|
||||||
&xfs_mount,
|
&xfs_mount,
|
||||||
|
|
||||||
/* capability querying operations */
|
/* capability querying operations */
|
||||||
&xfs_get_supported_operations,
|
&xfs_get_supported_operations,
|
||||||
|
|
||||||
NULL, // validate_resize
|
NULL, // validate_resize
|
||||||
NULL, // validate_move
|
NULL, // validate_move
|
||||||
NULL, // validate_set_content_name
|
NULL, // validate_set_content_name
|
||||||
NULL, // validate_set_content_parameters
|
NULL, // validate_set_content_parameters
|
||||||
NULL, // validate_initialize,
|
NULL, // validate_initialize,
|
||||||
|
|
||||||
/* shadow partition modification */
|
/* shadow partition modification */
|
||||||
NULL, // shadow_changed
|
NULL, // shadow_changed
|
||||||
|
|
||||||
/* writing */
|
/* writing */
|
||||||
NULL, // defragment
|
NULL, // defragment
|
||||||
NULL, // repair
|
NULL, // repair
|
||||||
NULL, // resize
|
NULL, // resize
|
||||||
NULL, // move
|
NULL, // move
|
||||||
NULL, // set_content_name
|
NULL, // set_content_name
|
||||||
NULL, // set_content_parameters
|
NULL, // set_content_parameters
|
||||||
xfs_initialize,
|
xfs_initialize,
|
||||||
xfs_uninitialize};
|
xfs_uninitialize};
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 Shubham Bhagat, [email protected]
|
* Copyright 2007, Ingo Weinhold, [email protected].
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYSTE_DEPENDENCIES_H
|
#ifndef _SYSTEM_DEPENDENCIES_H_
|
||||||
#define _SYSTEM_DEPENDENCIES_H
|
#define _SYSTEM_DEPENDENCIES_H_
|
||||||
|
|
||||||
#ifdef FS_SHELL
|
#ifdef FS_SHELL
|
||||||
// This needs to be included before the fs_shell wrapper
|
// This needs to be included before the fs_shell wrapper
|
||||||
|
|
||||||
#include "fssh_api_wrapper.h"
|
#include "fssh_api_wrapper.h"
|
||||||
#include "fssh_auto_deleter.h"
|
#include "fssh_auto_deleter.h"
|
||||||
#include <new>
|
#include "Debug.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
typedef unsigned char uuid_t[16];
|
typedef unsigned char uuid_t[16];
|
||||||
|
|
||||||
void uuid_generate(uuid_t out);
|
void uuid_generate(uuid_t out);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#else // !FS_SHELL
|
#else // !FS_SHELL
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
@@ -44,6 +45,7 @@ void uuid_generate(uuid_t out);
|
|||||||
#include <fs_interface.h>
|
#include <fs_interface.h>
|
||||||
#include <fs_query.h>
|
#include <fs_query.h>
|
||||||
#include <fs_volume.h>
|
#include <fs_volume.h>
|
||||||
|
#include "Debug.h"
|
||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <NodeMonitor.h>
|
#include <NodeMonitor.h>
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xfs.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
XfsSuperBlock::IsValid()
|
||||||
|
{
|
||||||
|
if (sb_magicnum != XFS_SB_MAGIC) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
XfsSuperBlock::BlockSize()
|
||||||
|
{
|
||||||
|
return sb_blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
XfsSuperBlock::Size()
|
||||||
|
{
|
||||||
|
return XFS_SB_MAXSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
XfsSuperBlock::Name()
|
||||||
|
{
|
||||||
|
return sb_fname;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
XfsSuperBlock::SwapEndian()
|
||||||
|
{
|
||||||
|
sb_magicnum = B_BENDIAN_TO_HOST_INT32(sb_magicnum);
|
||||||
|
sb_blocksize = B_BENDIAN_TO_HOST_INT32(sb_blocksize);
|
||||||
|
sb_dblocks = B_BENDIAN_TO_HOST_INT64(sb_dblocks);
|
||||||
|
sb_rblocks = B_BENDIAN_TO_HOST_INT64(sb_rblocks);
|
||||||
|
sb_rextents = B_BENDIAN_TO_HOST_INT64(sb_rextents);
|
||||||
|
sb_logstart = B_BENDIAN_TO_HOST_INT64(sb_logstart);
|
||||||
|
sb_rootino = B_BENDIAN_TO_HOST_INT64(sb_rootino);
|
||||||
|
sb_rbmino = B_BENDIAN_TO_HOST_INT64(sb_rbmino);
|
||||||
|
sb_rsumino = B_BENDIAN_TO_HOST_INT64(sb_rsumino);
|
||||||
|
sb_rextsize = B_BENDIAN_TO_HOST_INT32(sb_rextsize);
|
||||||
|
sb_agblocks = B_BENDIAN_TO_HOST_INT32(sb_agblocks);
|
||||||
|
sb_agcount = B_BENDIAN_TO_HOST_INT32(sb_agcount);
|
||||||
|
sb_rbmblocks = B_BENDIAN_TO_HOST_INT32(sb_rbmblocks);
|
||||||
|
sb_logblocks = B_BENDIAN_TO_HOST_INT32(sb_logblocks);
|
||||||
|
sb_versionnum = B_BENDIAN_TO_HOST_INT16(sb_versionnum);
|
||||||
|
sb_sectsize = B_BENDIAN_TO_HOST_INT16(sb_sectsize);
|
||||||
|
sb_inodesize = B_BENDIAN_TO_HOST_INT16(sb_inodesize);
|
||||||
|
sb_inopblock = B_BENDIAN_TO_HOST_INT16(sb_inopblock);
|
||||||
|
sb_icount = B_BENDIAN_TO_HOST_INT64(sb_icount);
|
||||||
|
sb_ifree = B_BENDIAN_TO_HOST_INT64(sb_ifree);
|
||||||
|
sb_fdblocks = B_BENDIAN_TO_HOST_INT64(sb_fdblocks);
|
||||||
|
sb_frextents = B_BENDIAN_TO_HOST_INT64(sb_frextents);
|
||||||
|
sb_uquotino = B_BENDIAN_TO_HOST_INT64(sb_uquotino);
|
||||||
|
sb_gquotino = B_BENDIAN_TO_HOST_INT64(sb_gquotino);
|
||||||
|
sb_qflags = B_BENDIAN_TO_HOST_INT16(sb_qflags);
|
||||||
|
sb_inoalignmt = B_BENDIAN_TO_HOST_INT32(sb_inoalignmt);
|
||||||
|
sb_unit = B_BENDIAN_TO_HOST_INT32(sb_unit);
|
||||||
|
sb_width = B_BENDIAN_TO_HOST_INT32(sb_width);
|
||||||
|
sb_logsectsize = B_BENDIAN_TO_HOST_INT16(sb_logsectsize);
|
||||||
|
sb_logsunit = B_BENDIAN_TO_HOST_INT32(sb_logsunit);
|
||||||
|
sb_features2 = B_BENDIAN_TO_HOST_INT32(sb_features2);
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XFS_SB_H_
|
||||||
|
#define _XFS_SB_H_
|
||||||
|
|
||||||
|
#include "system_dependencies.h"
|
||||||
|
#include "xfs_types.h"
|
||||||
|
|
||||||
|
#define XFS_SB_MAGIC 0x58465342 /* Identifies XFS. "XFSB" */
|
||||||
|
#define XFS_SB_MAXSIZE 512
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Version 4 superblock definition */
|
||||||
|
class XfsSuperBlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool IsValid();
|
||||||
|
char* Name();
|
||||||
|
uint32 BlockSize();
|
||||||
|
uint32 Size();
|
||||||
|
void SwapEndian();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint32 sb_magicnum;
|
||||||
|
uint32 sb_blocksize;
|
||||||
|
xfs_rfsblock_t sb_dblocks;
|
||||||
|
xfs_rfsblock_t sb_rblocks;
|
||||||
|
xfs_rtblock_t sb_rextents;
|
||||||
|
uuid_t sb_uuid;
|
||||||
|
xfs_fsblock_t sb_logstart;
|
||||||
|
xfs_ino_t sb_rootino;
|
||||||
|
xfs_ino_t sb_rbmino;
|
||||||
|
xfs_ino_t sb_rsumino;
|
||||||
|
xfs_agblock_t sb_rextsize;
|
||||||
|
xfs_agblock_t sb_agblocks;
|
||||||
|
xfs_agnumber_t sb_agcount;
|
||||||
|
xfs_extlen_t sb_rbmblocks;
|
||||||
|
xfs_extlen_t sb_logblocks;
|
||||||
|
uint16 sb_versionnum;
|
||||||
|
uint16 sb_sectsize;
|
||||||
|
uint16 sb_inodesize;
|
||||||
|
uint16 sb_inopblock;
|
||||||
|
char sb_fname[12];
|
||||||
|
uint8 sb_blocklog;
|
||||||
|
uint8 sb_sectlog;
|
||||||
|
uint8 sb_inodelog;
|
||||||
|
uint8 sb_inopblog;
|
||||||
|
uint8 sb_agblklog;
|
||||||
|
uint8 sb_rextslog;
|
||||||
|
uint8 sb_inprogress;
|
||||||
|
uint8 sb_imax_pct;
|
||||||
|
uint64 sb_icount;
|
||||||
|
uint64 sb_ifree;
|
||||||
|
uint64 sb_fdblocks;
|
||||||
|
uint64 sb_frextents;
|
||||||
|
xfs_ino_t sb_uquotino;
|
||||||
|
xfs_ino_t sb_gquotino;
|
||||||
|
uint16 sb_qflags;
|
||||||
|
uint8 sb_flags;
|
||||||
|
uint8 sb_shared_vn;
|
||||||
|
xfs_extlen_t sb_inoalignmt;
|
||||||
|
uint32 sb_unit;
|
||||||
|
uint32 sb_width;
|
||||||
|
uint8 sb_dirblklog;
|
||||||
|
uint8 sb_logsectlog;
|
||||||
|
uint16 sb_logsectsize;
|
||||||
|
uint32 sb_logsunit;
|
||||||
|
uint32 sb_features2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
These flags indicate features introduced over time.
|
||||||
|
|
||||||
|
If the lower nibble of sb_versionnum >=4 then the following features are
|
||||||
|
checked. If it's equal to 5, it's version 5.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XFS_SB_VERSION_ATTRBIT 0x0010
|
||||||
|
#define XFS_SB_VERSION_NLINKBIT 0x0020
|
||||||
|
#define XFS_SB_VERSION_QUOTABIT 0x0040
|
||||||
|
#define XFS_SB_VERSION_ALIGNBIT 0x0080
|
||||||
|
#define XFS_SB_VERSION_DALIGNBIT 0x0100
|
||||||
|
#define XFS_SB_VERSION_SHAREDBIT 0x0200
|
||||||
|
#define XFS_SB_VERSION_LOGV2BIT 0x0400
|
||||||
|
#define XFS_SB_VERSION_SECTORBIT 0x0800
|
||||||
|
#define XFS_SB_VERSION_EXTFLGBIT 0x1000
|
||||||
|
#define XFS_SB_VERSION_DIRV2BIT 0x2000
|
||||||
|
#define XFS_SB_VERSION_MOREBITSBIT 0x4000
|
||||||
|
|
||||||
|
/*
|
||||||
|
Superblock quota flags - sb_qflags
|
||||||
|
*/
|
||||||
|
#define XFS_UQUOTA_ACCT 0x0001
|
||||||
|
#define XFS_UQUOTA_ENFD 0x0002
|
||||||
|
#define XFS_UQUOTA_CHKD 0x0004
|
||||||
|
#define XFS_PQUOTA_ACCT 0x0008
|
||||||
|
#define XFS_OQUOTA_ENFD 0x0010
|
||||||
|
#define XFS_OQUOTA_CHKD 0x0020
|
||||||
|
#define XFS_GQUOTA_ACCT 0x0040
|
||||||
|
#define XFS_GQUOTA_ENFD 0x0080
|
||||||
|
#define XFS_GQUOTA_CHKD 0x0100
|
||||||
|
#define XFS_PQUOTA_ENFD 0x0200
|
||||||
|
#define XFS_PQUOTA_CHKD 0x0400
|
||||||
|
|
||||||
|
/*
|
||||||
|
Superblock flags - sb_flags
|
||||||
|
*/
|
||||||
|
#define XFS_SBF_READONLY 0x1
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended v4 Superblock flags - sb_features2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XFS_SB_VERSION2_LAZYSBCOUNTBIT \
|
||||||
|
0x0001 /*update global free space \
|
||||||
|
and inode on clean unmount*/
|
||||||
|
#define XFS_SB_VERSION2_ATTR2BIT \
|
||||||
|
0x0002 /* optimises the inode layout of ext-attr */
|
||||||
|
#define XFS_SB_VERSION2_PARENTBIT 0x0004 /* Parent pointers */
|
||||||
|
#define XFS_SB_VERSION2_PROJID32BIT 0x0008 /* 32-bit project id */
|
||||||
|
#define XFS_SB_VERSION2_CRCBIT 0x0010 /* Metadata checksumming */
|
||||||
|
#define XFS_SB_VERSION2_FTYPE 0x0020
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020, Shubham Bhagat, [email protected]
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _XFS_TYPES_H_
|
||||||
|
#define _XFS_TYPES_H_
|
||||||
|
|
||||||
|
#include "system_dependencies.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reference documentation:
|
||||||
|
https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs
|
||||||
|
/xfs_filesystem_structure.pdf
|
||||||
|
|
||||||
|
Chapter 5: Common XFS types (Page 8)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint64 xfs_ino_t; // absolute inode number
|
||||||
|
typedef int64 xfs_off_t; // file offset
|
||||||
|
typedef int64 xfs_daddr_t; // device address
|
||||||
|
typedef uint32 xfs_agnumber_t; // Allocation Group (AG) number
|
||||||
|
typedef uint32 xfs_agblock_t; // AG relative block number
|
||||||
|
typedef uint32 xfs_extlen_t; // extent length in blocks
|
||||||
|
typedef int32 xfs_extnum_t; // number of extends in a file
|
||||||
|
typedef int16 xfs_aextnum_t; // number of extents in an attribute fork
|
||||||
|
typedef uint32 xfs_dablk_t; // block number for directories
|
||||||
|
// and extended attributes
|
||||||
|
typedef uint32 xfs_dahash_t; // hash of a directory file name
|
||||||
|
// or extended attribute name
|
||||||
|
typedef uint64 xfs_fsblock_t; // filesystem block number combining AG number
|
||||||
|
// and block offset into the AG
|
||||||
|
typedef uint64 xfs_rfsblock_t; // raw filesystem block number
|
||||||
|
typedef uint64 xfs_rtblock_t; // extent number in the real-time sub-volume
|
||||||
|
typedef uint64 xfs_filoff_t; // block offset into a file
|
||||||
|
typedef uint64 xfs_filblks_t; // block count for a file
|
||||||
|
typedef int64 xfs_fsize_t; // byte size of a file
|
||||||
|
|
||||||
|
// typedef unsigned char uuid_t[16];
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -38,15 +38,17 @@ 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 =
|
||||||
|
xfs.cpp
|
||||||
|
Volume.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
BuildPlatformMergeObject <build>xfs.o : $(xfsSource) ;
|
BuildPlatformMergeObject <build>xfs_shell.o : $(xfsSource) ;
|
||||||
|
|
||||||
BuildPlatformMain <build>xfs_shell
|
BuildPlatformMain <build>xfs_shell
|
||||||
:
|
:
|
||||||
:
|
:
|
||||||
<build>xfs.o
|
<build>xfs_shell.o
|
||||||
<build>fs_shell.a $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
|
<build>fs_shell.a $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
|
||||||
$(HOST_LIBROOT) $(fsShellCommandLibs)
|
$(HOST_LIBROOT) $(fsShellCommandLibs)
|
||||||
;
|
;
|
||||||
@@ -54,7 +56,7 @@ BuildPlatformMain <build>xfs_shell
|
|||||||
BuildPlatformMain <build>xfs_fuse
|
BuildPlatformMain <build>xfs_fuse
|
||||||
:
|
:
|
||||||
:
|
:
|
||||||
<build>xfs.o
|
<build>xfs_shell.o
|
||||||
<build>fuse_module.a
|
<build>fuse_module.a
|
||||||
$(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
|
$(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
|
||||||
$(HOST_STATIC_LIBROOT) $(fsShellCommandLibs) fuse
|
$(HOST_STATIC_LIBROOT) $(fsShellCommandLibs) fuse
|
||||||
|
|||||||
Reference in New Issue
Block a user