From 589de4799a4c1e367c737cb286a821ec307d195b Mon Sep 17 00:00:00 2001 From: Suhel Mehta Date: Fri, 22 May 2020 14:30:30 +0530 Subject: [PATCH] ufs2: Implementing read_stat function and fs_info Change-Id: I337c53c017f00f480af7ac94a5774b39eb5255db Reviewed-on: https://review.haiku-os.org/c/haiku/+/2773 Reviewed-by: Adrien Destugues --- src/add-ons/kernel/file_systems/ufs2/Inode.h | 34 +++++++++++--- .../kernel/file_systems/ufs2/Volume.cpp | 10 +++++ src/add-ons/kernel/file_systems/ufs2/Volume.h | 45 ++++++++++--------- .../file_systems/ufs2/kernel_interface.cpp | 41 +++++++++++++++-- src/add-ons/kernel/file_systems/ufs2/ufs2.h | 2 +- 5 files changed, 101 insertions(+), 31 deletions(-) diff --git a/src/add-ons/kernel/file_systems/ufs2/Inode.h b/src/add-ons/kernel/file_systems/ufs2/Inode.h index 6fe1b77842..e1499f1f72 100644 --- a/src/add-ons/kernel/file_systems/ufs2/Inode.h +++ b/src/add-ons/kernel/file_systems/ufs2/Inode.h @@ -12,6 +12,13 @@ #define UFS2_ROOT ((ino_t)2) + +struct timeval32 +{ + int tv_sec, tv_usec; +}; + + struct ufs2_inode { u_int16_t fileMode; int16_t linkCount; @@ -20,10 +27,10 @@ struct ufs2_inode { int32_t inodeBlockSize; int64_t size; int64_t byteHeld; - int64_t accessTime; - int64_t modifiedTime; - int64_t changeTime; - int64_t createTime; + struct timeval32 accessTime; + struct timeval32 modifiedTime; + struct timeval32 changeTime; + struct timeval32 createTime; /* time in nano seconds */ int32_t nsModifiedTime; int32_t nsAccessTime; @@ -57,6 +64,20 @@ struct ufs2_inode { int64_t unused2; int64_t unused3; + + static void _DecodeTime(struct timespec& timespec, timeval32 time) + { + timespec.tv_sec = time.tv_sec; + timespec.tv_nsec = time.tv_usec * 1000; + } + void GetAccessTime(struct timespec& timespec) const + { _DecodeTime(timespec, accessTime); } + void GetChangeTime(struct timespec& timespec) const + { _DecodeTime(timespec, changeTime); } + void GetModificationTime(struct timespec& timespec) const + { _DecodeTime(timespec, modifiedTime); } + void GetCreationTime(struct timespec& timespec) const + { _DecodeTime(timespec, createTime); } }; class Inode { @@ -86,14 +107,14 @@ class Inode { off_t Size() const { return fNode.size; } uid_t UserID() const { return fNode.userId; } gid_t GroupID() const { return fNode.groupId; } - /*void GetChangeTime(struct timespec& timespec) const + void GetChangeTime(struct timespec& timespec) const { fNode.GetChangeTime(timespec); } void GetModificationTime(struct timespec& timespec) const { fNode.GetModificationTime(timespec); } void GetCreationTime(struct timespec& timespec) const { fNode.GetCreationTime(timespec); } void GetAccessTime(struct timespec& timespec) const - { fNode.GetCreationTime(timespec); }*/ + { fNode.GetAccessTime(timespec); } Volume* GetVolume() const { return fVolume; } @@ -119,6 +140,7 @@ 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/Volume.cpp b/src/add-ons/kernel/file_systems/ufs2/Volume.cpp index 6c1d657008..1dae4b25b5 100644 --- a/src/add-ons/kernel/file_systems/ufs2/Volume.cpp +++ b/src/add-ons/kernel/file_systems/ufs2/Volume.cpp @@ -27,6 +27,16 @@ ufs2_super_block::IsValid() } +const char* +Volume::Name() const +{ + if (fSuperBlock.fs_volname[0]) + return fSuperBlock.fs_volname; + + return fName; +} + + bool Volume::IsValidSuperBlock() { diff --git a/src/add-ons/kernel/file_systems/ufs2/Volume.h b/src/add-ons/kernel/file_systems/ufs2/Volume.h index 66ad0272ff..8bae234709 100644 --- a/src/add-ons/kernel/file_systems/ufs2/Volume.h +++ b/src/add-ons/kernel/file_systems/ufs2/Volume.h @@ -18,31 +18,34 @@ class Inode; class Volume { public: - Volume(fs_volume* volume); - ~Volume(); + Volume(fs_volume* volume); + ~Volume(); - status_t Mount(const char* device, uint32 flags); - status_t Unmount(); - status_t Initialize(int fd, const char* name, - uint32 blockSize, uint32 flags); + status_t Mount(const char* device, uint32 flags); + status_t Unmount(); + status_t Initialize(int fd, const char* name, + uint32 blockSize, uint32 flags); - bool IsValidSuperBlock(); - bool IsValidInodeBlock(off_t block) const; - bool IsReadOnly() const; - fs_volume* FSVolume() const { return fFSVolume; } - dev_t ID() const - { return fFSVolume ? fFSVolume->id : -1; } - ufs2_super_block& SuperBlock() { return fSuperBlock; } - status_t LoadSuperBlock(); - static status_t Identify(int fd, ufs2_super_block* superBlock); + bool IsValidSuperBlock(); + bool IsValidInodeBlock(off_t block) const; + bool IsReadOnly() const + { return (fFlags & VOLUME_READ_ONLY) != 0; } + const char* Name() const; + fs_volume* FSVolume() const { return fFSVolume; } + dev_t ID() const + { return fFSVolume ? fFSVolume->id : -1; } + ufs2_super_block& SuperBlock() { return fSuperBlock; } + status_t LoadSuperBlock(); +static status_t Identify(int fd, ufs2_super_block* superBlock); private: - fs_volume* fFSVolume; - int fDevice; - ufs2_super_block fSuperBlock; - mutex fLock; - uint32 fFlags; - Inode* fRootNode; + fs_volume* fFSVolume; + int fDevice; + ufs2_super_block fSuperBlock; + mutex fLock; + uint32 fFlags; + Inode* fRootNode; + char fName[32]; }; #endif // VOLUME_H 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 cc8738f8d2..b2f6b25331 100644 --- a/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp @@ -9,7 +9,9 @@ #include "Volume.h" #include "Inode.h" -#ifdef TRACE_ufs2 + +#define TRACE_UFS2 +#ifdef TRACE_UFS2 #define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x) #else #define TRACE(x...) ; @@ -107,7 +109,18 @@ ufs2_unmount(fs_volume *_volume) static status_t ufs2_read_fs_info(fs_volume *_volume, struct fs_info *info) { - return B_NOT_SUPPORTED; + Volume* volume = (Volume*)_volume->private_volume; + + // File system flags + info->flags = B_FS_IS_PERSISTENT + | (volume->IsReadOnly() ? B_FS_IS_READONLY : 0); + info->io_size = 65536; + info->block_size = volume->SuperBlock().fs_sbsize; + info->total_blocks = volume->SuperBlock().fs_size; + + strlcpy(info->volume_name, volume->Name(), sizeof(info->volume_name)); + + return B_OK; } @@ -198,7 +211,29 @@ ufs2_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd, static status_t ufs2_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat) { - return B_NOT_SUPPORTED; + TRACE("Reading stat...\n"); + Inode* inode = (Inode*)_node->private_node; + stat->st_dev = inode->GetVolume()->ID(); + stat->st_ino = inode->ID(); +// TODO handle hardlinks which will have nlink > 1. Maybe linkCount in inode +// structure may help? + stat->st_nlink = 1; + stat->st_blksize = 65536; + + stat->st_uid = inode->UserID(); + stat->st_gid = inode->GroupID(); + stat->st_mode = inode->Mode(); + stat->st_type = 0; + + inode->GetAccessTime(stat->st_atim); +/* inode->GetModificationTime(stat->st_mtim);*/ + inode->GetChangeTime(stat->st_ctim); + inode->GetCreationTime(stat->st_crtim); + + stat->st_size = inode->Size(); + stat->st_blocks = (inode->Size() + 511) / 512; + + 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 2fc1b7d637..36f46411cf 100644 --- a/src/add-ons/kernel/file_systems/ufs2/ufs2.h +++ b/src/add-ons/kernel/file_systems/ufs2/ufs2.h @@ -301,7 +301,7 @@ struct ufs2_super_block { int8_t fs_ronly; /* mounted read-only flag */ int8_t fs_old_flags; /* old FS_ flags */ u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */ - u_char fs_volname[MAXVOLLEN]; /* volume name */ + char fs_volname[MAXVOLLEN]; /* volume name */ u_int64_t fs_swuid; /* system-wide uid */ int32_t fs_pad; /* due to alignment of fs_swuid */ /* these fields retain the current block allocation info */