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 <pulkomandy@gmail.com>
This commit is contained in:
Suhel Mehta 2020-05-22 14:30:30 +05:30 committed by Adrien Destugues
parent 69c8afc98e
commit 589de4799a
5 changed files with 101 additions and 31 deletions

View File

@ -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;

View File

@ -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()
{

View File

@ -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

View File

@ -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;
}

View File

@ -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 */