20#define DENTRY_MAP_SIZE 4096
39 if (iter->parent == dentry->
parent && iter->
name[length] ==
'\0' &&
71 curr = &(*curr)->
next;
118 dentry->
name[0] =
'\0';
136 if (superblock ==
NULL)
142 if ((parent ==
NULL || name ==
NULL) && ((
void*)parent != (
void*)name))
190 if (parent ==
NULL || name ==
NULL || length == 0)
202 for (dentry =
map[hash]; dentry !=
NULL; dentry = dentry->
next)
204 if (dentry->
parent == parent && dentry->
name[length] ==
'\0' &&
memcmp(dentry->
name, name, length) == 0)
231 if (parent ==
NULL || name ==
NULL || length == 0)
291 if (dentry ==
NULL || vnode ==
NULL)
#define MAX_NAME
Maximum length of names.
#define assert(expression)
EFI_PHYSICAL_ADDRESS buffer
static dentry_t * map[DENTRY_MAP_SIZE]
static dentry_t * dentry_get(const dentry_t *parent, const char *name, size_t length)
static void dentry_map_remove(dentry_t *dentry)
static void dentry_ctor(void *ptr)
static uint64_t dentry_hash(dentry_id_t parentId, const char *name, size_t length)
static uint64_t dentry_map_add(dentry_t *dentry)
static void dentry_free(dentry_t *dentry)
#define DENTRY_IS_DIR(dentry)
Check if the vnode associated with a dentry is a directory.
dentry_t * dentry_new(superblock_t *superblock, dentry_t *parent, const char *name)
Create a new dentry.
uint64_t dentry_generic_iterate(dentry_t *dentry, dir_ctx_t *ctx)
Helper function for a basic iterate.
uint64_t dentry_id_t
Dentry ID type.
dentry_t * dentry_lookup(dentry_t *parent, const char *name, size_t length)
Lookup a dentry for the given name without traversing mountpoints.
void dentry_make_positive(dentry_t *dentry, vnode_t *vnode)
Make a dentry positive by associating it with an vnode.
void dentry_remove(dentry_t *dentry)
Remove a dentry from the dentry cache.
bool dentry_iterate_dots(dentry_t *dentry, dir_ctx_t *ctx)
Helper function to iterate over the special entries "." and "..".
#define DENTRY_IS_POSITIVE(dentry)
Check if a dentry is positive.
#define DENTRY_IS_ROOT(dentry)
Macro to check if a dentry is the root entry in its filesystem.
dentry_t * dentry_rcu_get(const dentry_t *parent, const char *name, size_t length)
Get a dentry from the dentry cache in an RCU read-side critical section without traversing mountpoint...
#define CACHE_LINE
Cache line size in bytes.
void * cache_alloc(cache_t *cache)
Allocate an object from the cache.
#define CACHE_CREATE(_cache, _name, _size, _alignment, _ctor, _dtor)
Macro to create a cache initializer.
void mutex_release(mutex_t *mtx)
Releases a mutex.
void mutex_acquire(mutex_t *mtx)
Acquires a mutex, blocking until it is available.
#define RCU_READ_SCOPE()
RCU read-side critical section for the current scope.
void rcu_call_cache_free(void *arg)
Helper callback to free a cache object.
void rcu_call(rcu_entry_t *entry, rcu_callback_t func, void *arg)
Add a callback to be executed after a grace period.
static uint64_t seqlock_read_begin(seqlock_t *seqlock)
Begins a read operation on a sequence lock.
static void seqlock_write_release(seqlock_t *seqlock)
Releases the write lock of a sequence lock.
static bool seqlock_read_retry(seqlock_t *seqlock, uint64_t seq)
Checks if a read operation on a sequence lock needs to be retried.
#define SEQLOCK_CREATE()
Create a sequence lock initializer.
static void seqlock_write_acquire(seqlock_t *seqlock)
Acquires the write lock of a sequence lock.
uint64_t hash_object(const void *object, uint64_t length)
Hash a object.
#define REF_TRY(ptr)
Increment reference count, but only if the current count is not zero.
#define REF_COUNT(ptr)
Get current reference count.
#define REF(ptr)
Increment reference count.
static void ref_init(ref_t *ref, void *callback)
Initialize a reference counter.
#define UNREF(ptr)
Decrement reference count.
uint64_t vfs_id_get(void)
Generates a new unique ID, to be used for any VFS object.
#define ENOENT
No such file or directory.
#define EEXIST
File exists.
#define EINVAL
Invalid argument.
#define ENOMEM
Out of memory.
#define errno
Error number variable.
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
static void list_remove(list_entry_t *entry)
Removes a list entry from its current list.
static void list_push_back(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.
#define NULL
Pointer error value.
#define ERR
Integer error value.
#define RFLAGS_INTERRUPT_ENABLE
static uint64_t rflags_read(void)
#define atomic_fetch_add_explicit(object, operand, order)
#define atomic_init(obj, value)
#define atomic_fetch_sub_explicit(object, operand, order)
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
_PUBLIC int memcmp(const void *s1, const void *s2, size_t n)
_PUBLIC size_t strlen(const char *s)
uint64_t(* revalidate)(dentry_t *dentry)
Called when the dentry is looked up or retrieved from cache.
void(* cleanup)(dentry_t *dentry)
Called when the dentry is being freed.
Directory entry structure.
rcu_entry_t rcu
RCU entry for deferred cleanup.
char name[MAX_NAME]
The name of the dentry, immutable after creation.
list_entry_t otherEntry
Made available for use by any other subsystems for convenience.
dentry_t * parent
The parent dentry, will be itself if this is the root dentry, immutable after creation.
struct dentry * next
Next dentry in the dentry cache hash bucket.
vnode_t * vnode
Will be NULL if the dentry is negative, once positive it will never be modified.
superblock_t * superblock
list_entry_t siblingEntry
Directory context used to iterate over directory entries.
size_t index
An index that the filesystem can use for its own purposes.
size_t pos
The current position in the directory, can be used to skip entries.
bool(* emit)(dir_ctx_t *ctx, const char *name, vtype_t type)
Emit function.
Intrusive RCU head structure.
Reference counting structure.
const dentry_ops_t * dentryOps