hrev54389 adds 1 changeset to branch 'master'
old head: 4a230cfc6cbfb8413d9a02f81384fa4e201c23cd
new head: 239a1c3561edb27048be8730afb4f9d02d8c3cdc
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=239a1c3561ed+%5E4a230cfc6cbf
----------------------------------------------------------------------------
239a1c3561ed: ufs2: implementing open_dir and read_dir function
Root directory is read sucessfully.
Change-Id: I8bdc8c1a52edb679a6cb4b5f70e7f42eb2b2c8f1
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2907
Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
[ Suhel Mehta <mehtasuhel@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54389
Commit: 239a1c3561edb27048be8730afb4f9d02d8c3cdc
URL: https://git.haiku-os.org/haiku/commit/?id=239a1c3561ed
Author: Suhel Mehta <mehtasuhel@xxxxxxxxx>
Date: Fri Jun 12 19:26:16 2020 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Fri Jul 3 19:21:06 2020 UTC
----------------------------------------------------------------------------
10 files changed, 282 insertions(+), 14 deletions(-)
.../file_systems/ufs2/DirectoryIterator.cpp | 130 +++++++++++++++++++
.../kernel/file_systems/ufs2/DirectoryIterator.h | 66 ++++++++++
src/add-ons/kernel/file_systems/ufs2/Inode.cpp | 11 ++
src/add-ons/kernel/file_systems/ufs2/Inode.h | 4 +-
src/add-ons/kernel/file_systems/ufs2/Jamfile | 1 +
src/add-ons/kernel/file_systems/ufs2/Volume.cpp | 8 +-
src/add-ons/kernel/file_systems/ufs2/Volume.h | 1 +
.../file_systems/ufs2/kernel_interface.cpp | 71 +++++++++-
src/add-ons/kernel/file_systems/ufs2/ufs2.h | 3 +
.../kernel/file_systems/ufs2/ufs2_shell/Jamfile | 1 +
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.cpp
b/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.cpp
new file mode 100644
index 0000000000..36dd4d3d82
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2020 Suhel Mehta, mehtasuhel@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "DirectoryIterator.h"
+
+#include <stdlib.h>
+
+#include "Inode.h"
+
+#define TRACE_UFS2
+#ifdef TRACE_UFS2
+# define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
+#else
+# define TRACE(x...) ;
+#endif
+
+#define ERROR(x...) dprintf("\33[34mufs2:\33[0m " x)
+
+
+DirectoryIterator::DirectoryIterator(Inode* inode)
+ :
+ fInode(inode)
+{
+ TRACE("DirectoryIterator::DirectoryIterator() \n");
+}
+
+
+int DirectoryIterator::countDir = 0;
+
+DirectoryIterator::~DirectoryIterator()
+{
+}
+
+
+status_t
+DirectoryIterator::InitCheck()
+{
+ return B_OK;
+}
+
+
+status_t
+DirectoryIterator::Lookup(const char* name, size_t length, ino_t* _id)
+{
+ int count = 0;
+ if (strcmp(name, ".") == 0) {
+ *_id = fInode->ID();
+ return B_OK;
+ } else if (strcmp(name, "..") == 0) {
+ if (fInode->ID() == 1)
+ *_id = fInode->ID();
+
+ /* else
+ *_id = fInode->Parent();*/
+
+ }
+ while(_GetNext(name, &length, _id, count) != B_OK) {
+ count++;
+ }
+ return B_OK;
+}
+
+
+status_t
+DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
+{
+ TRACE("In GetNext function\n");
+ int64_t offset = fInode->GetBlockPointer() * MINBSIZE;
+ dir direct;
+ dir_info direct_info;
+ int fd = fInode->GetVolume()->Device();
+ if (read_pos(fd, offset, &direct_info,
+ sizeof(dir_info)) != sizeof(dir_info)) {
+ return B_BAD_DATA;
+ }
+
+ offset = offset + sizeof(dir_info) + 16 * countDir;
+ if (read_pos(fd, offset, &direct, sizeof(dir)) != sizeof(dir)) {
+ return B_BAD_DATA;
+ }
+
+ if (direct.next_ino != 0) {
+ strlcpy(name, direct.name, sizeof(name));
+ *_id = direct.next_ino;
+ *_nameLength = direct.namlen;
+ countDir++;
+ return B_OK;
+ }
+ countDir = 0;
+ return B_ENTRY_NOT_FOUND;
+}
+
+
+status_t
+DirectoryIterator::_GetNext(const char* name, size_t* _nameLength,
+ ino_t* _id, int count)
+{
+ TRACE("In GetNext function\n");
+ int64_t offset = fInode->GetBlockPointer() * MINBSIZE;
+ dir direct;
+ dir_info direct_info;
+ int fd = fInode->GetVolume()->Device();
+ if (read_pos(fd, offset, &direct_info,
+ sizeof(dir_info)) != sizeof(dir_info)) {
+ return B_BAD_DATA;
+ }
+ if(strcmp(name, "..") == 0)
+ {
+ *_id = direct_info.dotdot_ino;
+ return B_OK;
+ }
+
+ offset = offset + sizeof(dir_info) + (16 * count);
+ if (read_pos(fd, offset, &direct, sizeof(dir)) != sizeof(dir)) {
+ return B_BAD_DATA;
+ }
+
+ char getname;
+ strlcpy(&getname, direct.name, sizeof(name));
+ if(strcmp(name, &getname) == 0) {
+ *_id = direct.next_ino;
+ return B_OK;
+ }
+ else {
+ return B_ENTRY_NOT_FOUND;
+ }
+}
diff --git a/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.h
b/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.h
new file mode 100644
index 0000000000..5da9f9fa0c
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 Suhel Mehta, mehtasuhel@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#ifndef DIRECTORYITERATOR_H
+#define DIRECTORYITERATOR_H
+
+
+#include "ufs2.h"
+
+
+class Inode;
+
+#define MAXNAMELEN 255
+
+struct dir {
+ u_int32_t next_ino;
+ u_int16_t reclen;
+ u_int8_t type;
+ u_int8_t namlen;
+ char name[MAXNAMELEN + 1];
+};
+
+struct dir_info {
+ u_int32_t dot_ino;
+ int16_t dot_reclen;
+ u_int8_t dot_type;
+ u_int8_t dot_namelen;
+ char dot_name[4];
+ u_int32_t dotdot_ino;
+ int16_t dotdot_reclen;
+ u_int8_t dotdot_type;
+ u_int8_t dotdot_namelen;
+ char dotdot_name[4];
+};
+
+class DirectoryIterator {
+public:
+
DirectoryIterator(Inode* inode);
+
~DirectoryIterator();
+
+ status_t InitCheck();
+ status_t Lookup(const char*
name, size_t length,
+
ino_t* id);
+ status_t GetNext(char* name,
size_t* _nameLength,
+
ino_t* _id);
+ status_t _GetNext(const char*
name, size_t* _nameLength,
+
ino_t* _id, int count);
+ dir* DirectContent() {
return direct; }
+ dir_info* DirectInfo() { return
direct_info; }
+ static int countDir;
+
+private:
+
+ int64 fOffset;
+ cluster_t fCluster;
+ Inode* fInode;
+ dir* direct;
+ dir_info* direct_info;
+
+};
+
+
+#endif // DIRECTORYITERATOR_H
diff --git a/src/add-ons/kernel/file_systems/ufs2/Inode.cpp
b/src/add-ons/kernel/file_systems/ufs2/Inode.cpp
index 7a73cbdc19..455e753d62 100644
--- a/src/add-ons/kernel/file_systems/ufs2/Inode.cpp
+++ b/src/add-ons/kernel/file_systems/ufs2/Inode.cpp
@@ -13,6 +13,7 @@
#endif
#define ERROR(x...) dprintf("\33[34mufs2:\33[0m " x)
+
Inode::Inode(Volume* volume, ino_t id)
:
fVolume(volume),
@@ -29,6 +30,16 @@ Inode::Inode(Volume* volume, ino_t id)
fMap = file_map_create(fVolume->ID(), ID(), Size());
}
}
+ int fd = fVolume->Device();
+ ufs2_super_block* superblock = (ufs2_super_block*
)&fVolume->SuperBlock();
+ int64_t fs_block = ino_to_fsba(superblock, id);
+ int64_t offset_in_block = ino_to_fsbo(superblock, id);
+ int64_t offset = fs_block * MINBSIZE + offset_in_block * 256;
+
+ if (read_pos(fd, offset, (void*)&fNode, sizeof(fNode)) != sizeof(fNode))
+ ERROR("Inode::Inode(): IO Error\n");
+
+
}
diff --git a/src/add-ons/kernel/file_systems/ufs2/Inode.h
b/src/add-ons/kernel/file_systems/ufs2/Inode.h
index e1499f1f72..f76cd1a0f5 100644
--- a/src/add-ons/kernel/file_systems/ufs2/Inode.h
+++ b/src/add-ons/kernel/file_systems/ufs2/Inode.h
@@ -118,6 +118,9 @@ class Inode {
Volume* GetVolume() const { return fVolume; }
+ int64_t GetBlockPointer() { return
fNode.directBlkPtr1; }
+ ino_t Parent();
+
// status_t FindBlock(off_t logical, off_t&
physical,
// off_t* _length = NULL);
// status_t ReadAt(off_t pos, uint8* buffer,
size_t* length);
@@ -140,7 +143,6 @@ private:
::Volume* fVolume;
ino_t fID;
void* fCache;
- bool fHasNanoTime;
void* fMap;
status_t fInitStatus;
ufs2_inode fNode;
diff --git a/src/add-ons/kernel/file_systems/ufs2/Jamfile
b/src/add-ons/kernel/file_systems/ufs2/Jamfile
index b50e8ed08e..5b601de2bf 100644
--- a/src/add-ons/kernel/file_systems/ufs2/Jamfile
+++ b/src/add-ons/kernel/file_systems/ufs2/Jamfile
@@ -19,6 +19,7 @@ DEFINES += DEBUG_APP="\\\"ufs2\\\"" ;
local ufs2Sources =
DeviceOpener.cpp
+ DirectoryIterator.cpp
Inode.cpp
Volume.cpp
kernel_interface.cpp
diff --git a/src/add-ons/kernel/file_systems/ufs2/Volume.cpp
b/src/add-ons/kernel/file_systems/ufs2/Volume.cpp
index 1dae4b25b5..73971d4cb1 100644
--- a/src/add-ons/kernel/file_systems/ufs2/Volume.cpp
+++ b/src/add-ons/kernel/file_systems/ufs2/Volume.cpp
@@ -111,14 +111,10 @@ Volume::Mount(const char *deviceName, uint32 flags)
TRACE("Valid super block\n");
- status = get_vnode(fFSVolume, UFS2_ROOT, (void**) &fRootNode);
- if (status != B_OK) {
- ERROR("could not create root node: get_vnode() failed!
%d\n",status);
- return status;
- }
fRootNode = new(std::nothrow) Inode(this, UFS2_ROOT);
- status = publish_vnode(fFSVolume, UFS2_ROOT, (void*)fRootNode,
+ status = publish_vnode(this->FSVolume(), UFS2_ROOT, (void*)fRootNode,
&gufs2VnodeOps, fRootNode->Mode(), 0);
+
opener.Keep();
return B_OK;
diff --git a/src/add-ons/kernel/file_systems/ufs2/Volume.h
b/src/add-ons/kernel/file_systems/ufs2/Volume.h
index 8bae234709..9defae27dd 100644
--- a/src/add-ons/kernel/file_systems/ufs2/Volume.h
+++ b/src/add-ons/kernel/file_systems/ufs2/Volume.h
@@ -32,6 +32,7 @@ class Volume {
{ return
(fFlags & VOLUME_READ_ONLY) != 0; }
const char* Name() const;
fs_volume* FSVolume() const {
return fFSVolume; }
+ int Device() const
{ return fDevice; }
dev_t ID() const
{ return
fFSVolume ? fFSVolume->id : -1; }
ufs2_super_block& SuperBlock() { return
fSuperBlock; }
diff --git a/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
b/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
index b2f6b25331..c97855353f 100644
--- a/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
@@ -4,11 +4,11 @@
*/
+#include "DirectoryIterator.h"
+#include "Inode.h"
#include "system_dependencies.h"
#include "ufs2.h"
#include "Volume.h"
-#include "Inode.h"
-
#define TRACE_UFS2
#ifdef TRACE_UFS2
@@ -196,7 +196,19 @@ static status_t
ufs2_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
ino_t *_vnodeID)
{
- return B_NOT_SUPPORTED;
+ TRACE("UFS2_LOOKUP: %p (%s)\n", name, name);
+ Volume* volume = (Volume*)_volume->private_volume;
+ Inode* directory = (Inode*)_directory->private_node;
+
+ status_t status = DirectoryIterator(directory).Lookup(name,
strlen(name),
+ (ino_t*)_vnodeID);
+
+ if (status != B_OK)
+ return status;
+
+ status = get_vnode(volume->FSVolume(), *_vnodeID, NULL);
+ TRACE("get_vnode status: %s\n", strerror(status));
+ return status;
}
@@ -215,6 +227,7 @@ ufs2_read_stat(fs_volume *_volume, fs_vnode *_node, struct
stat *stat)
Inode* inode = (Inode*)_node->private_node;
stat->st_dev = inode->GetVolume()->ID();
stat->st_ino = inode->ID();
+ TRACE("stat->st_ino %ld\n",stat->st_ino);
// TODO handle hardlinks which will have nlink > 1. Maybe linkCount in
inode
// structure may help?
stat->st_nlink = 1;
@@ -226,7 +239,7 @@ ufs2_read_stat(fs_volume *_volume, fs_vnode *_node, struct
stat *stat)
stat->st_type = 0;
inode->GetAccessTime(stat->st_atim);
-/* inode->GetModificationTime(stat->st_mtim);*/
+ inode->GetModificationTime(stat->st_mtim);
inode->GetChangeTime(stat->st_ctim);
inode->GetCreationTime(stat->st_crtim);
@@ -269,7 +282,8 @@ ufs2_free_cookie(fs_volume *_volume, fs_vnode *_node, void
*_cookie)
static status_t
ufs2_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
{
- return B_NOT_SUPPORTED;
+ TRACE("In access\n");
+ return B_OK;
}
@@ -308,7 +322,17 @@ ufs2_remove_dir(fs_volume *_volume, fs_vnode *_directory,
const char *name)
static status_t
ufs2_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
{
- return B_NOT_SUPPORTED;
+ Inode* inode = (Inode*)_node->private_node;
+
+ if (!inode->IsDirectory())
+ return B_NOT_A_DIRECTORY;
+
+ DirectoryIterator* iterator = new(std::nothrow)
DirectoryIterator(inode);
+ if (iterator == NULL)
+ return B_NO_MEMORY;
+
+ *_cookie = iterator;
+ return B_OK;
}
@@ -316,7 +340,40 @@ static status_t
ufs2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
struct dirent *dirent, size_t bufferSize, uint32 *_num)
{
- return B_NOT_SUPPORTED;
+ TRACE("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;
+ ino_t iNodeNo;
+
+ status_t status = iterator->GetNext(dirent->d_name, &length,
&iNodeNo);
+ 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 = iNodeNo;
+ dirent->d_reclen = sizeof(dirent) + length;
+ bufferSize -= dirent->d_reclen;
+ dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
+ count++;
+ }
+
+ *_num = count;
+ TRACE("count is %d\n", count);
+ return B_OK;
+
}
diff --git a/src/add-ons/kernel/file_systems/ufs2/ufs2.h
b/src/add-ons/kernel/file_systems/ufs2/ufs2.h
index 36f46411cf..00366f99b2 100644
--- a/src/add-ons/kernel/file_systems/ufs2/ufs2.h
+++ b/src/add-ons/kernel/file_systems/ufs2/ufs2.h
@@ -37,6 +37,9 @@
#include "system_dependencies.h"
+typedef uint32 cluster_t;
+typedef uint64_t ufs2_daddr_t;
+
#define SBLOCK_FLOPPY 0
#define SBLOCK_UFS1 8192
#define SBLOCK_UFS2 65536
diff --git a/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
b/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
index ebc59e0703..8bf460e4f5 100644
--- a/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
+++ b/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
@@ -40,6 +40,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
local ufs2Source =
DeviceOpener.cpp
+ DirectoryIterator.cpp
Inode.cpp
Volume.cpp
kernel_interface.cpp