MOS Source Code
Loading...
Searching...
No Matches
vfs_utils.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4
10#include "mos/mm/slab.h"
12
14#include <mos/types.h>
15#include <mos_stdlib.h>
16#include <mos_string.h>
17
20
21static dentry_t *dentry_create(superblock_t *sb, dentry_t *parent, const char *name)
22{
23 dentry_t *dentry = kmalloc(dentry_cache);
24 dentry->superblock = sb;
26
27 if (name)
28 dentry->name = strdup(name);
29
30 if (parent)
31 {
33 tree_add_child(tree_node(parent), tree_node(dentry));
34 dentry->superblock = parent->superblock;
35 }
36
37 return dentry;
38}
39
41{
42 if (!parent)
43 return dentry_create(sb, NULL, name);
44
45 dentry_t *dentry = NULL;
46
47 spinlock_acquire(&parent->lock);
48 tree_foreach_child(dentry_t, child, parent)
49 {
50 if (strcmp(child->name, name) == 0)
51 {
52 dentry = child;
53 break;
54 }
55 }
56
57 // if not found, create a new one
58 if (!dentry)
59 dentry = dentry_create(sb, parent, name);
60
61 spinlock_release(&parent->lock);
62 return dentry;
63}
64
65bool simple_page_write_begin(inode_cache_t *icache, off_t offset, size_t size, phyframe_t **page, void **private)
66{
68 *page = pagecache_get_page_for_write(icache, offset / MOS_PAGE_SIZE);
69 if (!*page)
70 return false;
71
72 *private = NULL;
73 return true;
74}
75
76void simple_page_write_end(inode_cache_t *icache, off_t offset, size_t size, phyframe_t *page, void *private)
77{
78 MOS_UNUSED(page);
79 MOS_UNUSED(private);
80
81 // also update the inode's size
82 if (offset + size > icache->owner->size)
83 icache->owner->size = offset + size;
84}
85
87{
88 MOS_UNUSED(icache);
89 MOS_UNUSED(pgoff);
90 MOS_UNUSED(page);
91 return 0;
92}
93
94// read from the page cache, the size and offset are already validated to be in the file's bounds
95ssize_t vfs_generic_read(const file_t *file, void *buf, size_t size, off_t offset)
96{
97 // cap the read size to the file's size
98 size = MIN(size, file->dentry->inode->size - offset);
99 inode_cache_t *icache = &file->dentry->inode->cache;
100 const ssize_t read = vfs_read_pagecache(icache, buf, size, offset);
101 return read;
102}
103
104// write to the page cache, the size and offset are already validated to be in the file's bounds
105ssize_t vfs_generic_write(const file_t *file, const void *buf, size_t size, off_t offset)
106{
107 inode_cache_t *icache = &file->dentry->inode->cache;
108 const ssize_t written = vfs_write_pagecache(icache, buf, size, offset);
109 return written;
110}
111
112bool vfs_simple_write_begin(inode_cache_t *icache, off_t offset, size_t size)
113{
114 MOS_UNUSED(icache);
115 MOS_UNUSED(offset);
117 return true;
118}
119
121{
122 dentry_t *d_parent = dentry_parent(dir);
123 if (d_parent == NULL)
124 d_parent = root_dentry;
125
126 MOS_ASSERT(d_parent->inode != NULL);
127 MOS_ASSERT(dir->inode);
128
129 add_record(state, dir->inode->ino, ".", 1, FILE_TYPE_DIRECTORY);
130 add_record(state, d_parent->inode->ino, "..", 2, FILE_TYPE_DIRECTORY);
131
132 tree_foreach_child(dentry_t, child, dir)
133 {
134 if (child->inode)
135 add_record(state, child->inode->ino, child->name, strlen(child->name), child->inode->type);
136 }
137}
#define MOS_ASSERT(cond)
Definition assert.h:14
#define MOS_PAGE_SIZE
Definition autoconf.h:6
@ FILE_TYPE_DIRECTORY
Definition fs_types.h:16
should_inline dentry_t * dentry_parent(const dentry_t *dentry)
Definition dentry.h:65
MOSAPI char * strdup(const char *src)
MOSAPI s32 strcmp(const char *str1, const char *str2)
Definition mos_string.c:24
#define MIN(a, b)
Definition mos_stdlib.h:30
dentry_t * root_dentry
Definition vfs.c:36
#define MOS_UNUSED(x)
Definition mos_global.h:64
ssize_t vfs_write_pagecache(inode_cache_t *icache, const void *buf, size_t total_size, off_t offset)
Definition page_cache.c:137
phyframe_t * pagecache_get_page_for_write(inode_cache_t *cache, off_t pgoff)
Get a page from the page cache for writing.
Definition page_cache.c:103
ssize_t vfs_read_pagecache(inode_cache_t *icache, void *buf, size_t size, off_t offset)
Definition page_cache.c:108
#define NULL
Definition pb_syshdr.h:46
static size_t strlen(const char *s)
Definition pb_syshdr.h:80
size_t size
Definition slab.c:30
const char * name
Definition slab.c:31
#define SLAB_AUTOINIT(name, var, type)
should_inline bool spinlock_is_locked(const spinlock_t *lock)
Definition spinlock.h:68
#define spinlock_acquire(lock)
Definition spinlock.h:61
#define spinlock_release(lock)
Definition spinlock.h:62
superblock_t * superblock
Definition vfs_types.h:119
spinlock_t lock
Definition vfs_types.h:115
const char * name
Definition vfs_types.h:118
inode_t * inode
Definition vfs_types.h:117
dentry_t * dentry
Definition vfs_types.h:200
inode_t * owner
Definition vfs_types.h:150
size_t size
Definition vfs_types.h:160
inode_cache_t cache
Definition vfs_types.h:175
u64 ino
Definition vfs_types.h:157
Definition slab.h:45
MOSAPI void tree_node_init(tree_node_t *node)
Definition tree.c:8
#define tree_node(element)
Definition tree.h:29
MOSAPI void tree_add_child(tree_node_t *parent, tree_node_t *child)
Definition tree.c:14
#define tree_foreach_child(t, v, h)
Definition tree.h:36
ssize_t off_t
Definition types.h:84
signed long ssize_t
Definition types.h:83
void dentry_iterator_op(vfs_listdir_state_t *state, u64 ino, const char *name, size_t name_len, file_type_t type)
Definition vfs_types.h:60
bool simple_page_write_begin(inode_cache_t *icache, off_t offset, size_t size, phyframe_t **page, void **private)
Definition vfs_utils.c:65
static dentry_t * dentry_create(superblock_t *sb, dentry_t *parent, const char *name)
Definition vfs_utils.c:21
ssize_t vfs_generic_write(const file_t *file, const void *buf, size_t size, off_t offset)
Definition vfs_utils.c:105
void vfs_generic_iterate_dir(const dentry_t *dir, vfs_listdir_state_t *state, dentry_iterator_op add_record)
Definition vfs_utils.c:120
dentry_t * dentry_get_from_parent(superblock_t *sb, dentry_t *parent, const char *name)
Create a new dentry with the given name and parent.
Definition vfs_utils.c:40
void simple_page_write_end(inode_cache_t *icache, off_t offset, size_t size, phyframe_t *page, void *private)
Definition vfs_utils.c:76
bool vfs_simple_write_begin(inode_cache_t *icache, off_t offset, size_t size)
Definition vfs_utils.c:112
slab_t * dentry_cache
Definition vfs_utils.c:18
ssize_t vfs_generic_read(const file_t *file, void *buf, size_t size, off_t offset)
Definition vfs_utils.c:95
long simple_flush_page_discard_data(inode_cache_t *icache, off_t pgoff, phyframe_t *page)
Definition vfs_utils.c:86