48 buffer.superblockId = superblockId;
61 buffer.parentId = parentId;
78 panic(
NULL,
"vfs: failed to initialize map");
94 LOG_INFO(
"virtual file system initialized\n");
170 if (superblock ==
NULL)
175 map_key_t key = inode_cache_key(superblock->
id, number);
303 if (superblock ==
NULL)
356 return path_walk(outPath, pathname, &cwd, flags, &process->namespace);
375 return path_walk_parent(outPath, pathname, &cwd, outLastName, flags, &process->namespace);
673 if (fdsLocal[0] ==
ERR)
678 if (fdsLocal[1] ==
ERR)
958 for (
uint64_t i = 0; i < amount; i++)
971 if (ctx->
queues[j] == queue)
994 for (
uint64_t i = 0; i < amount; i++)
1029 for (
uint64_t i = 0; i < amount; i++)
1069 deadline =
uptime + timeout;
1084 if (readyCount ==
ERR)
1090 if (readyCount > 0 ||
uptime >= deadline)
1127 for (
uint64_t i = 0; i < amount; i++)
1152 for (
uint64_t i = 0; i < amount; i++)
1158 for (
uint64_t i = 0; i < amount; i++)
1374 return vfs_link(&oldPathname, &newPathname, process);
#define MAX_NAME
Maximum length of names.
#define assert(expression)
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
dentry_t * dentry_new(superblock_t *superblock, dentry_t *parent, const char *name)
Create a new dentry.
uint64_t dentry_id_t
Dentry ID type.
file_t * file_new(inode_t *inode, const path_t *path, path_flags_t flags)
Create a new file structure.
void inode_notify_change(inode_t *inode)
Notify the inode that its metadata has changed.
void inode_notify_modify(inode_t *inode)
Notify the inode that its content has been modified.
void inode_notify_access(inode_t *inode)
Notify the inode that it has been accessed.
void inode_truncate(inode_t *inode)
Truncate the inode.
void key_init(void)
Initializes the key subsystem.
uint64_t path_walk_parent(path_t *outPath, const pathname_t *pathname, const path_t *start, char *outLastName, walk_flags_t flags, namespace_t *ns)
Traverse a pathname to its parent and get the last component name.
#define PATH_CREATE(inMount, inDentry)
Helper to create a path.
uint64_t path_walk(path_t *outPath, const pathname_t *pathname, const path_t *start, walk_flags_t flags, namespace_t *ns)
Traverse a pathname from a specified starting path.
#define PATH_DEFER(path)
Defer path put.
uint64_t path_walk_single_step(path_t *outPath, const path_t *parent, const char *name, walk_flags_t flags, namespace_t *ns)
Traverse a single component from a parent path.
walk_flags_t
Flags for walking a path.
#define PATH_VALID_CHAR(ch)
Check if a char is valid.
#define PATHNAME_IS_VALID(pathname)
Check if a pathname is valid.
void path_flags_init(void)
Initialize path flags resolution.
void path_copy(path_t *dest, const path_t *src)
Copy a path.
#define PATH_EMPTY
Helper to create an empty path.
@ WALK_NEGATIVE_IS_OK
If a negative dentry is ok, if not specified then it is considered an error.
uint64_t superblock_id_t
Superblock ID type.
uint64_t vfs_ctx_get_cwd(vfs_ctx_t *ctx, path_t *outCwd)
fd_t vfs_ctx_alloc_fd(vfs_ctx_t *ctx, file_t *file)
Allocate a new file descriptor in a VFS context.
uint64_t vfs_ctx_free_fd(vfs_ctx_t *ctx, fd_t fd)
Free a file descriptor in a VFS context.
file_t * vfs_ctx_get_file(vfs_ctx_t *ctx, fd_t fd)
Get a file from a VFS context.
uint64_t vfs_ioctl(file_t *file, uint64_t request, void *argp, uint64_t size)
Perform an ioctl operation on a file.
uint64_t vfs_register_fs(filesystem_t *fs)
Registers a filesystem.
uint64_t vfs_unregister_fs(filesystem_t *fs)
Unregisters a filesystem.
uint64_t vfs_get_new_id(void)
Generates a new unique ID.
uint64_t vfs_seek(file_t *file, int64_t offset, seek_origin_t origin)
Seek in a file.
void * vfs_mmap(file_t *file, void *address, uint64_t length, pml_flags_t flags)
Memory map a file.
void vfs_remove_inode(inode_t *inode)
Remove an inode from the inode cache.
bool vfs_is_name_valid(const char *name)
Check if a name is valid.
uint64_t vfs_walk_parent_and_child(path_t *outParent, path_t *outChild, const pathname_t *pathname, walk_flags_t flags, process_t *process)
Walk a pathname to path and its parent path, starting from the current process's working directory.
filesystem_t * vfs_get_fs(const char *name)
Gets a filesystem by name.
uint64_t vfs_poll(poll_file_t *files, uint64_t amount, clock_t timeout)
Poll multiple files.
uint64_t vfs_getdents(file_t *file, dirent_t *buffer, uint64_t count)
Get directory entries from a directory file.
void vfs_remove_dentry(dentry_t *dentry)
Remove a dentry from the dentry cache.
uint64_t vfs_write(file_t *file, const void *buffer, uint64_t count)
Write to a file.
file_t * vfs_open(const pathname_t *pathname, process_t *process)
Open a file.
uint64_t vfs_add_dentry(dentry_t *dentry)
Add a dentry to the dentry cache.
dentry_t * vfs_get_or_lookup_dentry(const path_t *parent, const char *name)
Get or lookup a dentry for the given name. Will NOT traverse mountpoints.
uint64_t vfs_remove(const pathname_t *pathname, process_t *process)
Remove a file or directory.
dentry_t * vfs_get_dentry(const dentry_t *parent, const char *name)
Get a dentry for the given name. Will NOT traverse mountpoints.
uint64_t vfs_stat(const pathname_t *pathname, stat_t *buffer, process_t *process)
Get file information.
uint64_t vfs_walk_parent(path_t *outPath, const pathname_t *pathname, char *outLastName, walk_flags_t flags, process_t *process)
Walk a pathname to its parent path, starting from the current process's working directory.
void vfs_remove_superblock(superblock_t *superblock)
Remove a superblock from the superblock list.
uint64_t vfs_read(file_t *file, void *buffer, uint64_t count)
Read from a file.
uint64_t vfs_walk(path_t *outPath, const pathname_t *pathname, walk_flags_t flags, process_t *process)
Walk a pathname to a path, starting from the current process's working directory.
void vfs_init(void)
Initializes the VFS.
uint64_t vfs_link(const pathname_t *oldPathname, const pathname_t *newPathname, process_t *process)
Make the same file appear twice in the filesystem.
uint64_t vfs_open2(const pathname_t *pathname, file_t *files[2], process_t *process)
Open one file, returning two file handles.
inode_t * vfs_get_inode(superblock_t *superblock, inode_number_t number)
Get an inode for the given superblock and inode number.
uint64_t vfs_add_inode(inode_t *inode)
Add a inode to the inode cache.
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
#define LOG_INFO(format,...)
void space_unpin(space_t *space, const void *address, uint64_t length)
Unpins pages in a region previously pinned with space_pin() or space_pin_string().
uint64_t space_check_access(space_t *space, const void *addr, uint64_t length)
Checks if a virtual memory region is within the allowed address range of the space.
uint64_t space_pin(space_t *space, const void *address, uint64_t length, stack_pointer_t *userStack)
Pins pages within a region of the address space.
pml_flags_t vmm_prot_to_flags(prot_t prot)
Converts the user space memory protection flags to page table entry flags.
uint64_t thread_copy_to_user(thread_t *thread, void *dest, const void *userSrc, uint64_t length)
Safely copy data to user space.
uint64_t thread_copy_from_user_pathname(thread_t *thread, pathname_t *pathname, const char *userPath)
Safely copy a string from user space and use it to initialize a pathname.
uint64_t wait_block_commit(void)
Block the currently running thread.
uint64_t wait_block_setup(wait_queue_t **waitQueues, uint64_t amount, clock_t timeout)
Setup blocking but dont block yet.
void wait_block_cancel(void)
Cancel blocking.
process_t * sched_process(void)
Retrieves the process of the currently running thread.
thread_t * sched_thread(void)
Retrieves the currently running thread.
void mutex_release(mutex_t *mtx)
Releases a mutex.
void mutex_acquire(mutex_t *mtx)
Acquires a mutex, blocking until it is available.
#define MUTEX_SCOPE(mutex)
Acquires a mutex for the reminder of the current scope.
#define RWLOCK_READ_SCOPE(lock)
Acquires a rwlock for reading for the reminder of the current scope.
void rwlock_init(rwlock_t *lock)
Initializes a rwlock.
#define RWLOCK_WRITE_SCOPE(lock)
Acquires a rwlock for writing for the reminder of the current scope.
clock_t timer_uptime(void)
Time since boot.
static map_key_t map_key_buffer(const void *buffer, uint64_t length)
Create a map key from a buffer.
uint64_t map_insert(map_t *map, const map_key_t *key, map_entry_t *value)
Insert a key-value pair into the map.
uint64_t map_init(map_t *map)
Initialize a map.
void map_remove(map_t *map, const map_key_t *key)
Remove a key-value pair from the map.
map_entry_t * map_get(map_t *map, const map_key_t *key)
Get a value from the map by key.
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
#define REF(ptr)
Increment reference count.
#define DEREF(ptr)
Decrement reference count.
#define CONFIG_MAX_FD
Maximum file descriptor configuration.
#define ENOENT
No such file or directory.
#define ESTALE
Stale NFS file handle.
#define EEXIST
File exists.
#define ESPIPE
Illegal seek.
#define EINVAL
Invalid argument.
#define EXDEV
Cross-device link.
#define EFAULT
Bad address.
#define ENOSYS
Function not implemented.
#define ETIMEDOUT
Connection timed out.
#define EBUSY
Device or resource busy.
#define ENOTDIR
Not a directory.
#define EBADFLAG
Invalid path flag.
#define errno
Error number variable.
#define ENOTTY
Not a typewriter.
#define EBADF
Bad file number.
#define EPERM
Operation not permitted.
#define EISDIR
Is a directory.
uint64_t inode_number_t
Inode number enum.
uint8_t seek_origin_t
Type for the seek() origin argument.
poll_events_t
Poll events type.
#define POLL_SPECIAL
Poll event values that will always be checked and included even if not specified.
@ INODE_DIR
Is a directory.
@ POLLNVAL
Invalid file descriptor.
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
static void list_push(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
static void list_init(list_t *list)
Initializes a list.
clock_t uptime(void)
System call for retreving the time since boot.
prot_t
Memory protection flags.
#define NULL
Pointer error value.
#define ERR
Integer error value.
__UINT64_TYPE__ fd_t
A file descriptor.
#define CONTAINER_OF_SAFE(ptr, type, member)
Safe container of macro.
__UINT64_TYPE__ clock_t
A nanosecond time.
EFI_PHYSICAL_ADDRESS buffer
static socket_family_ops_t ops
#define RFLAGS_INTERRUPT_ENABLE
static uint64_t rflags_read()
#define atomic_load(object)
#define ATOMIC_VAR_INIT(value)
#define atomic_fetch_add(object, operand)
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
_PUBLIC int strcmp(const char *s1, const char *s2)
_PUBLIC void * memset(void *s, int c, size_t n)
errno_t strncpy_s(char *_RESTRICT s1, rsize_t s1max, const char *_RESTRICT s2, rsize_t n)
size_t strnlen_s(const char *s, size_t maxsize)
uint64_t(* getdents)(dentry_t *dentry, dirent_t *buffer, uint64_t count, uint64_t *offset, path_flags_t flags)
Used to now what is in a directory.
Directory entry structure.
superblock_t * superblock
Filesystem structure, represents a filesystem type, e.g. fat32, ramfs, sysfs, etc.
uint64_t(* create)(inode_t *dir, dentry_t *target, path_flags_t flags)
Handles both directories and files, works the same as lookup.
uint64_t(* remove)(inode_t *parent, dentry_t *target, path_flags_t flags)
Handles both directories and files.
uint64_t(* link)(dentry_t *old, inode_t *dir, dentry_t *target)
uint64_t(* lookup)(inode_t *dir, dentry_t *target)
Should set the target dentry to be positive (give it an inode), if the entry does not exist the opera...
time_t accessTime
Unix time stamp for the last inode access.
time_t createTime
Unix time stamp for the inode creation.
time_t modifyTime
Unix time stamp for last file content alteration.
inode_type_t type
Constant after creation.
inode_number_t number
Constant after creation.
superblock_t * superblock
Constant after creation.
const inode_ops_t * ops
Constant after creation.
time_t changeTime
Unix time stamp for the last file metadata alteration.
map_entry_t mapEntry
Protected by the inodeCache lock.
A entry in a page table without a specified address or callback ID.
Structure for polling multiple files.
Poll file descriptor structure.
poll_events_t revents
The events that occurred.
poll_events_t events
The events to wait for.
fd_t fd
The file descriptor to poll.
atomic_uint32_t count
Atomic reference counter.
Virtual address space structure.
Thread of execution structure.
process_t * process
The parent process that the thread executes within.
stack_pointer_t userStack
The user stack of the thread.
Helper structure for lists with a lock.
Helper structure for maps with a lock.
uint16_t lookupTable[CONFIG_MAX_FD]
wait_queue_t * queues[CONFIG_MAX_FD]
static void vfs_map_init(vfs_map_t *map)
static uint64_t vfs_poll_ctx_check_events(vfs_poll_ctx_t *ctx, poll_file_t *files, uint64_t amount)
static dentry_t * vfs_get_dentry_internal(map_key_t *key)
static map_key_t dentry_cache_key(dentry_id_t parentId, const char *name)
static uint64_t vfs_create(path_t *outPath, const pathname_t *pathname, process_t *process)
static uint64_t vfs_poll_ctx_init(vfs_poll_ctx_t *ctx, poll_file_t *files, uint64_t amount)
static uint64_t vfs_open_lookup(path_t *outPath, const pathname_t *pathname, process_t *process)
dentry_t * vfs_get_root_dentry(void)
static void vfs_list_init(vfs_list_t *list)