diff --git a/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp index f199e10903..07432a11d8 100644 --- a/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp @@ -1,6 +1,13 @@ +/* +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* All rights reserved. Distributed under the terms of the MIT License. +*/ + #include "BPlusTree.h" -void bplustree_short_block::SwapEndian() + +void +bplustree_short_block::SwapEndian() { bb_magic = B_BENDIAN_TO_HOST_INT32(bb_magic); bb_level = B_BENDIAN_TO_HOST_INT16(bb_level); @@ -10,7 +17,8 @@ void bplustree_short_block::SwapEndian() } -void bplustree_long_block::SwapEndian() +void +bplustree_long_block::SwapEndian() { bb_magic = B_BENDIAN_TO_HOST_INT32(bb_magic); bb_level = B_BENDIAN_TO_HOST_INT16(bb_level); @@ -20,70 +28,100 @@ void bplustree_long_block::SwapEndian() } -void xfs_alloc_rec::SwapEndian() +void +xfs_alloc_rec::SwapEndian() { ar_startblock = B_BENDIAN_TO_HOST_INT32(ar_startblock); ar_blockcount = B_BENDIAN_TO_HOST_INT32(ar_blockcount); } -uint32 BPlusTree::BlockSize(){ +uint32 +BPlusTree::BlockSize() +{ return fVolume.SuperBlock().BlockSize(); } -int BPlusTree::RecordSize(){ +int +BPlusTree::RecordSize() +{ if (fRecType == ALLOC_FLAG) return XFS_ALLOC_REC_SIZE; + + return B_BAD_VALUE; } -int BPlusTree::MaxRecords(bool leaf){ +int +BPlusTree::MaxRecords(bool leaf) +{ int blockLen = BlockSize(); - + if (fPtrType == SHORT_BLOCK_FLAG) blockLen - XFS_BTREE_SBLOCK_SIZE; - if (leaf){ + if (leaf) { if (fRecType == ALLOC_FLAG) - return blockLen/sizeof(xfs_alloc_rec_t); - } - else { - if (fKeyType) == ALLOC_FLAG){ - return blockLen/(sizeof(xfs_alloc_key_t) + return blockLen / sizeof(xfs_alloc_rec_t); + } else { + if (fKeyType == ALLOC_FLAG) { + return blockLen / (sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t)); } } + + return B_BAD_VALUE; } -int BPlusTree::KeyLen(){ - if (fKeyType == ALLOC_FLAG) return XFS_ALLOC_REC_SIZE; +int +BPlusTree::KeyLen() +{ + if (fKeyType == ALLOC_FLAG) + return XFS_ALLOC_REC_SIZE; + return B_BAD_VALUE; } -int BPlusTree::BlockLen(){ - if(fPtrType == LONG_BLOCK_FLAG) return XFS_BTREE_LBLOCK_SIZE; - else return XFS_BTREE_SBLOCK_SIZE; +int +BPlusTree::BlockLen() +{ + if (fPtrType == LONG_BLOCK_FLAG) + return XFS_BTREE_LBLOCK_SIZE; + if (fPtrType == SHORT_BLOCK_FLAG) + return XFS_BTREE_SBLOCK_SIZE; + return B_BAD_VALUE; } -int BPlusTree::PtrLen(){ - if(fPtrType == LONG_BLOCK_FLAG) return sizeof(uint64); - else return sizeof(uint32); +int +BPlusTree::PtrLen() +{ + if (fPtrType == LONG_BLOCK_FLAG) + return sizeof(uint64); + else + return sizeof(uint32); } -int BPlusTree::RecordOffset(int pos){ - return BlockLen() + (pos-1)*RecordSize(); +int +BPlusTree::RecordOffset(int pos) +{ + return BlockLen() + (pos - 1) * RecordSize(); } -int BPlusTree::KeyOffset(int pos){ - return BlockLen() + (pos-1)*KeyLen(); +int +BPlusTree::KeyOffset(int pos) +{ + return BlockLen() + (pos - 1) * KeyLen(); } -int BPlusTree::PtrOffset(int pos, int level){ - return BlockLen() + MaxRecords(level>0)*KeyLen() + (pos-1)*PtrLen(); +int +BPlusTree::PtrOffset(int pos, int level) +{ + return BlockLen() + MaxRecords(level > 0) * KeyLen() + + (pos - 1) * PtrLen(); } diff --git a/src/add-ons/kernel/file_systems/xfs/BPlusTree.h b/src/add-ons/kernel/file_systems/xfs/BPlusTree.h index d9e0828b20..7156e7a2bb 100644 --- a/src/add-ons/kernel/file_systems/xfs/BPlusTree.h +++ b/src/add-ons/kernel/file_systems/xfs/BPlusTree.h @@ -1,3 +1,8 @@ +/* +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* All rights reserved. Distributed under the terms of the MIT License. +*/ + #ifndef _BPLUS_TREE_H_ #define _BPLUS_TREE_H_ @@ -11,23 +16,47 @@ /* Header for Short Format btree */ #define XFS_BTREE_SBLOCK_SIZE 18 +/* Header for Long Format btree */ +#define XFS_BTREE_LBLOCK_SIZE 24 + + /* * Headers are the "nodes" really and are called "blocks". The records, keys and * pts are calculated using helpers */ struct bplustree_short_block { + void SwapEndian(); + + uint32 Magic() + { return bb_magic; } + + uint16 Level() + { return bb_level; } + + uint16 NumRecs() + { return bb_numrecs; } + + xfs_alloc_ptr_t Left() + { return bb_leftsib; } + + xfs_alloc_ptr_t Right() + { return bb_rightsib;} + uint32 bb_magic; uint16 bb_level; uint16 bb_numrecs; uint32 bb_leftsib; uint32 bb_rightsib; +} + +struct bplustree_long_block { void SwapEndian(); uint32 Magic() { return bb_magic; } - + uint16 Level() { return bb_level; } @@ -39,43 +68,18 @@ struct bplustree_short_block { xfs_alloc_ptr_t Right() { return bb_rightsib;} -} - -/* Header for Long Format btree */ -#define XFS_BTREE_LBLOCK_SIZE 24 -struct bplustree_long_block { uint32 bb_magic; uint16 bb_level; uint16 bb_numrecs; uint64 bb_leftsib; uint64 bb_rightsib; - - void SwapEndian(); - - uint32 Magic() - { return bb_magic; } - - uint16 Level() - { return bb_level; } - - uint16 NumRecs() - { return bb_numrecs; } - - xfs_alloc_ptr_t Left() - { return bb_leftsib; } - - xfs_alloc_ptr_t Right() - { return bb_rightsib;} } /* Array of these records in the leaf node along with above headers */ #define XFS_ALLOC_REC_SIZE 8 typedef struct xfs_alloc_rec { - uint32 ar_startblock; - uint32 ar_blockcount; - void SwapEndian(); uint32 StartBlock() @@ -84,6 +88,9 @@ typedef struct xfs_alloc_rec { uint32 BlockCount() { return ar_blockcount; } + uint32 ar_startblock; + uint32 ar_blockcount; + } xfs_alloc_rec_t, xfs_alloc_key_t; // Swap Endians while returning itself @@ -99,14 +106,17 @@ union btree_ptr { bplustree_short_block fShortBlock; } + union btree_key { xfs_alloc_key_t fAlloc; } + union btree_rec { xfs_alloc_rec_t fAlloc; } + class BPlusTree { public: uint32 BlockSize(); @@ -128,4 +138,6 @@ class BPlusTree { int fPtrType; } + #endif + diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.cpp b/src/add-ons/kernel/file_systems/xfs/Inode.cpp new file mode 100644 index 0000000000..9f5ff1aebf --- /dev/null +++ b/src/add-ons/kernel/file_systems/xfs/Inode.cpp @@ -0,0 +1,112 @@ +#include "Inode.h" + + +void +xfs_inode::SwapEndian() +{ + di_magic = B_BENDIAN_TO_HOST_INT16(di_magic); + di_mode = B_BENDIAN_TO_HOST_INT16(di_mode); + di_onlink = B_BENDIAN_TO_HOST_INT16(di_onlink); + di_uid = B_BENDIAN_TO_HOST_INT32(di_uid); + di_gid = B_BENDIAN_TO_HOST_INT32(di_gid); + di_nlink = B_BENDIAN_TO_HOST_INT32(di_nlink); + di_projid = B_BENDIAN_TO_HOST_INT16(di_projid); + di_flushiter = B_BENDIAN_TO_HOST_INT16(di_flushiter); + di_atime.t_sec = B_BENDIAN_TO_HOST_INT32(di_atime.t_sec); + di_atime.t_nsec = B_BENDIAN_TO_HOST_INT32(di_atime.t_nsec); + di_mtime.t_sec = B_BENDIAN_TO_HOST_INT32(di_mtime.t_sec); + di_mtime.t_nsec = B_BENDIAN_TO_HOST_INT32(di_mtime.t_nsec); + di_ctime.t_sec = B_BENDIAN_TO_HOST_INT32(di_ctime.t_sec); + di_ctime.t_nsec = B_BENDIAN_TO_HOST_INT32(di_ctime.t_nsec); + di_size = B_BENDIAN_TO_HOST_INT64(di_size); + di_nblocks = B_BENDIAN_TO_HOST_INT64(di_nblocks); + di_extsize = B_BENDIAN_TO_HOST_INT32(di_extsize); + di_nextents = B_BENDIAN_TO_HOST_INT32(di_nextents); + di_anextents = B_BENDIAN_TO_HOST_INT16(di_anextents); + di_dmevmask = B_BENDIAN_TO_HOST_INT32(di_dmevmask); + di_dmstate = B_BENDIAN_TO_HOST_INT16(di_dmstate); + di_flags = B_BENDIAN_TO_HOST_INT16(di_flags); + di_gen = B_BENDIAN_TO_HOST_INT32(di_gen); + di_next_unlinked = B_BENDIAN_TO_HOST_INT32(di_next_unlinked); +} + + +mode_t +xfs_inode::Mode() +{ + return di_mode; +} + + +Inode::Inode(Volume* volume, xfs_ino_t id) +{ + fVolume = volume; + fId = id; + fNode = new(std::nothrow) xfs_inode_t; + + uint16 inodeSize = volume->InodeSize(); + fBuffer = new(std::nothrow) char[inodeSize]; + + status_t status = GetFromDisk(); + if (status == B_OK) { + status = InitCheck(); + if (status) { + TRACE("Inode successfully read!"); + } else { + TRACE("Inode wasn't read successfully!"); + } + } +} + + +status_t +Inode::GetFromDisk() +{ + xfs_agnumber_t agNo = INO_TO_AGNO(fId, fVolume); + // Get the AG number from the inode + uint32 agInodeNo = INO_TO_AGINO(fId, fVolume->AgInodeBits()); + // AG relative ino # + xfs_agblock_t agBlock = INO_TO_AGBLOCK(agInodeNo, fVolume); + // AG relative block number + xfs_off_t offset = INO_TO_OFFSET(fId, fVolume); + // Offset into the block + uint32 len = fVolume->InodeSize(); + // Inode len to read (size of inode) + int fd = fVolume->Device(); + + if (agNo > fVolume->AgCount()) { + ERROR("Inode::GetFromDisk : AG Number more than number of AGs"); + return B_ENTRY_NOT_FOUND; + } + + xfs_agblock_t agBlocks = fVolume->AgBlocks(); + + xfs_fsblock_t blockToRead = + FSB_TO_BB(fVolume->BlockLog(), ((uint64)(agNo * agBlocks) + agBlock)); + + xfs_daddr_t readPos = blockToRead*(BBLOCKSIZE) + offset; + + if (read_pos(fd, readPos, fBuffer, len) != len) { + ERROR("Inode::Inode(): IO Error"); + return B_IO_ERROR; + } + + memcpy(fNode, fBuffer, INODE_CORE_UNLINKED_SIZE); + fNode->SwapEndian(); + + return B_OK; +} + + +bool +Inode::InitCheck() +{ + return fNode->di_magic == INODE_MAGIC; +} + + +Inode::~Inode() +{ + delete fBuffer; + delete fNode; +} diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.h b/src/add-ons/kernel/file_systems/xfs/Inode.h new file mode 100644 index 0000000000..e6c3e848d4 --- /dev/null +++ b/src/add-ons/kernel/file_systems/xfs/Inode.h @@ -0,0 +1,146 @@ +/* +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* All rights reserved. Distributed under the terms of the MIT License. +*/ + +#ifndef _INODE_H_ +#define _INODE_H_ + + +#include "system_dependencies.h" +#include "Volume.h" +#include "xfs_types.h" + + +#define INODE_MAGIC 0x494e +#define INODE_CORE_SIZE 96 // For v4 FS +#define INODE_CORE_UNLINKED_SIZE 100 //For v4 FS +#define DATA_FORK_OFFSET 0x64 + +#define INO_MASK(x) ((1ULL << (x)) - 1) + // Gets 2^x - 1 +#define INO_TO_AGNO(id, volume) (xfs_agnumber_t)id >> (volume->AgInodeBits()) + // Gets AG number from inode number +#define INO_TO_AGINO(id, bits) (uint32) id & INO_MASK(bits); + // Gets the AG relative inode number +#define INO_TO_AGBLOCK(id, volume) \ + (id >> (volume->InodesPerBlkLog())) \ + & (INO_MASK(volume->AgBlocksLog())) + // Gets the AG relative block number that contains inode +#define INO_TO_OFFSET(id, volume) (id & INO_MASK(volume->InodesPerBlkLog())) + // Gets the offset into the block from the inode number + + +typedef struct xfs_timestamp +{ + int32 t_sec; + int32 t_nsec; +} xfs_timestamp_t; + + +typedef enum xfs_dinode_fmt +{ + XFS_DINODE_FMT_DEV, // For devices + XFS_DINODE_FMT_LOCAL, // For Directories and links + XFS_DINODE_FMT_EXTENTS, // For large number of extents + XFS_DINODE_FMT_BTREE, // Extents and Directories + XFS_DINODE_FMT_UUID, // Not used +} xfs_dinode_fmt_t; + + +/* + The xfs_ino_t is the same for all types of inodes, the data and attribute + fork might be different and that is to be handled accordingly. +*/ +typedef struct xfs_inode +{ + void SwapEndian(); + void DirIsV2(); //TODO + mode_t Mode(); + void GetModificationTime(); + int8 Format(); // The format of the inode + + uint16 di_magic; + uint16 di_mode; // uses standard S_Ixxx + int8 di_version; // 1 or 2 + int8 di_format; + uint16 di_onlink; + uint32 di_uid; + uint32 di_gid; + uint32 di_nlink; + uint16 di_projid; + uint8 di_pad[8]; + uint16 di_flushiter; + xfs_timestamp_t di_atime; + xfs_timestamp_t di_mtime; + xfs_timestamp_t di_ctime; + xfs_fsize_t di_size; // size in bytes or length if link + xfs_rfsblock_t di_nblocks; // blocks used including metadata + // extended attributes not included + xfs_extlen_t di_extsize; // extent size + xfs_extnum_t di_nextents; // number of data extents + xfs_aextnum_t di_anextents; // number of EA extents + uint8 di_forkoff; // decides where di_a starts + int8 di_aformat; // similar to di_format + uint32 di_dmevmask; + uint16 di_dmstate; + uint16 di_flags; + uint32 di_gen; + + uint32 di_next_unlinked; +} xfs_inode_t; + + +class Inode +{ + public: + Inode(Volume* volume, xfs_ino_t id); + ~Inode(); + bool InitCheck(); + bool IsDirectory() const + { return S_ISDIR(Mode()); } + + bool IsFile() const + { return S_ISREG(Mode()); } + + bool IsSymLink() const + { return S_ISLNK(Mode()); } + + mode_t Mode() const { return fNode->Mode(); } + + Volume* GetVolume() { return fVolume;} + + int8 Format() { return fNode->Format(); } + + bool IsLocal() { return Format() == XFS_DINODE_FMT_LOCAL; } + + #if 0 + int32 Flags() const { return fNode->Flags(); } + + off_t Size() const { return fNode->Size(); } + + void GetChangeTime(xfs_timestamp_t *stamp) const + { fNode.GetChangeTime(stamp, fHasExtraAttributes); } + + void GetModificationTime(xfs_timestamp_t *stamp) const + { fNode.GetModificationTime(stamp, + fHasExtraAttributes); } + + void GetCreationTime(xfs_timestamp_t *stamp) const + { fNode.GetCreationTime(stamp, + fHasExtraAttributes); } + + void GetAccessTime(xfs_timestamp_t *stamp) const + { fNode.GetAccessTime(stamp, fHasExtraAttributes); } + #endif + + private: + + status_t GetFromDisk(); + xfs_inode_t* fNode; + xfs_ino_t fId; + Volume* fVolume; + char* fBuffer; // Contains the disk inode in BE format +}; + +#endif diff --git a/src/add-ons/kernel/file_systems/xfs/Jamfile b/src/add-ons/kernel/file_systems/xfs/Jamfile index 228377d12c..1a6803e53e 100644 --- a/src/add-ons/kernel/file_systems/xfs/Jamfile +++ b/src/add-ons/kernel/file_systems/xfs/Jamfile @@ -2,13 +2,13 @@ SubDir HAIKU_TOP src add-ons kernel file_systems xfs ; # set some additional defines { - local defines = - XFS_DEBUGGER_COMMANDS - ; + local defines = + XFS_DEBUGGER_COMMANDS + ; - defines = [ FDefines $(defines) ] ; - SubDirCcFlags $(defines) ; - SubDirC++Flags $(defines) ; + defines = [ FDefines $(defines) ] ; + SubDirCcFlags $(defines) ; + SubDirC++Flags $(defines) ; } UsePrivateHeaders [ FDirName kernel util ] ; @@ -20,23 +20,23 @@ DEFINES += DEBUG_APP="\\\"xfs\\\"" ; UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ; local xfsSources = - DeviceOpener.cpp - xfs.cpp - Volume.cpp - kernel_cpp.cpp - kernel_interface.cpp - ; + Inode.cpp + kernel_cpp.cpp + kernel_interface.cpp + Volume.cpp + xfs.cpp + ; KernelAddon xfs : - $(xfsSources) - : + $(xfsSources) + : libuuid_kernel.a ; SEARCH on [ FGristFiles $(xfsSources) ] - = [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ; + = [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ; SEARCH on [ FGristFiles DeviceOpener.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ; SEARCH on [ FGristFiles kernel_cpp.cpp ] - = [ FDirName $(HAIKU_TOP) src system kernel util ] ; \ No newline at end of file + = [ FDirName $(HAIKU_TOP) src system kernel util ] ; \ No newline at end of file diff --git a/src/add-ons/kernel/file_systems/xfs/Volume.h b/src/add-ons/kernel/file_systems/xfs/Volume.h index f008476404..1a9be65efe 100644 --- a/src/add-ons/kernel/file_systems/xfs/Volume.h +++ b/src/add-ons/kernel/file_systems/xfs/Volume.h @@ -1,14 +1,18 @@ /* - * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com - * All rights reserved. Distributed under the terms of the MIT License. - */ +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* 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; + +/* Converting the FS Blocks to Basic Blocks */ +#define FSBSHIFT(fsBlockLog) (fsBlockLog - BBLOCKLOG); +#define FSB_TO_BB(fsBlockLog, x) x << FSBSHIFT(fsBlockLog); + enum volume_flags { VOLUME_READ_ONLY = 0x0001 }; @@ -38,15 +42,35 @@ public: XfsSuperBlock& SuperBlock() { return fSuperBlock; } int Device() const { return fDevice; } - static status_t Identify(int fd, XfsSuperBlock *superBlock); + static status_t Identify(int fd, XfsSuperBlock *superBlock); + + uint32 BlockSize() { return fSuperBlock.BlockSize(); } + + uint8 BlockLog() { return fSuperBlock.BlockLog(); } + + uint32 DirBlockSize() + { return fSuperBlock.DirBlockSize(); } + + uint8 AgInodeBits() + { return fSuperBlock.AgInodeBits(); } + + uint8 AgBlocksLog() + { return fSuperBlock.AgBlocksLog(); } + + uint8 InodesPerBlkLog() + { return fSuperBlock.InodesPerBlkLog(); } + + off_t Root() const { return fSuperBlock.Root(); } + + uint16 InodeSize() { return fSuperBlock.InodeSize(); } + + xfs_agnumber_t AgCount() { return fSuperBlock.AgCount(); } + + xfs_agblock_t AgBlocks() { return fSuperBlock.AgBlocks(); } #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: @@ -54,7 +78,7 @@ protected: int fDevice; XfsSuperBlock fSuperBlock; char fName[32]; /* filesystem name */ - + uint32 fDeviceBlockSize; mutex fLock; diff --git a/src/add-ons/kernel/file_systems/xfs/system_dependencies.h b/src/add-ons/kernel/file_systems/xfs/system_dependencies.h index a42dc02a51..e0257cf90c 100644 --- a/src/add-ons/kernel/file_systems/xfs/system_dependencies.h +++ b/src/add-ons/kernel/file_systems/xfs/system_dependencies.h @@ -51,6 +51,7 @@ extern "C" #include #include #include +#include #endif // !FS_SHELL #endif // _SYSTEM_DEPENDENCIES diff --git a/src/add-ons/kernel/file_systems/xfs/xfs.cpp b/src/add-ons/kernel/file_systems/xfs/xfs.cpp index 886d476394..763d66fb37 100644 --- a/src/add-ons/kernel/file_systems/xfs/xfs.cpp +++ b/src/add-ons/kernel/file_systems/xfs/xfs.cpp @@ -1,7 +1,7 @@ /* - * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com - * All rights reserved. Distributed under the terms of the MIT License. - */ +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* All rights reserved. Distributed under the terms of the MIT License. +*/ #include "xfs.h" @@ -9,13 +9,14 @@ bool XfsSuperBlock::IsValid() { - if (sb_magicnum != XFS_SB_MAGIC) return false; + if (sb_magicnum != XFS_SB_MAGIC) + return false; - if (BBLOCKSIZE > sb_blocksize){ + if (BBLOCKSIZE > sb_blocksize) { ERROR("Basic block is less than 512 bytes!"); return false; } - + return true; } @@ -27,6 +28,41 @@ XfsSuperBlock::BlockSize() } +uint8 +XfsSuperBlock::BlockLog() +{ + return sb_blocklog; +} + + +uint32 +XfsSuperBlock::DirBlockSize() +{ + return BlockSize() * (1 << sb_dirblklog); +} + + +uint8 +XfsSuperBlock::AgInodeBits() +{ + return AgBlocksLog() + InodesPerBlkLog(); +} + + +uint8 +XfsSuperBlock::InodesPerBlkLog() +{ + return sb_inopblog; +} + + +uint8 +XfsSuperBlock::AgBlocksLog() +{ + return sb_agblklog; +} + + uint32 XfsSuperBlock::Size() { @@ -34,6 +70,13 @@ XfsSuperBlock::Size() } +uint16 +XfsSuperBlock::InodeSize() +{ + return sb_inodesize; +} + + xfs_rfsblock_t XfsSuperBlock::TotalBlocks() { @@ -69,6 +112,27 @@ XfsSuperBlock::Name() } +xfs_ino_t +XfsSuperBlock::Root() const +{ + return sb_rootino; +} + + +xfs_agnumber_t +XfsSuperBlock::AgCount() +{ + return sb_agcount; +} + + +xfs_agblock_t +XfsSuperBlock::AgBlocks() +{ + return sb_agblocks; +} + + void XfsSuperBlock::SwapEndian() { diff --git a/src/add-ons/kernel/file_systems/xfs/xfs.h b/src/add-ons/kernel/file_systems/xfs/xfs.h index 40e3d9b503..b7d5ed4d30 100644 --- a/src/add-ons/kernel/file_systems/xfs/xfs.h +++ b/src/add-ons/kernel/file_systems/xfs/xfs.h @@ -1,12 +1,14 @@ /* - * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com - * All rights reserved. Distributed under the terms of the MIT License. - */ +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* All rights reserved. Distributed under the terms of the MIT License. +*/ /* -Important: -All fields in XFS metadata structures are in big-endian byte order -except for log items which are formatted in host order. +*Important: +*All fields in XFS metadata structures are in big-endian byte order +*except for log items which are formatted in host order. +* +*This file contains all global structure definitions. */ #ifndef _XFS_SB_H_ @@ -15,10 +17,15 @@ except for log items which are formatted in host order. #include "system_dependencies.h" #include "xfs_types.h" + +extern fs_vnode_ops gxfsVnodeOps; +extern fs_volume_ops gxfsVolumeOps; + + #define XFS_SB_MAGIC 0x58465342 /* Identifies XFS. "XFSB" */ #define XFS_SB_MAXSIZE 512 #define BBLOCKLOG 9 /* Log of block size should be 9 */ -#define BBLOCKSIZE 1<=4 then the following features are - checked. If it's equal to 5, it's version 5. +/* +*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 @@ -104,6 +121,7 @@ private: #define XFS_SB_VERSION_DIRV2BIT 0x2000 #define XFS_SB_VERSION_MOREBITSBIT 0x4000 + /* Superblock quota flags - sb_qflags */ @@ -119,65 +137,24 @@ Superblock quota flags - sb_qflags #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_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 - -/* AG Free Space Block */ - -/* -index 0 for free space B+Tree indexed by block number -index 1 for free space B+Tree indexed by extent size - -Version 5 has XFS_BT_NUM_AGF defined as 3. This is because the index 2 is -for reverse-mapped B+Trees. I have spare0/1 defined here instead. -*/ - -#define XFS_BTNUM_AGF 2 -#define XFS_AG_MAGICNUM 0x58414746 -class AGFreeSpace{ - public: - //TODO: - void SwapEndian(); - private: - uint32 magicnum; - uint32 versionnum; // should be set to 1 - uint32 seqno; // defines the ag number for the sector - uint32 length; // size of ag in fs blocks - uint32 roots[XFS_BTNUM_AGF]; // roots of trees - uint32 spare0; //spare - uint32 levels[XFS_BTNUM_AGF]; // tree levels - uint32 spare1; //spare - uint32 flfirst; // index to first free list block - uint32 fllast; // index to last free list block - uint32 flcount; // number of blocks in freelist - uint32 freeblks; // current num of free blocks in AG - uint32 longest; // no.of blocks of longest - // contiguous free space in the AG - - /*number of blocks used for the free space B+trees. - This is only used if the XFS_SB_VERSION2_LAZYSBCOUNTBIT - bit is set in sb_features2 - */ - - uint32 btreeblks; -}; - - #endif diff --git a/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile b/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile index 41caf14c65..64b6177aca 100644 --- a/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile +++ b/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile @@ -39,10 +39,10 @@ UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ; local xfsSource = - DeviceOpener.cpp - xfs.cpp - Volume.cpp + Inode.cpp kernel_interface.cpp + Volume.cpp + xfs.cpp ; BuildPlatformMergeObject xfs_shell.o : $(xfsSource) ;