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:
CruxBox
2020-03-09 08:52:50 +00:00
committed by Adrien Destugues
parent 0d2645e44f
commit 2deffe2f3f
10 changed files with 715 additions and 84 deletions
@@ -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
@@ -39,6 +35,8 @@ iterative_io_finished_hook(void *cookie, io_request *request, status_t status,
// #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,6 +114,7 @@ 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)
@@ -134,6 +163,7 @@ 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)
@@ -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)
{ {
@@ -210,6 +241,7 @@ 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)
@@ -324,8 +356,7 @@ xfs_close_attr(fs_volume *_volume, fs_vnode *_node,
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;
} }
@@ -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,6 +459,7 @@ 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,
@@ -435,11 +468,12 @@ fs_volume_ops gxfsVolumeOps = {
&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,
@@ -509,7 +543,8 @@ 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,
@@ -520,7 +555,7 @@ static file_system_module_info sxfsFileSystem = {
"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
, ,
@@ -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);
}
+129
View File
@@ -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