hrev54385 adds 1 changeset to branch 'master'
old head: 66f0993a1b418ee02d0236f45f58233d9b9814ed
new head: 7e1b5cf8099ce814ddf190e119d83496abaf8c72
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=7e1b5cf8099c+%5E66f0993a1b41
----------------------------------------------------------------------------
7e1b5cf8099c: xfs: An attempt at reading shortform dir
This patch gets read_dir, lookup and few others to work. Entries cannot
be listed yet except the root.
Change-Id: Ic4b7b61a794a1b75849e45777a383b3315b15aa8
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2915
Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
[ CruxBox <shubhambhagat111@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54385
Commit: 7e1b5cf8099ce814ddf190e119d83496abaf8c72
URL: https://git.haiku-os.org/haiku/commit/?id=7e1b5cf8099c
Author: CruxBox <shubhambhagat111@xxxxxxxxx>
Date: Sat Jun 13 20:12:13 2020 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Fri Jul 3 08:13:27 2020 UTC
----------------------------------------------------------------------------
16 files changed, 781 insertions(+), 335 deletions(-)
.../kernel/file_systems/xfs/BPlusTree.cpp | 7 +-
src/add-ons/kernel/file_systems/xfs/BPlusTree.h | 39 ++-
src/add-ons/kernel/file_systems/xfs/Debug.h | 2 +-
.../kernel/file_systems/xfs/Directory.cpp | 99 +++++++
src/add-ons/kernel/file_systems/xfs/Directory.h | 35 +++
src/add-ons/kernel/file_systems/xfs/Inode.cpp | 88 +++---
src/add-ons/kernel/file_systems/xfs/Inode.h | 275 ++++++++++---------
src/add-ons/kernel/file_systems/xfs/Jamfile | 3 +
.../kernel/file_systems/xfs/ShortDirectory.cpp | 84 ++++++
.../kernel/file_systems/xfs/ShortDirectory.h | 78 ++++++
src/add-ons/kernel/file_systems/xfs/Volume.cpp | 26 +-
src/add-ons/kernel/file_systems/xfs/Volume.h | 52 ++--
.../kernel/file_systems/xfs/kernel_interface.cpp | 121 ++++++--
src/add-ons/kernel/file_systems/xfs/xfs.cpp | 43 +--
src/add-ons/kernel/file_systems/xfs/xfs.h | 161 +++++------
.../kernel/file_systems/xfs/xfs_shell/Jamfile | 3 +
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp
b/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp
index 07432a11d8..b14f869cc3 100644
--- a/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/BPlusTree.cpp
@@ -1,7 +1,8 @@
/*
-* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
-* All rights reserved. Distributed under the terms of the MIT License.
-*/
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
#include "BPlusTree.h"
diff --git a/src/add-ons/kernel/file_systems/xfs/BPlusTree.h
b/src/add-ons/kernel/file_systems/xfs/BPlusTree.h
index 7156e7a2bb..371a4f4411 100644
--- a/src/add-ons/kernel/file_systems/xfs/BPlusTree.h
+++ b/src/add-ons/kernel/file_systems/xfs/BPlusTree.h
@@ -1,30 +1,28 @@
/*
-* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
-* All rights reserved. Distributed under the terms of the MIT License.
-*/
-
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
#ifndef _BPLUS_TREE_H_
#define _BPLUS_TREE_H_
#include "system_dependencies.h"
-/* Allocation B+ Tree Format */
-#define XFS_ABTB_MAGICNUM 0x41425442 // For block offset B+Tree
-#define XFS_ABTC_MAGICNUM 0x41425443 // For block count B+ Tree
-
-/* Header for Short Format btree */
+/* Allocation B+ Tree Format */
+#define XFS_ABTB_MAGICNUM 0x41425442
+ // For block offset B+Tree
+#define XFS_ABTC_MAGICNUM 0x41425443
+ // For block count B+ Tree
#define XFS_BTREE_SBLOCK_SIZE 18
-
-/* Header for Long Format btree */
+ // Header for Short Format btree
#define XFS_BTREE_LBLOCK_SIZE 24
+ // Header for Long Format btree
/*
-* Headers are the "nodes" really and are called "blocks". The records, keys and
-* pts are calculated using helpers
-*/
-
+ * Headers are the "nodes" really and are called "blocks". The records, keys
+ * and ptrs are calculated using helpers
+ */
struct bplustree_short_block {
void SwapEndian();
@@ -93,11 +91,11 @@ typedef struct xfs_alloc_rec {
} xfs_alloc_rec_t, xfs_alloc_key_t;
-// Swap Endians while returning itself
-typedef uint32 xfs_alloc_ptr_t; // Node pointers, AG relative block
pointer
-#define ALLOC_FLAG 0x1
+typedef uint32 xfs_alloc_ptr_t;
+ // Node pointers, AG relative block pointer
+#define ALLOC_FLAG 0x1
#define LONG_BLOCK_FLAG 0x1
#define SHORT_BLOCK_FLAG 0x2
@@ -118,7 +116,7 @@ union btree_rec {
class BPlusTree {
- public:
+public:
uint32 BlockSize();
int RecordSize();
int MaxRecords(bool
leaf);
@@ -129,7 +127,7 @@ class BPlusTree {
int KeyOffset(int
pos); // get the pos'th key
int PtrOffset(int
pos); // get the pos'th ptr
- private:
+private:
Volume* fVolume;
xfs_agnumber_t fAgnumber;
btree_ptr* fRoot;
@@ -140,4 +138,3 @@ class BPlusTree {
#endif
-
diff --git a/src/add-ons/kernel/file_systems/xfs/Debug.h
b/src/add-ons/kernel/file_systems/xfs/Debug.h
index 6ab16012bc..bc41c80b0e 100644
--- a/src/add-ons/kernel/file_systems/xfs/Debug.h
+++ b/src/add-ons/kernel/file_systems/xfs/Debug.h
@@ -5,7 +5,7 @@
#ifndef _DEBUG_H_
#define _DEBUG_H_
-#define TRACE_XFS
+// #define TRACE_XFS
#ifdef TRACE_XFS
#define TRACE(x...) dprintf("\n\33[34mxfs:\33[0m " x)
#else
diff --git a/src/add-ons/kernel/file_systems/xfs/Directory.cpp
b/src/add-ons/kernel/file_systems/xfs/Directory.cpp
new file mode 100644
index 0000000000..3b8c06ef3c
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Directory.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "Directory.h"
+
+
+DirectoryIterator::DirectoryIterator(Inode* inode)
+{
+ fInode = inode;
+ fShortDir = NULL;
+}
+
+
+DirectoryIterator::~DirectoryIterator()
+{
+ delete fShortDir;
+}
+
+
+status_t
+DirectoryIterator::Init()
+{
+ if (fInode->Format() == XFS_DINODE_FMT_LOCAL)
+ {
+ fShortDir = new(std::nothrow) ShortDirectory(fInode);
+ if (fShortDir == NULL)
+ return B_NO_MEMORY;
+ return B_OK;
+ }
+
+ /* Return B_OK so even if the shortform directory has an extent
directory
+ * we can atleast still list the shortform directory
+ */
+
+ //TODO: Reading from extent based directories
+ if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
+ TRACE("Iterator:GetNext: EXTENTS");
+ return B_OK;
+ }
+
+ //TODO: Reading from B+Trees based directories
+ if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
+ TRACE("Iterator:GetNext: B+TREE");
+ return B_OK;
+ }
+
+ return B_BAD_VALUE;
+}
+
+status_t
+DirectoryIterator::GetNext(char* name, size_t* length, xfs_ino_t* ino)
+{
+ if (fInode->Format() == XFS_DINODE_FMT_LOCAL) {
+ status_t status = fShortDir->GetNext(name, length, ino);
+ return status;
+ }
+
+ //TODO: Reading from extent based directories
+ if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
+ TRACE("Iterator:GetNext: EXTENTS");
+ return B_NOT_SUPPORTED;
+ }
+
+ //TODO: Reading from B+Trees based directories
+ if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
+ TRACE("Iterator:GetNext: B+TREE");
+ return B_NOT_SUPPORTED;
+ }
+
+ // Only reaches here if Inode is a device or is corrupt.
+ return B_BAD_VALUE;
+}
+
+
+status_t
+DirectoryIterator::Lookup(const char* name, size_t length, xfs_ino_t* ino)
+{
+ if (fInode->Format() == XFS_DINODE_FMT_LOCAL) {
+ status_t status = fShortDir->Lookup(name, length, ino);
+ return status;
+ }
+
+ //TODO: Reading from extent based dirs
+ if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
+ TRACE("Iterator:Lookup: EXTENTS");
+ return B_NOT_SUPPORTED;
+ }
+
+ //TODO: Reading from B+Tree based dirs
+ if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
+ TRACE("Iterator:Lookup: B+TREE");
+ return B_NOT_SUPPORTED;
+ }
+
+ return B_BAD_VALUE;
+}
diff --git a/src/add-ons/kernel/file_systems/xfs/Directory.h
b/src/add-ons/kernel/file_systems/xfs/Directory.h
new file mode 100644
index 0000000000..fd0e3bec6b
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Directory.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef _DIRECTORY_H_
+#define _DIRECTORY_H_
+
+
+#include "Inode.h"
+#include "ShortDirectory.h"
+
+
+/*
+ * This class should act as a layer between any kind of directory
+ * and the kernel interface
+ */
+class DirectoryIterator {
+public:
+
DirectoryIterator(Inode* inode);
+
~DirectoryIterator();
+ status_t Init();
+ bool IsLocalDir() { return
fInode->IsLocal(); }
+ status_t GetNext(char* name,
size_t* length,
+
xfs_ino_t* ino);
+ status_t Lookup(const char*
name, size_t length,
+
xfs_ino_t* id);
+
+private:
+ Inode* fInode;
+ ShortDirectory* fShortDir;
+ // Short form Directory type
+};
+
+
+#endif
diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.cpp
b/src/add-ons/kernel/file_systems/xfs/Inode.cpp
index 61823765fd..98a40ceb29 100644
--- a/src/add-ons/kernel/file_systems/xfs/Inode.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/Inode.cpp
@@ -1,13 +1,14 @@
/*
-* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
-* All rights reserved. Distributed under the terms of the MIT License.
-*/
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
#include "Inode.h"
void
-xfs_inode::SwapEndian()
+xfs_inode_t::SwapEndian()
{
di_magic = B_BENDIAN_TO_HOST_INT16(di_magic);
di_mode = B_BENDIAN_TO_HOST_INT16(di_mode);
@@ -37,42 +38,42 @@ xfs_inode::SwapEndian()
xfs_rfsblock_t
-xfs_inode::NoOfBlocks() const
+xfs_inode_t::NoOfBlocks() const
{
return di_nblocks;
}
xfs_fsize_t
-xfs_inode::Size() const
+xfs_inode_t::Size() const
{
return di_size;
}
mode_t
-xfs_inode::Mode()
+xfs_inode_t::Mode() const
{
return di_mode;
}
uint32
-xfs_inode::UserId()
+xfs_inode_t::UserId() const
{
return di_uid;
}
uint32
-xfs_inode::GroupId()
+xfs_inode_t::GroupId() const
{
return di_gid;
}
void
-xfs_inode::GetModificationTime(struct timespec& stamp)
+xfs_inode_t::GetModificationTime(struct timespec& stamp)
{
stamp.tv_sec = di_mtime.t_sec;
stamp.tv_nsec = di_mtime.t_nsec;
@@ -80,7 +81,7 @@ xfs_inode::GetModificationTime(struct timespec& stamp)
void
-xfs_inode::GetAccessTime(struct timespec& stamp)
+xfs_inode_t::GetAccessTime(struct timespec& stamp)
{
stamp.tv_sec = di_atime.t_sec;
stamp.tv_nsec = di_atime.t_nsec;
@@ -88,7 +89,7 @@ xfs_inode::GetAccessTime(struct timespec& stamp)
void
-xfs_inode::GetChangeTime(struct timespec& stamp)
+xfs_inode_t::GetChangeTime(struct timespec& stamp)
{
stamp.tv_sec = di_ctime.t_sec;
stamp.tv_nsec = di_ctime.t_nsec;
@@ -96,51 +97,66 @@ xfs_inode::GetChangeTime(struct timespec& stamp)
uint32
-xfs_inode::NLink()
+xfs_inode_t::NLink() const
{
return di_nlink;
}
int8
-xfs_inode::Version()
+xfs_inode_t::Version() const
{
return di_version;
}
uint16
-xfs_inode::Flags()
+xfs_inode_t::Flags() const
{
return di_flags;
}
int8
-xfs_inode::Format()
+xfs_inode_t::Format() const
{
return di_format;
}
Inode::Inode(Volume* volume, xfs_ino_t id)
+ :
+ fVolume(volume),
+ fId(id)
+{
+
+}
+
+
+status_t
+Inode::Init()
{
- fVolume = volume;
- fId = id;
fNode = new(std::nothrow) xfs_inode_t;
+ if (fNode == NULL)
+ return B_NO_MEMORY;
- uint16 inodeSize = volume->InodeSize();
+ uint16 inodeSize = fVolume->InodeSize();
fBuffer = new(std::nothrow) char[inodeSize];
+ if (fBuffer == NULL)
+ return B_NO_MEMORY;
status_t status = GetFromDisk();
if (status == B_OK) {
- status = InitCheck();
- if (status) {
- TRACE("Inode successfully read!");
+ if (fNode->di_magic == INODE_MAGIC) {
+ TRACE("Init(): Inode successfully read.\n");
+ status = B_OK;
} else {
- TRACE("Inode wasn't read successfully!");
+ TRACE("Init(): Inode wasn't read successfully!\n");
+ status = B_BAD_VALUE;
}
}
+
+ return status;
}
@@ -149,29 +165,28 @@ 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());
+ uint32 agRelativeInodeNo = INO_TO_AGINO(fId, fVolume->AgInodeBits());
// AG relative ino #
- xfs_agblock_t agBlock = INO_TO_AGBLOCK(agInodeNo, fVolume);
+ xfs_agblock_t agBlock = INO_TO_AGBLOCK(agRelativeInodeNo, fVolume);
// AG relative block number
- xfs_off_t offset = INO_TO_OFFSET(fId, fVolume);
- // Offset into the block
+ xfs_off_t offset = INO_TO_BLOCKOFFSET(fId, fVolume);
+ // Offset into the block1
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_agblock_t numberOfBlocksInAg = fVolume->AgBlocks();
- xfs_fsblock_t blockToRead =
- FSB_TO_BB(fVolume->BlockLog(), ((uint64)(agNo * agBlocks) +
agBlock));
+ xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(fVolume->BlockLog(),
+ ((uint64)(agNo * numberOfBlocksInAg) + agBlock));
- xfs_daddr_t readPos = blockToRead*(BBLOCKSIZE) + offset;
+ xfs_daddr_t readPos = blockToRead*(BASICBLOCKSIZE) + offset;
- if (read_pos(fd, readPos, fBuffer, len) != len) {
+ if (read_pos(fVolume->Device(), readPos, fBuffer, len) != len) {
ERROR("Inode::Inode(): IO Error");
return B_IO_ERROR;
}
@@ -183,13 +198,6 @@ Inode::GetFromDisk()
}
-bool
-Inode::InitCheck()
-{
- return fNode->di_magic == INODE_MAGIC;
-}
-
-
Inode::~Inode()
{
delete fBuffer;
diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.h
b/src/add-ons/kernel/file_systems/xfs/Inode.h
index 5241c291ea..2d794f94c2 100644
--- a/src/add-ons/kernel/file_systems/xfs/Inode.h
+++ b/src/add-ons/kernel/file_systems/xfs/Inode.h
@@ -1,22 +1,23 @@
/*
-* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
-* All rights reserved. Distributed under the terms of the MIT License.
-*/
-
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * 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 INODE_MINSIZE_LOG 8
+#define INODE_MAXSIZE_LOG 11
+#define INODE_CORE_SIZE 96
+#define INODE_CORE_UNLINKED_SIZE 100
+ // Inode core but with unlinked pointer
#define DATA_FORK_OFFSET 0x64
-
+ // For v4 FS
#define INO_MASK(x) ((1ULL << (x)) - 1)
// Gets 2^x - 1
#define INO_TO_AGNO(id, volume) (xfs_agnumber_t)id >>
(volume->AgInodeBits())
@@ -27,132 +28,156 @@
(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()))
+#define INO_TO_BLOCKOFFSET(id, volume) (id &
INO_MASK(volume->InodesPerBlkLog()))
// Gets the offset into the block from the inode number
+#define DIR_DFORK_PTR(dir_ino_ptr) (char*) dir_ino_ptr + DATA_FORK_OFFSET
+#define DIR_AFORK_PTR(dir_ino_ptr) \
+ (XFS_DFORK_PTR + \
+ ((uint32)dir_ino_ptr->di_forkoff<<3))
+#define DIR_AFORK_EXIST(dir_ino_ptr) dir_ino_ptr->di_forkoff!=0
-typedef struct xfs_timestamp
-{
+struct xfs_timestamp_t {
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;
+enum xfs_dinode_fmt_t {
+ 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
+};
/*
- 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();
- int8 Version(); //TODO
- mode_t Mode();
- void GetModificationTime(struct
timespec& timestamp);
- void GetChangeTime(struct timespec&
timestamp);
- void GetAccessTime(struct timespec&
timestamp);
- int8 Format(); // The
format of the inode
- xfs_fsize_t Size() const; // TODO
- xfs_rfsblock_t NoOfBlocks() const;
- uint32 NLink();
- uint16 Flags();
- uint32 UserId();
- uint32 GroupId();
-
- 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();
-
- xfs_ino_t ID() const { return fId; }
-
- 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; }
-
- uint32 NLink() { return fNode->NLink(); }
-
- int8 Version() { return fNode->Version(); }
-
- xfs_fsize_t Size() const { return fNode->Size(); }
-
- xfs_rfsblock_t NoOfBlocks() const { return
fNode->NoOfBlocks(); }
-
- int16 Flags() const { return fNode->Flags(); }
-
- void GetChangeTime(struct timespec& timestamp) const
- { fNode->GetChangeTime(timestamp); }
-
- void GetModificationTime(struct timespec& timestamp)
const
- {
fNode->GetModificationTime(timestamp); }
-
- void GetAccessTime(struct timespec& timestamp) const
- { fNode->GetAccessTime(timestamp); }
-
- private:
- uint32 UserId() { return fNode->UserId(); }
- uint32 GroupId() { return fNode->GroupId(); }
-
- status_t GetFromDisk();
- xfs_inode_t* fNode;
- xfs_ino_t fId;
- Volume* fVolume;
- char* fBuffer; // Contains the
disk inode in BE format
+ * 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.
+ */
+struct xfs_inode_t {
+ void SwapEndian();
+ int8 Version() const;
+ //TODO: Check
+ mode_t Mode() const;
+ void
GetModificationTime(struct timespec&
+
timestamp);
+ void GetChangeTime(struct
timespec& timestamp);
+ void GetAccessTime(struct
timespec& timestamp);
+ int8 Format() const;
+ // The format of the inode
+ xfs_fsize_t Size() const;
+ xfs_rfsblock_t NoOfBlocks() const;
+ uint32 NLink() const;
+ uint16 Flags() const;
+ uint32 UserId() const;
+ uint32 GroupId() const;
+
+ uint16 di_magic;
+ uint16 di_mode;
+ // uses standard S_Ixxx
+ int8 di_version;
+ //This either would be 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;
+};
+
+
+class Inode {
+public:
+ Inode(Volume*
volume, xfs_ino_t id);
+ ~Inode();
+ status_t Init();
+
+ xfs_ino_t ID() const { return
fId; }
+
+ 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() const { return
fNode->Format(); }
+
+ bool IsLocal() const
+ { return
+
Format() == XFS_DINODE_FMT_LOCAL; }
+
+ uint32 NLink() const { return
fNode->NLink(); }
+
+ int8 Version() const {
return fNode->Version(); }
+
+ xfs_rfsblock_t NoOfBlocks() const
+ {
return fNode->NoOfBlocks(); }
+
+ char* Buffer() { return
fBuffer; }
+
+ int16 Flags() const { return
fNode->Flags(); }
+
+ xfs_fsize_t Size() const { return
fNode->Size(); }
+
+ void GetChangeTime(struct
timespec& timestamp) const
+ {
fNode->GetChangeTime(timestamp); }
+
+ void
GetModificationTime(struct timespec& timestamp)
+ const
+ {
fNode->GetModificationTime(timestamp); }
+
+ void GetAccessTime(struct
timespec& timestamp) const
+ {
fNode->GetAccessTime(timestamp); }
+
+ uint32 UserId() const { return
fNode->UserId(); }
+ uint32 GroupId() const {
return fNode->GroupId(); }
+
+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 1a6803e53e..0509ce2e83 100644
--- a/src/add-ons/kernel/file_systems/xfs/Jamfile
+++ b/src/add-ons/kernel/file_systems/xfs/Jamfile
@@ -20,9 +20,12 @@ DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
local xfsSources =
+ DeviceOpener.cpp
+ Directory.cpp
Inode.cpp
kernel_cpp.cpp
kernel_interface.cpp
+ ShortDirectory.cpp
Volume.cpp
xfs.cpp
;
diff --git a/src/add-ons/kernel/file_systems/xfs/ShortDirectory.cpp
b/src/add-ons/kernel/file_systems/xfs/ShortDirectory.cpp
new file mode 100644
index 0000000000..b9e37ea9fc
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/ShortDirectory.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "ShortDirectory.h"
+
+
+ShortDirectory::ShortDirectory(Inode* inode)
+ :
+ fInode(inode),
+ fTrack(0)
+{
+ memcpy(&fHeader,
+ DIR_DFORK_PTR(fInode->Buffer()), sizeof(xfs_dir2_sf_hdr_t));
+}
+
+
+ShortDirectory::~ShortDirectory()
+{
+}
+
+
+xfs_ino_t
+ShortDirectory::GetParentIno()
+{
+ TRACE("GetParentIno: \n");
+ if (fHeader.i8count > 0)
+ return B_BENDIAN_TO_HOST_INT64(fHeader.parent.i8);
+ else
+ return B_BENDIAN_TO_HOST_INT32(fHeader.parent.i4);
+}
+
+
+status_t
+ShortDirectory::Lookup(const char* name, size_t length, xfs_ino_t* ino)
+{
+ if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+ xfs_ino_t rootIno = fInode->GetVolume()->Root();
+ if (strcmp(name, ".") == 0 || (rootIno == fInode->ID())) {
+ *ino = fInode->ID();
+ TRACE("ShortDirectory:Lookup: name: \".\" ino: (%d)\n",
*ino);
+ return B_OK;
+ }
+ *ino = GetParentIno();
+ TRACE("Parent: (%d)\n", *ino);
+ return B_OK;
+ }
+
+ //TODO: Other entries
+ return B_NOT_SUPPORTED;
+}
+
+
+status_t
+ShortDirectory::GetNext(char* name, size_t* length, xfs_ino_t* ino)
+{
+ if (fTrack == 0) {
+ // Return '.'
+ if (*length < 2)
+ return B_BUFFER_OVERFLOW;
+ *length = 2;
+ strlcpy(name, ".", *length + 1);
+ *ino = fInode->ID();
+ fTrack = 1;
+ TRACE("ShortDirectory:GetNext: name: \".\" ino: (%d)\n", *ino);
+ return B_OK;
+ }
+ if (fTrack == 1) {
+ // Return '..'
+ if (*length < 3)
+ return B_BUFFER_OVERFLOW;
+ *length = 3;
+ strlcpy(name, "..", *length + 1);
+ *ino = GetParentIno();
+ fTrack = 2;
+ TRACE("ShortDirectory:GetNext: name: \"..\" ino: (%d)\n", *ino);
+ return B_OK;
+ }
+
+ // TODO: Now iterate through sf entries
+ return B_NOT_SUPPORTED;
+}
diff --git a/src/add-ons/kernel/file_systems/xfs/ShortDirectory.h
b/src/add-ons/kernel/file_systems/xfs/ShortDirectory.h
new file mode 100644
index 0000000000..b17f6ed8d6
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/ShortDirectory.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef __SHORT_DIR_H__
+#define __SHORT_DIR_H__
+
+#include "Inode.h"
+
+
+struct xfs_dir2_sf_off_t { uint8 i[2]; };
+ //offset into the literal area
+
+union xfs_dir2_inou_t {
+ uint64 i8;
+ uint32 i4;
+};
+
+
+// Short form directory header
+struct xfs_dir2_sf_hdr_t {
+ uint8 count;
+ // number of entries
+ uint8 i8count;
+ // # of 64bit inode entries
+ xfs_dir2_inou_t parent;
+ // absolute inode # of parent
+};
+
+
+/*
+ *The xfs_dir2_sf_entry is split into
+ * two parts because the entries size is variable
+ */
+struct xfs_dir2_sf_entry_t {
+ uint8 namelen;
+ // length of the name, in bytes
+ xfs_dir2_sf_off_t offset;
+ // offset tag, for directory iteration
+ uint8 name[];
+ // name of directory entry
+};
+
+
+union xfs_dir2_sf_entry_inum_t {
+ struct xfs_ftype_inum{
+ uint8 ftype;
+ xfs_dir2_inou_t inumber;
+ };
+ struct xfs_inum{
+ xfs_dir2_inou_t inumber;
+ };
+};
+
+
+class ShortDirectory
+{
+public:
+
ShortDirectory(Inode* inode);
+
~ShortDirectory();
+ status_t GetNext(char* name,
size_t* length,
+
xfs_ino_t* ino);
+ xfs_ino_t GetParentIno();
+ status_t Lookup(const char*
name, size_t length,
+
xfs_ino_t* id);
+
+private:
+ Inode* fInode;
+ xfs_dir2_sf_hdr_t fHeader;
+ xfs_dir2_sf_off_t fLastEntryOffset;
+ // offset into the literal area
+ uint8 fTrack;
+ // Takes the values 0, 1 or 2 only
+
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/add-ons/kernel/file_systems/xfs/Volume.cpp
b/src/add-ons/kernel/file_systems/xfs/Volume.cpp
index aa6d14ce00..e63bd5164f 100644
--- a/src/add-ons/kernel/file_systems/xfs/Volume.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/Volume.cpp
@@ -3,12 +3,15 @@
* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
* All rights reserved. Distributed under the terms of the MIT License.
*/
+
+
#include "Volume.h"
-#include "DeviceOpener.h"
+
+#include "Inode.h"
Volume::Volume(fs_volume *volume)
- : fFSVolume(volume)
+ : fFSVolume(volume)
{
fFlags = 0;
mutex_init(&fLock, "xfs volume");
@@ -24,7 +27,7 @@ Volume::~Volume()
bool
-Volume::IsValidSuperBlock()
+Volume::IsValidSuperBlock() const
{
return fSuperBlock.IsValid();
}
@@ -65,7 +68,7 @@ Volume::Mount(const char *deviceName, uint32 flags)
DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0
? O_RDONLY
-
: O_RDWR);
+
: O_RDWR);
fDevice = opener.Device();
if (fDevice < B_OK) {
ERROR("Volume::Mount(): couldn't open device\n");
@@ -92,6 +95,21 @@ Volume::Mount(const char *deviceName, uint32 flags)
}
opener.Keep();
+
+ //publish the root inode
+ Inode* rootInode = new(std::nothrow) Inode(this, Root());
+ if (rootInode == NULL)
+ return B_NO_MEMORY;
+
+ status = rootInode->Init();
+ if (status != B_OK)
+ return status;
+
+ status = publish_vnode(FSVolume(), Root(),
+ (void*)rootInode, &gxfsVnodeOps, rootInode->Mode(), 0);
+ if (status != B_OK)
+ return B_BAD_VALUE;
+
return B_OK;
}
diff --git a/src/add-ons/kernel/file_systems/xfs/Volume.h
b/src/add-ons/kernel/file_systems/xfs/Volume.h
index 1a9be65efe..bd69abfdec 100644
--- a/src/add-ons/kernel/file_systems/xfs/Volume.h
+++ b/src/add-ons/kernel/file_systems/xfs/Volume.h
@@ -1,17 +1,19 @@
/*
-* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
-* All rights reserved. Distributed under the terms of the MIT License.
-*/
-
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
#ifndef _VOLUME_H_
#define _VOLUME_H_
+
+#include <DeviceOpener.h>
+
#include "xfs.h"
-/* Converting the FS Blocks to Basic Blocks */
-#define FSBSHIFT(fsBlockLog) (fsBlockLog - BBLOCKLOG);
-#define FSB_TO_BB(fsBlockLog, x) x << FSBSHIFT(fsBlockLog);
+#define FSBLOCK_SHIFT(fsBlockLog) (fsBlockLog - BASICBLOCKLOG);
+#define FSBLOCKS_TO_BASICBLOCKS(fsBlockLog, x) x << FSBLOCK_SHIFT(fsBlockLog);
+ // Converting the FS Blocks to Basic Blocks
enum volume_flags {
VOLUME_READ_ONLY = 0x0001
@@ -28,15 +30,16 @@ public:
status_t Initialize(int fd,
const char *label,
uint32
blockSize, uint32 sectorSize);
- bool IsValidSuperBlock();
+ bool IsValidSuperBlock()
const;
bool IsReadOnly() const
- {
return (fFlags & VOLUME_READ_ONLY) != 0; }
+ { return
+
(fFlags & VOLUME_READ_ONLY) != 0; }
dev_t ID() const
{
return fFSVolume ? fFSVolume->id : -1; }
fs_volume* FSVolume() const
{
return fFSVolume; }
- char* Name()
+ const char* Name() const
{
return fSuperBlock.Name(); }
XfsSuperBlock& SuperBlock() { return
fSuperBlock; }
@@ -44,29 +47,37 @@ public:
static status_t Identify(int fd, XfsSuperBlock
*superBlock);
- uint32 BlockSize() { return
fSuperBlock.BlockSize(); }
+ uint32 BlockSize() const
+ {
return fSuperBlock.BlockSize(); }
- uint8 BlockLog() { return
fSuperBlock.BlockLog(); }
+ uint8 BlockLog() const
+ {
return fSuperBlock.BlockLog(); }
- uint32 DirBlockSize()
+ uint32 DirBlockSize() const
{
return fSuperBlock.DirBlockSize(); }
- uint8 AgInodeBits()
+ uint8 AgInodeBits() const
{
return fSuperBlock.AgInodeBits(); }
- uint8 AgBlocksLog()
+ uint8 AgBlocksLog() const
{
return fSuperBlock.AgBlocksLog(); }
- uint8 InodesPerBlkLog()
+ uint8 InodesPerBlkLog() const
{
return fSuperBlock.InodesPerBlkLog(); }
off_t Root() const { return
fSuperBlock.Root(); }
- uint16 InodeSize() { return
fSuperBlock.InodeSize(); }
+ uint16 InodeSize() const
+ {
return fSuperBlock.InodeSize(); }
+
+ xfs_agnumber_t AgCount() const
+ {
return fSuperBlock.AgCount(); }
- xfs_agnumber_t AgCount() { return
fSuperBlock.AgCount(); }
+ xfs_agblock_t AgBlocks() const
+ {
return fSuperBlock.AgBlocks(); }
- xfs_agblock_t AgBlocks() { return
fSuperBlock.AgBlocks(); }
+ uint8 SuperBlockFlags() const
+ {
return fSuperBlock.Flags(); }
#if 0
off_t NumBlocks() const
@@ -77,7 +88,8 @@ protected:
fs_volume* fFSVolume;
int fDevice;
XfsSuperBlock fSuperBlock;
- char fName[32]; /*
filesystem name */
+ char fName[32];
+ // Filesystem name
uint32 fDeviceBlockSize;
mutex fLock;
diff --git a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
index fef7c6f4da..309dd15fde 100644
--- a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
@@ -1,9 +1,12 @@
/*
-* Copyright 2001-2017, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
-* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
-* All rights reserved. Distributed under the terms of the MIT License.
-*/
+ * Copyright 2001-2017, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
#include "system_dependencies.h"
+#include "Directory.h"
#include "Inode.h"
#include "Volume.h"
@@ -86,16 +89,6 @@ xfs_mount(fs_volume *_volume, const char *device, uint32
flags,
return status;
}
- //publish the root inode
- Inode* rootInode = new(std::nothrow) Inode(volume, volume->Root());
- if (rootInode != NULL) {
- status = publish_vnode(volume->FSVolume(), volume->Root(),
- (void*)rootInode, &gxfsVnodeOps, rootInode->Mode(), 0);
-
- if (status!=B_OK)
- return B_BAD_VALUE;
- }
-
*_rootID = volume->Root();
return B_OK;
}
@@ -116,6 +109,7 @@ xfs_unmount(fs_volume *_volume)
static status_t
xfs_read_fs_info(fs_volume *_volume, struct fs_info *info)
{
+ TRACE("XFS_READ_FS_INFO:\n");
Volume* volume = (Volume*)_volume->private_volume;
info->flags = B_FS_IS_READONLY
@@ -140,15 +134,15 @@ static status_t
xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_node, int *_type,
uint32 *_flags, bool reenter)
{
+ TRACE("XFS_GET_VNODE:\n");
Volume* volume = (Volume*)_volume->private_volume;
Inode* inode = new(std::nothrow) Inode(volume, id);
-
if (inode == NULL)
return B_NO_MEMORY;
- status_t status = inode->InitCheck();
- if (status == false) {
+ status_t status = inode->Init();
+ if (status != B_OK) {
delete inode;
ERROR("get_vnode: InitCheck() failed. Error: %s\n",
strerror(status));
return B_NO_INIT;
@@ -158,7 +152,7 @@ xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode
*_node, int *_type,
_node->ops = &gxfsVnodeOps;
*_type = inode->Mode();
*_flags = 0;
-
+ TRACE("(%d)\n", inode->ID());
return B_OK;
}
@@ -166,7 +160,9 @@ xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode
*_node, int *_type,
static status_t
xfs_put_vnode(fs_volume *_volume, fs_vnode *_node, bool reenter)
{
- return B_NOT_SUPPORTED;
+ TRACE("XFS_PUT_VNODE:\n");
+ delete (Inode*)_node->private_node;
+ return B_OK;
}
@@ -208,7 +204,36 @@ static status_t
xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
ino_t *_vnodeID)
{
- return B_NOT_SUPPORTED;
+ TRACE("XFS_LOOKUP: %p (%s)\n", name, name);
+ Volume* volume = (Volume*)_volume->private_volume;
+ Inode* directory = (Inode*)_directory->private_node;
+
+ if (!directory->IsDirectory())
+ return B_NOT_A_DIRECTORY;
+
+ //TODO: pretend everything is accessible. We should actually checking
+ //for permission here.
+ DirectoryIterator* iterator =
+ new(std::nothrow) DirectoryIterator(directory);
+ if (iterator == NULL)
+ return B_NO_MEMORY;
+
+ status_t status = iterator->Init();
+ if (status != B_OK) {
+ delete iterator;
+ return status;
+ }
+
+ status = iterator->Lookup(name, strlen(name), (xfs_ino_t*)_vnodeID);
+ if (status != B_OK) {
+ delete iterator;
+ return status;
+ }
+
+ TRACE("XFS_LOOKUP: ID: (%d)\n", *_vnodeID);
+ status = get_vnode(volume->FSVolume(), *_vnodeID, NULL);
+ TRACE("get_vnode status: (%d)\n", status);
+ return status;
}
@@ -224,6 +249,7 @@ static status_t
xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
{
Inode* inode = (Inode*)_node->private_node;
+ TRACE("XFS_READ_STAT: root_id: (%d)\n", inode->ID());
stat->st_dev = inode->GetVolume()->ID();
stat->st_ino = inode->ID();
stat->st_nlink = 1;
@@ -234,7 +260,7 @@ xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct
stat *stat)
stat->st_mode = inode->Mode();
stat->st_type = 0; // TODO
- stat->st_size = inode->GetVolume()->InodeSize();
+ stat->st_size = inode->Size();
stat->st_blocks = inode->NoOfBlocks();
inode->GetAccessTime(stat->st_atim);
@@ -282,7 +308,9 @@ xfs_free_cookie(fs_volume *_volume, fs_vnode *_node, void
*_cookie)
static status_t
xfs_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
{
- return B_NOT_SUPPORTED;
+ //TODO: pretend everything is accessible. We should actually checking
+ //for permission here.
+ return B_OK;
}
@@ -322,7 +350,20 @@ xfs_remove_dir(fs_volume *_volume, fs_vnode *_directory,
const char *name)
static status_t
xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
{
- return B_NOT_SUPPORTED;
+ Inode* inode = (Inode*)_node->private_node;
+ TRACE("XFS_OPEN_DIR: (%d)\n", inode->ID());
+
+ if (!inode->IsDirectory())
+ return B_NOT_A_DIRECTORY;
+
+ DirectoryIterator* iterator = new(std::nothrow)
DirectoryIterator(inode);
+ if (iterator == NULL) {
+ delete iterator;
+ return B_NO_MEMORY;
+ }
+ status_t status = iterator->Init();
+ *_cookie = iterator;
+ return status;
}
@@ -330,7 +371,39 @@ static status_t
xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
struct dirent *dirent, size_t bufferSize, uint32 *_num)
{
- return B_NOT_SUPPORTED;
+ TRACE("XFS_READ_DIR\n");
+ DirectoryIterator* iterator = (DirectoryIterator*)_cookie;
+ Volume* volume = (Volume*)_volume->private_volume;
+
+ uint32 maxCount = *_num;
+ uint32 count = 0;
+
+ while (count < maxCount and (bufferSize > sizeof(struct dirent))) {
+ size_t length = bufferSize - sizeof(struct dirent) + 1;
+ xfs_ino_t ino;
+
+ status_t status = iterator->GetNext(dirent->d_name, &length,
&ino);
+ if (status == B_ENTRY_NOT_FOUND)
+ break;
+ if (status == B_BUFFER_OVERFLOW) {
+ if (count == 0)
+ return status;
+ break;
+ }
+ if (status != B_OK)
+ return status;
+
+ dirent->d_dev = volume->ID();
+ dirent->d_ino = ino;
+ dirent->d_reclen = sizeof(dirent) + length;
+ bufferSize -= dirent->d_reclen;
+ dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
+ count++;
+ }
+
+ *_num = count;
+ TRACE("Count: (%d)\n", count);
+ return B_OK;
}
diff --git a/src/add-ons/kernel/file_systems/xfs/xfs.cpp
b/src/add-ons/kernel/file_systems/xfs/xfs.cpp
index 763d66fb37..6200c182ef 100644
--- a/src/add-ons/kernel/file_systems/xfs/xfs.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/xfs.cpp
@@ -6,13 +6,20 @@
#include "xfs.h"
+uint8
+XfsSuperBlock::Flags() const
+{
+ return sb_flags;
+}
+
+
bool
-XfsSuperBlock::IsValid()
+XfsSuperBlock::IsValid() const
{
if (sb_magicnum != XFS_SB_MAGIC)
return false;
- if (BBLOCKSIZE > sb_blocksize) {
+ if (BASICBLOCKSIZE > sb_blocksize) {
ERROR("Basic block is less than 512 bytes!");
return false;
}
@@ -22,91 +29,91 @@ XfsSuperBlock::IsValid()
uint32
-XfsSuperBlock::BlockSize()
+XfsSuperBlock::BlockSize() const
{
return sb_blocksize;
}
uint8
-XfsSuperBlock::BlockLog()
+XfsSuperBlock::BlockLog() const
{
return sb_blocklog;
}
uint32
-XfsSuperBlock::DirBlockSize()
+XfsSuperBlock::DirBlockSize() const
{
return BlockSize() * (1 << sb_dirblklog);
}
uint8
-XfsSuperBlock::AgInodeBits()
+XfsSuperBlock::AgInodeBits() const
{
return AgBlocksLog() + InodesPerBlkLog();
}
uint8
-XfsSuperBlock::InodesPerBlkLog()
+XfsSuperBlock::InodesPerBlkLog() const
{
return sb_inopblog;
}
uint8
-XfsSuperBlock::AgBlocksLog()
+XfsSuperBlock::AgBlocksLog() const
{
return sb_agblklog;
}
uint32
-XfsSuperBlock::Size()
+XfsSuperBlock::Size() const
{
return XFS_SB_MAXSIZE;
}
uint16
-XfsSuperBlock::InodeSize()
+XfsSuperBlock::InodeSize() const
{
return sb_inodesize;
}
xfs_rfsblock_t
-XfsSuperBlock::TotalBlocks()
+XfsSuperBlock::TotalBlocks() const
{
return sb_dblocks;
}
xfs_rfsblock_t
-XfsSuperBlock::TotalBlocksWithLog()
+XfsSuperBlock::TotalBlocksWithLog() const
{
return TotalBlocks() + sb_logblocks;
}
uint64
-XfsSuperBlock::FreeBlocks()
+XfsSuperBlock::FreeBlocks() const
{
return sb_fdblocks;
}
uint64
-XfsSuperBlock::UsedBlocks()
+XfsSuperBlock::UsedBlocks() const
{
return TotalBlocks() - FreeBlocks();
}
-char*
-XfsSuperBlock::Name()
+const char*
+XfsSuperBlock::Name() const
{
return sb_fname;
}
@@ -120,14 +127,14 @@ XfsSuperBlock::Root() const
xfs_agnumber_t
-XfsSuperBlock::AgCount()
+XfsSuperBlock::AgCount() const
{
return sb_agcount;
}
xfs_agblock_t
-XfsSuperBlock::AgBlocks()
+XfsSuperBlock::AgBlocks() const
{
return sb_agblocks;
}
diff --git a/src/add-ons/kernel/file_systems/xfs/xfs.h
b/src/add-ons/kernel/file_systems/xfs/xfs.h
index b7d5ed4d30..135c63d30d 100644
--- a/src/add-ons/kernel/file_systems/xfs/xfs.h
+++ b/src/add-ons/kernel/file_systems/xfs/xfs.h
@@ -1,19 +1,19 @@
/*
-* Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
-* All rights reserved. Distributed under the terms of the MIT License.
-*/
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * 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.
-*
-*This file contains all global structure definitions.
-*/
-
+ *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_
#define _XFS_SB_H_
+
#include "system_dependencies.h"
#include "xfs_types.h"
@@ -22,83 +22,86 @@ extern fs_vnode_ops gxfsVnodeOps;
extern fs_volume_ops gxfsVolumeOps;
-#define XFS_SB_MAGIC 0x58465342 /* Identifies XFS. "XFSB" */
+#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 << BBLOCKLOG /* The size of a basic block
should be 512 */
+#define BASICBLOCKLOG 9
+ // Log of block size should be 9
+#define BASICBLOCKSIZE 1 << BASICBLOCKLOG
+ // The size of a basic block should be 512
/* Version 4 superblock definition */
-class XfsSuperBlock
-{
+class XfsSuperBlock {
public:
- bool IsValid();
- char* Name();
- uint32 BlockSize();
- uint8 BlockLog();
- uint32 DirBlockSize(); //
maximum 65536
- uint8 AgInodeBits();
- uint8 InodesPerBlkLog();
- uint8 AgBlocksLog();
- xfs_rfsblock_t TotalBlocks();
- xfs_rfsblock_t TotalBlocksWithLog();
- uint64 FreeBlocks();
- uint64 UsedBlocks();
- uint32 Size();
- uint16 InodeSize();
- void SwapEndian();
- xfs_ino_t Root() const;
- xfs_agnumber_t AgCount();
- xfs_agblock_t AgBlocks();
-
+ bool IsValid() const;
+ const char* Name() const;
+ uint32 BlockSize() const;
+ uint8 BlockLog() const;
+ uint32 DirBlockSize() const;
+ // maximum 65536
+ uint8 AgInodeBits() const;
+ uint8 InodesPerBlkLog() const;
+ uint8 AgBlocksLog() const;
+ xfs_rfsblock_t TotalBlocks() const;
+ xfs_rfsblock_t TotalBlocksWithLog() const;
+ uint64 FreeBlocks() const;
+ uint64 UsedBlocks() const;
+ uint32 Size() const;
+ uint16 InodeSize() const;
+ void SwapEndian();
+ xfs_ino_t Root() const;
+ xfs_agnumber_t AgCount() const;
+ xfs_agblock_t AgBlocks() const;
+ uint8 Flags() const;
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;
+ 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;
};
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 64b6177aca..c9fe209f6f 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,8 +39,11 @@ UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
local xfsSource =
+ DeviceOpener.cpp
+ Directory.cpp
Inode.cpp
kernel_interface.cpp
+ ShortDirectory.cpp
Volume.cpp
xfs.cpp
;