mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-01 18:39:16 +00:00
Merge remote-tracking branch 'Drivers/master'
This commit is contained in:
382
Drivers/include/fs.h
Normal file
382
Drivers/include/fs.h
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_FILESYSTEM_H__
|
||||
#define __FENNIX_API_FILESYSTEM_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
/**
|
||||
* File type mask for the upper 32 bits of mode_t.
|
||||
*
|
||||
* @note Maybe it will be used in the future.
|
||||
*/
|
||||
#define S_IFMT32 037777600000
|
||||
|
||||
/**
|
||||
* File type mask.
|
||||
*
|
||||
* This mask is used to extract the file type
|
||||
* from the mode field of a stat structure.
|
||||
*
|
||||
* Doing bitwise AND with this mask will return
|
||||
* the file type.
|
||||
* Example: st_mode & S_IFMT
|
||||
*
|
||||
* Doing bitwise negation and AND with this mask
|
||||
* will return the permissions.
|
||||
* Example: st_mode & ~S_IFMT
|
||||
*/
|
||||
#define S_IFMT 0170000
|
||||
|
||||
/* Whiteout */
|
||||
#define S_IFWHT 0160000
|
||||
/* Socket */
|
||||
#define S_IFSOCK 0140000
|
||||
/* Symbolic link */
|
||||
#define S_IFLNK 0120000
|
||||
/* Regular file */
|
||||
#define S_IFREG 0100000
|
||||
/* Block device */
|
||||
#define S_IFBLK 0060000
|
||||
/* Directory */
|
||||
#define S_IFDIR 0040000
|
||||
/* Character device */
|
||||
#define S_IFCHR 0020000
|
||||
/* FIFO */
|
||||
#define S_IFIFO 0010000
|
||||
|
||||
#define S_ISUID 04000
|
||||
#define S_ISGID 02000
|
||||
#define S_ISVTX 01000
|
||||
|
||||
/** Owner: RWX */
|
||||
#define S_IRWXU 0700
|
||||
/** Owner: R */
|
||||
#define S_IRUSR 0400
|
||||
/** Owner: W */
|
||||
#define S_IWUSR 0200
|
||||
/** Owner: X */
|
||||
#define S_IXUSR 0100
|
||||
|
||||
/** Group: RWX */
|
||||
#define S_IRWXG 0070
|
||||
/** Group: R */
|
||||
#define S_IRGRP 0040
|
||||
/** Group: W */
|
||||
#define S_IWGRP 0020
|
||||
/** Group: X */
|
||||
#define S_IXGRP 0010
|
||||
|
||||
/** Other: RWX */
|
||||
#define S_IRWXO 0007
|
||||
/** Other: R */
|
||||
#define S_IROTH 0004
|
||||
/** Other: W */
|
||||
#define S_IWOTH 0002
|
||||
/** Other: X */
|
||||
#define S_IXOTH 0001
|
||||
|
||||
#define O_RDONLY 00
|
||||
#define O_WRONLY 01
|
||||
#define O_RDWR 02
|
||||
#define O_CREAT 0100
|
||||
#define O_EXCL 0200
|
||||
#define O_TRUNC 01000
|
||||
#define O_APPEND 02000
|
||||
#define O_NOFOLLOW 0400000
|
||||
#define O_CLOEXEC 02000000
|
||||
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
|
||||
#define DT_UNKNOWN 0x0
|
||||
#define DT_FIFO 0x1
|
||||
#define DT_CHR 0x2
|
||||
#define DT_DIR 0x4
|
||||
#define DT_BLK 0x6
|
||||
#define DT_REG 0x8
|
||||
#define DT_LNK 0xA
|
||||
#define DT_SOCK 0xC
|
||||
#define DT_WHT 0xE
|
||||
|
||||
#define IFTODT(x) ((x) >> 12 & 0xF)
|
||||
#define DTTOIF(x) ((x) << 12)
|
||||
|
||||
#define SYMLOOP_MAX 40
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define static_assert _Static_assert
|
||||
#endif
|
||||
|
||||
#ifdef __LP64__
|
||||
static_assert(sizeof(dev_t) == 8, "dev_t must be 64 bits");
|
||||
static_assert(sizeof(ino_t) == 8, "ino_t must be 64 bits");
|
||||
static_assert(sizeof(mode_t) == 4, "mode_t must be 32 bits");
|
||||
static_assert(sizeof(nlink_t) == 4, "nlink_t must be 32 bits");
|
||||
static_assert(sizeof(uid_t) == 4, "uid_t must be 32 bits");
|
||||
static_assert(sizeof(gid_t) == 4, "gid_t must be 32 bits");
|
||||
static_assert(sizeof(off_t) == 8, "off_t must be 64 bits");
|
||||
static_assert(sizeof(time_t) == 8, "time_t must be 64 bits");
|
||||
static_assert(sizeof(blksize_t) == 8, "blksize_t must be 64 bits");
|
||||
static_assert(sizeof(blkcnt_t) == 8, "blkcnt_t must be 64 bits");
|
||||
#else
|
||||
static_assert(sizeof(dev_t) == 4, "dev_t must be 32 bits");
|
||||
static_assert(sizeof(ino_t) == 4, "ino_t must be 32 bits");
|
||||
static_assert(sizeof(mode_t) == 2, "mode_t must be 16 bits");
|
||||
static_assert(sizeof(nlink_t) == 2, "nlink_t must be 16 bits");
|
||||
static_assert(sizeof(uid_t) == 2, "uid_t must be 16 bits");
|
||||
static_assert(sizeof(gid_t) == 2, "gid_t must be 16 bits");
|
||||
static_assert(sizeof(off_t) == 4, "off_t must be 32 bits");
|
||||
static_assert(sizeof(time_t) == 4, "time_t must be 32 bits");
|
||||
static_assert(sizeof(blksize_t) == 4, "blksize_t must be 32 bits");
|
||||
static_assert(sizeof(blkcnt_t) == 4, "blkcnt_t must be 32 bits");
|
||||
#endif
|
||||
|
||||
#undef static_assert
|
||||
|
||||
struct kstat
|
||||
{
|
||||
/** Device ID of the file. */
|
||||
dev_t Device;
|
||||
|
||||
/** Inode number. */
|
||||
ino_t Index;
|
||||
|
||||
/** File type and mode. */
|
||||
mode_t Mode;
|
||||
|
||||
/** Number of hard links. */
|
||||
nlink_t HardLinks;
|
||||
|
||||
/** User ID of the file's owner. */
|
||||
uid_t UserID;
|
||||
|
||||
/** Group ID of the file's owner. */
|
||||
gid_t GroupID;
|
||||
|
||||
/** Device ID for special files. */
|
||||
dev_t RawDevice;
|
||||
|
||||
/** Size of the file in bytes. */
|
||||
off_t Size;
|
||||
|
||||
/** Time of last access. */
|
||||
time_t AccessTime;
|
||||
|
||||
/** Time of last modification. */
|
||||
time_t ModifyTime;
|
||||
|
||||
/** Time of last status change. */
|
||||
time_t ChangeTime;
|
||||
|
||||
/** Optimal I/O block size. */
|
||||
blksize_t BlockSize;
|
||||
|
||||
/** Number of blocks allocated. */
|
||||
blkcnt_t Blocks;
|
||||
|
||||
/** Additional file attributes. */
|
||||
mode_t Attribute;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
dev_t MakeDevice(int Major, int Minor)
|
||||
{
|
||||
return ((Major & 0xFFF) << 8) |
|
||||
(Minor & 0xFF);
|
||||
}
|
||||
|
||||
int GetMajor()
|
||||
{
|
||||
return ((unsigned int)(Device) >> 8) & 0xFFF;
|
||||
}
|
||||
|
||||
int GetMinor()
|
||||
{
|
||||
return Device & 0xFF;
|
||||
}
|
||||
|
||||
void SetFileType(mode_t Type)
|
||||
{
|
||||
Mode = (Mode & ~S_IFMT) |
|
||||
(Type & S_IFMT);
|
||||
}
|
||||
|
||||
mode_t GetFileType() { return Mode & S_IFMT; }
|
||||
void ClearFileType() { Mode = Mode & ~S_IFMT; }
|
||||
bool IsType(mode_t Type) { return (Mode & S_IFMT) == Type; }
|
||||
|
||||
void SetPermissions(mode_t Permissions)
|
||||
{
|
||||
Mode = (Mode & S_IFMT) |
|
||||
(Permissions & ~S_IFMT);
|
||||
}
|
||||
|
||||
mode_t GetPermissions() { return Mode & ~S_IFMT; }
|
||||
void ClearPermissions() { Mode = Mode & S_IFMT; }
|
||||
|
||||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
struct kdirent
|
||||
{
|
||||
ino_t d_ino;
|
||||
off_t d_off;
|
||||
unsigned short d_reclen;
|
||||
unsigned char d_type;
|
||||
char d_name[];
|
||||
};
|
||||
|
||||
struct Inode
|
||||
{
|
||||
dev_t Device, RawDevice;
|
||||
ino_t Index;
|
||||
mode_t Mode;
|
||||
uint32_t Flags;
|
||||
off_t Offset;
|
||||
|
||||
uintptr_t KernelData;
|
||||
void *PrivateData;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* ... */
|
||||
|
||||
void SetDevice(int Major, int Minor)
|
||||
{
|
||||
this->RawDevice = ((Major & 0xFFF) << 8) |
|
||||
(Minor & 0xFF);
|
||||
}
|
||||
|
||||
int GetMajor()
|
||||
{
|
||||
return ((unsigned int)(this->RawDevice) >> 8) & 0xFFF;
|
||||
}
|
||||
|
||||
int GetMinor()
|
||||
{
|
||||
return this->RawDevice & 0xFF;
|
||||
}
|
||||
|
||||
Inode()
|
||||
{
|
||||
Device = 0;
|
||||
RawDevice = 0;
|
||||
Index = 0;
|
||||
Mode = 0;
|
||||
Flags = 0;
|
||||
Offset = 0;
|
||||
KernelData = 0x0;
|
||||
PrivateData = nullptr;
|
||||
}
|
||||
|
||||
~Inode() = default;
|
||||
|
||||
#else // __cplusplus
|
||||
|
||||
#define INODE_MAKEDEV(major, minor) \
|
||||
((dev_t)(((major & 0xFFF) << 8) | \
|
||||
(minor & 0xFF)))
|
||||
|
||||
#define INODE_MAJOR(rdev) \
|
||||
((int)(((rdev) >> 8) & 0xFFF))
|
||||
|
||||
#define INODE_MINOR(rdev) \
|
||||
((int)((rdev) & 0xFF))
|
||||
|
||||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
struct InodeOperations
|
||||
{
|
||||
int (*Lookup)(struct Inode *Parent, const char *Name, struct Inode **Result);
|
||||
int (*Create)(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
|
||||
int (*Remove)(struct Inode *Parent, const char *Name);
|
||||
int (*Rename)(struct Inode *Parent, const char *OldName, const char *NewName);
|
||||
ssize_t (*Read)(struct Inode *Node, void *Buffer, size_t Size, off_t Offset);
|
||||
ssize_t (*Write)(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset);
|
||||
int (*Truncate)(struct Inode *Node, off_t Size);
|
||||
int (*Open)(struct Inode *Node, int Flags, mode_t Mode);
|
||||
int (*Close)(struct Inode *Node);
|
||||
int (*Ioctl)(struct Inode *Node, unsigned long Request, void *Argp);
|
||||
ssize_t (*ReadDir)(struct Inode *Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries);
|
||||
int (*MkDir)(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
|
||||
int (*RmDir)(struct Inode *Parent, const char *Name);
|
||||
int (*SymLink)(struct Inode *Parent, const char *Name, const char *Target, struct Inode **Result);
|
||||
ssize_t (*ReadLink)(struct Inode *Node, char *Buffer, size_t Size);
|
||||
off_t (*Seek)(struct Inode *Node, off_t Offset);
|
||||
int (*Stat)(struct Inode *Node, struct kstat *Stat);
|
||||
} __attribute__((packed));
|
||||
|
||||
#define I_FLAG_ROOT 0x1
|
||||
#define I_FLAG_MOUNTPOINT 0x2
|
||||
#define I_FLAG_CACHE_KEEP 0x4
|
||||
|
||||
struct FileSystemInfo;
|
||||
struct SuperBlockOperations
|
||||
{
|
||||
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
|
||||
int (*DeleteInode)(struct FileSystemInfo *Info, struct Inode *Node);
|
||||
|
||||
/**
|
||||
* Synchronize the filesystem.
|
||||
*
|
||||
* Write all pending changes to the disk.
|
||||
*
|
||||
* @param Info Inode to synchronize. If NULL, synchronize all inodes.
|
||||
*
|
||||
* @return Zero on success, otherwise an error code.
|
||||
*/
|
||||
int (*Synchronize)(struct FileSystemInfo *Info, struct Inode *Node);
|
||||
|
||||
/**
|
||||
* Destroy the filesystem.
|
||||
*
|
||||
* Unregister the filesystem and free all resources.
|
||||
*
|
||||
* @param Info Filesystem to destroy.
|
||||
*
|
||||
* @return Zero on success, otherwise an error code.
|
||||
*/
|
||||
int (*Destroy)(struct FileSystemInfo *Info);
|
||||
} __attribute__((packed));
|
||||
|
||||
struct FileSystemInfo
|
||||
{
|
||||
const char *Name;
|
||||
const char *RootName;
|
||||
int Flags;
|
||||
struct SuperBlockOperations SuperOps;
|
||||
struct InodeOperations Ops;
|
||||
|
||||
void *PrivateData;
|
||||
} __attribute__((packed));
|
||||
|
||||
dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
|
||||
int UnregisterFileSystem(dev_t Device);
|
||||
|
||||
#endif // !__FENNIX_API_FILESYSTEM_H__
|
Reference in New Issue
Block a user