From Shubham Bhagat <shubhambhagat111@xxxxxxxxx>:
Shubham Bhagat has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/2981 ;)
Change subject: xfs: An attempt to read block directories
......................................................................
xfs: An attempt to read block directories
Map entries can be read, most structures are in place. Next is to
actually work with the directory block.
---
M src/add-ons/kernel/file_systems/xfs/Debug.h
M src/add-ons/kernel/file_systems/xfs/Directory.cpp
M src/add-ons/kernel/file_systems/xfs/Directory.h
A src/add-ons/kernel/file_systems/xfs/Extent.cpp
A src/add-ons/kernel/file_systems/xfs/Extent.h
M src/add-ons/kernel/file_systems/xfs/Inode.cpp
M src/add-ons/kernel/file_systems/xfs/Inode.h
M src/add-ons/kernel/file_systems/xfs/Jamfile
M src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
M src/add-ons/kernel/file_systems/xfs/xfs_types.h
M src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile
11 files changed, 253 insertions(+), 9 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/81/2981/1
diff --git a/src/add-ons/kernel/file_systems/xfs/Debug.h
b/src/add-ons/kernel/file_systems/xfs/Debug.h
index ec5a36b..ac7413c 100644
--- a/src/add-ons/kernel/file_systems/xfs/Debug.h
+++ b/src/add-ons/kernel/file_systems/xfs/Debug.h
@@ -9,7 +9,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)
#define ASSERT(x) \
diff --git a/src/add-ons/kernel/file_systems/xfs/Directory.cpp
b/src/add-ons/kernel/file_systems/xfs/Directory.cpp
index ad825ec..3f53817 100644
--- a/src/add-ons/kernel/file_systems/xfs/Directory.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/Directory.cpp
@@ -30,6 +30,13 @@
return B_NO_MEMORY;
return B_OK;
}
+ if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
+ fExtentDir = new(std::nothrow) Extent(fInode);
+ if (fExtentDir == NULL)
+ return B_NO_MEMORY;
+ status_t status = fExtentDir->Init();
+ return status;
+ }
/* Return B_OK so even if the shortform directory has an extent
directory
* we can atleast still list the shortform directory
@@ -87,6 +94,8 @@
//TODO: Reading from extent based dirs
if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
TRACE("Iterator:Lookup: EXTENTS");
+ // status_t status = fExtentDir->Lookup(name, length, ino);
+ // return status;
return B_NOT_SUPPORTED;
}
diff --git a/src/add-ons/kernel/file_systems/xfs/Directory.h
b/src/add-ons/kernel/file_systems/xfs/Directory.h
index fd0e3be..29450d2 100644
--- a/src/add-ons/kernel/file_systems/xfs/Directory.h
+++ b/src/add-ons/kernel/file_systems/xfs/Directory.h
@@ -8,6 +8,7 @@
#include "Inode.h"
#include "ShortDirectory.h"
+#include "Extent.h"
/*
@@ -28,6 +29,7 @@
private:
Inode* fInode;
ShortDirectory* fShortDir;
+ Extent* fExtentDir;
// Short form Directory type
};
diff --git a/src/add-ons/kernel/file_systems/xfs/Extent.cpp
b/src/add-ons/kernel/file_systems/xfs/Extent.cpp
new file mode 100644
index 0000000..fd42e5b
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Extent.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "Extent.h"
+
+
+uint32
+hashfunction(const char* name, int length)
+{
+ uint32 hashVal = 0;
+
+ int lengthCovered = 0;
+ int index = 0;
+ if (length >= 4) {
+ for (; index <= length; index+=4)
+ {
+ lengthCovered = index;
+ hashVal = (name[index] << 21) ^ (name[index+1] << 14) ^
(name[index+2] << 7)
+ ^ (name[index+3] << 0) ^ ((hashVal << 28) |
(hashVal >> (4)));
+ }
+ }
+
+ int leftToCover = length - lengthCovered;
+ if (leftToCover == 3) {
+ hashVal = (name[index] << 14) ^ (name[index+1] << 7) ^
(name[index+2] << 0)
+ ^ ((hashVal << 21) | (hashVal >> (11)));
+ }
+ if (leftToCover == 2) {
+ hashVal = (name[index] << 7) ^ (name[index+1] << 0)
+ ^ ((hashVal << 14) | (hashVal >> (32 - 14)));
+ }
+ if (leftToCover == 1) {
+ hashVal = (name[index] << 0) ^ ((hashVal << 7) | (hashVal >>
(32 - 7)));
+ }
+
+ return hashVal;
+}
+
+
+Extent::Extent(Inode* inode)
+ :
+ fInode(inode)
+{
+}
+
+
+void
+Extent::FillMapEntry(void* pointerToMap)
+{
+ uint64 firstHalf = *((uint64*)pointerToMap);
+ uint64 secondHalf = *((uint64*)pointerToMap + 1);
+ //dividing the 128 bits into 2 parts.
+ firstHalf = B_BENDIAN_TO_HOST_INT64(firstHalf);
+ secondHalf = B_BENDIAN_TO_HOST_INT64(secondHalf);
+ fMap->br_state = (firstHalf >> 63);
+ fMap->br_startoff = (firstHalf & MASK(63)) >> 9;
+ fMap->br_startblock = ((firstHalf & MASK(9)) << 43) | (secondHalf >>
21);
+ fMap->br_blockcount = (secondHalf & MASK(21));
+ TRACE("Extent::Init: startoff:(%ld), startblock:(%ld),
blockcount:(%ld),"
+ "state:(%d)\n",
+ fMap->br_startoff,
+ fMap->br_startblock,
+ fMap->br_blockcount,
+ fMap->br_state
+ );
+}
+
+
+status_t
+Extent::Init()
+{
+ fMap = new(std::nothrow) ExtentMapEntry;
+ if (fMap == NULL)
+ return B_NO_MEMORY;
+
+ ASSERT(BlockType() == true);
+ void* pointerToMap = DIR_DFORK_PTR(fInode->Buffer());
+ FillMapEntry(pointerToMap);
+
+ return B_NOT_SUPPORTED;
+}
+
+
+ExtentBlockTail*
+Extent::BlockTail(ExtentDataHeader* header)
+{
+ return (ExtentBlockTail*)
+ ((char*)header + fInode->DirBlockSize() -
sizeof(ExtentBlockTail));
+}
+
+
+ExtentLeafEntry*
+Extent::BlockFirstLeaf(ExtentBlockTail* tail)
+{
+ return (ExtentLeafEntry*)tail - B_BENDIAN_TO_HOST_INT32(tail->count);
+}
+
+
+bool
+Extent::BlockType()
+{
+ bool status = true;
+ if (fInode->NoOfBlocks() != 1)
+ status = false;
+ if (fInode->Size() != fInode->DirBlockSize())
+ status = false;
+ return status;
+}
+
diff --git a/src/add-ons/kernel/file_systems/xfs/Extent.h
b/src/add-ons/kernel/file_systems/xfs/Extent.h
new file mode 100644
index 0000000..9d1dde8
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Extent.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef _EXTENT_H_
+#define _EXTENT_H_
+
+
+#include "Inode.h"
+#include "system_dependencies.h"
+
+
+#define DIR2_BLOCK_HEADER_MAGIC 0x58443242
+ // for v4 system
+#define XFS_DIR2_DATA_FD_COUNT 3
+#define EXTENT_REC_SIZE 128
+#define MASK(n) ((1UL << n) - 1)
+
+
+// xfs_exntst_t
+enum ExtentState {
+ XFS_EXT_NORM,
+ XFS_EXT_UNWRITTEN,
+ XFS_EXT_INVALID
+};
+
+
+// xfs_dir2_data_free_t
+struct FreeRegion {
+ uint16 offset;
+ uint16 length;
+};
+
+
+// xfs_dir2_data_hdr_t
+struct ExtentDataHeader {
+ uint32 magic;
+ FreeRegion
bestfree[XFS_DIR2_DATA_FD_COUNT];
+};
+
+
+// xfs_dir2_data_entry_t
+struct ExtentDataEntry {
+ xfs_ino_t inumber;
+ uint8 namelen;
+ uint8 name[];
+
+// Followed by a file type (8bit) if applicable and a 16bit tag
+// tag is the offset from start of the block
+};
+
+
+// xfs_dir2_data_unused_t
+struct ExtentUnusedEntry {
+ uint16 freetag;
+ // takes the value 0xffff
+ uint16 length;
+ // freetag+length overrides the inumber
of an entry
+ uint16 tag;
+};
+
+
+// xfs_dir2_leaf_entry_t
+struct ExtentLeafEntry {
+ uint32 hashval;
+ uint32 address;
+ // offset into block after >> 3
+};
+
+
+// xfs_dir2_block_tail_t
+struct ExtentBlockTail {
+ uint32 count;
+ // # of entries in leaf
+ uint32 stale;
+ // # of free leaf entries
+};
+
+
+struct ExtentMapEntry {
+ xfs_fileoff_t br_startoff;
+ // logical file block offset
+ xfs_fsblock_t br_startblock;
+ // absolute block number
+ xfs_filblks_t br_blockcount;
+ // # of blocks
+ uint8 br_state;
+ // state of the extent
+};
+
+
+class Extent
+{
+public:
+ Extent(Inode*
inode);
+ ~Extent();
+ status_t Init();
+ bool BlockType();
+ void FillMapEntry(void*
pointerToMap);
+ ExtentDataHeader* BlockHeader();
+ ExtentBlockTail* BlockTail(ExtentDataHeader*
header);
+ ExtentLeafEntry* BlockFirstLeaf(ExtentBlockTail*
tail);
+ xfs_ino_t GetIno();
+ 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;
+ ExtentMapEntry* fMap;
+ char* fBlockBuffer;
+ // This isn't inode data. It holds the
directory block.
+};
+
+
+#endif
diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.cpp
b/src/add-ons/kernel/file_systems/xfs/Inode.cpp
index 787ccd6..670b819 100644
--- a/src/add-ons/kernel/file_systems/xfs/Inode.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/Inode.cpp
@@ -175,7 +175,8 @@
// Inode len to read (size of inode)
TRACE("AgNumber: (%d), AgRelativeIno: (%d), AgRelativeBlockNum: (%d),"
- "Offset: (%d), len: (%d)\n", agNo, agInodeNo, agBlock, offset,
len);
+ "Offset: (%d), len: (%d)\n", agNo,
+ agRelativeInodeNo, agBlock, offset, len);
if (agNo > fVolume->AgCount()) {
ERROR("Inode::GetFromDisk : AG Number more than number of AGs");
diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.h
b/src/add-ons/kernel/file_systems/xfs/Inode.h
index d891c8e..9c41604 100644
--- a/src/add-ons/kernel/file_systems/xfs/Inode.h
+++ b/src/add-ons/kernel/file_systems/xfs/Inode.h
@@ -159,6 +159,9 @@
xfs_fsize_t Size() const { return
fNode->Size(); }
+ uint32 DirBlockSize() const
+ {
return fVolume->DirBlockSize(); }
+
void GetChangeTime(struct
timespec& timestamp) const
{
fNode->GetChangeTime(timestamp); }
diff --git a/src/add-ons/kernel/file_systems/xfs/Jamfile
b/src/add-ons/kernel/file_systems/xfs/Jamfile
index 0509ce2..e1857d2 100644
--- a/src/add-ons/kernel/file_systems/xfs/Jamfile
+++ b/src/add-ons/kernel/file_systems/xfs/Jamfile
@@ -22,6 +22,7 @@
local xfsSources =
DeviceOpener.cpp
Directory.cpp
+ Extent.cpp
Inode.cpp
kernel_cpp.cpp
kernel_interface.cpp
@@ -42,4 +43,4 @@
= [ 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 ] ;
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 1eabf9e..c7e3fd8 100644
--- a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
@@ -152,7 +152,7 @@
_node->ops = &gxfsVnodeOps;
*_type = inode->Mode();
*_flags = 0;
- TRACE("(%d)\n", inode->ID());
+ TRACE("(%ld)\n", inode->ID());
return B_OK;
}
@@ -230,7 +230,7 @@
return status;
}
- TRACE("XFS_LOOKUP: ID: (%d)\n", *_vnodeID);
+ TRACE("XFS_LOOKUP: ID: (%ld)\n", *_vnodeID);
status = get_vnode(volume->FSVolume(), *_vnodeID, NULL);
TRACE("get_vnode status: (%d)\n", status);
return status;
@@ -249,7 +249,7 @@
xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
{
Inode* inode = (Inode*)_node->private_node;
- TRACE("XFS_READ_STAT: id: (%d)\n", inode->ID());
+ TRACE("XFS_READ_STAT: id: (%ld)\n", inode->ID());
stat->st_dev = inode->GetVolume()->ID();
stat->st_ino = inode->ID();
stat->st_nlink = 1;
@@ -351,7 +351,7 @@
xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
{
Inode* inode = (Inode*)_node->private_node;
- TRACE("XFS_OPEN_DIR: (%d)\n", inode->ID());
+ TRACE("XFS_OPEN_DIR: (%ld)\n", inode->ID());
if (!inode->IsDirectory())
return B_NOT_A_DIRECTORY;
diff --git a/src/add-ons/kernel/file_systems/xfs/xfs_types.h
b/src/add-ons/kernel/file_systems/xfs/xfs_types.h
index 3b1fd6e..ae32585 100644
--- a/src/add-ons/kernel/file_systems/xfs/xfs_types.h
+++ b/src/add-ons/kernel/file_systems/xfs/xfs_types.h
@@ -29,10 +29,9 @@
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_fileoff_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
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 c9fe209..1f3f52b 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
@@ -41,6 +41,7 @@
local xfsSource =
DeviceOpener.cpp
Directory.cpp
+ Extent.cpp
Inode.cpp
kernel_interface.cpp
ShortDirectory.cpp
--
To view, visit https://review.haiku-os.org/c/haiku/+/2981
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I700ee2e003bdef97838b1f06a95e53a5e4293658
Gerrit-Change-Number: 2981
Gerrit-PatchSet: 1
Gerrit-Owner: Shubham Bhagat <shubhambhagat111@xxxxxxxxx>
Gerrit-MessageType: newchange