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