#pragma once #include "fs.h" #include "stdint.h" #include "stddef.h" /** * Those structures aimes to represent VFS directory entries in memory. * It's the equivalent of the Linux dentry or SimpleOs sos_fs_nscache_node. */ /** * Path or Pascal String * */ struct pstr { size_t len; const char *name; }; #define PSTR_INIT(n, l) \ { \ .len = l, .name = n \ } #define PSTR_STATIC_INIT(n) \ { \ .len = sizeof(n) - 1, .name = n \ } /** * @brief Structure representing a file system entry. * * This structure holds information about a file system entry, * including its name, associated inode, relationships within * the file system hierarchy, and reference count. */ struct fs_entry { struct pstr name; struct inode *node; struct fs_entry *parent; // parent directory struct fs_entry *mountpoint; // if this is a mounted fs, point to mountpoint struct fs_entry *mountedFs; // Fs possibly mounted on this fsEntry struct fs_entry *childs; // point to the list of children struct fs_entry *nextSiblings, *prevSiblings; // Sibling at the same level uint ref; // reference counter }; /** * @brief Splits a pstr path into upper and lower components. * * This function takes a path and splits it into an upper component * (the first segment of the path) and a lower component (the rest of the path). * * @param path Pointer to the input pstr structure representing the path. * @param upper Pointer to the pstr structure to store the upper component. * @param lower Pointer to the pstr structure to store the lower component. * @return bool_t Returns true if there is a lower component, false otherwise. */ bool_t pstringSplipPath(struct pstr *path, struct pstr *upper, struct pstr *lower); /** * @brief Compares two pstr structures to check if they are equal. * * This function compares the length and the content of the strings * in the two provided pstr structures. * * @param a Pointer to the first pstr structure. * @param b Pointer to the second pstr structure. * @return int Returns 1 if the structures are equal, 0 otherwise. */ bool_t pstringIsEq(const struct pstr *p1, const struct pstr *p2); /** * @brief Checks if a pstr structure matches a given C string. * * @param s Pointer to the null-terminated C string to compare. * @return bool_t Returns true if the pstr matches the C string, false otherwise. */ bool_t pstringIsStr(const struct pstr *p, char *s); /** * @brief Increments the reference count of a file system entry. * * This function increments the reference count of the given file system * entry. It is typically used to manage the lifecycle of file system * entries, ensuring that they are not prematurely deallocated. * * @param entry Pointer to the fsEntry structure whose reference count will be incremented. * @return int Returns 0 on success. */ int fsEntryRef(struct fs_entry *entry); /** * @brief Decrements the reference count of a file system entry. * * This function decrements the reference count of the given file system * entry. It is typically used to manage the lifecycle of file system * entries, ensuring that they are not prematurely deallocated. * * @param entry Pointer to the fsEntry structure whose reference count will be decremented. * @return int Returns 0 on success. */ int fsEntryUnref(struct fs_entry **entry); /** * @brief Allocates and initializes a new fsEntry. * * This function allocates memory for a new `fsEntry` structure, initializes * it with the provided name and inode, and adds it to the parent's list of children. * * @param parent Pointer to the parent `fsEntry` structure. Can be NULL if the new entry has no parent. * @param name Pointer to the `pstr` structure representing the name of the new entry. Can be NULL. * @param inode Pointer to the `inode` structure associated with the new entry. * * @return struct fsEntry* Pointer to the newly allocated `fsEntry` structure, or NULL if allocation fails. * * @note The reference count of the new entry is set to 1. * @note If a parent is provided, the new entry is added to the parent's list of children and the parent's reference count is incremented. * @note The inode's reference count is incremented. */ struct fs_entry *fsEntryAlloc(struct fs_entry *parent, const struct pstr *name, struct inode *inode); /** * @brief Looks up an entry in the file system. * * This function searches for a specified entry within the children * of a given directory entry. The search is limited to the entries * that are already in memory. If the entry is not found, it indicates * that the entry must be resolved using disk accesses. * * @param entry The node in which we are looking for the entry. * @param name The name of the entry we are looking for. * @param root The base node beyond which lookup must not go (to * support chroot): a kind of "barrier". * @param result The fsEntry for the given entry (set only when * the return value is 0). * * @return int Returns 0 if the entry is found, otherwise returns a non-zero error code. * -ENOENT if the entry could not be found in the entry directory. * * @note The mountpoints are followed. * @note result is a NEW reference to the node. It should be unreferenced when unused. */ int fsEntryLookup(struct fs_entry *entry, const struct pstr *name, const struct fs_entry *root, struct fs_entry **result); /** * @brief Setup the fsEntry subsystem * */ int fsEntrySetup(void); /** * @brief Mounts a file system entry at a specified mount point. * * This function mounts a file system entry (`mounted`) at a specified mount point (`mountpoint`). * It updates the `mountedFs` field of the mount point and the `mountpoint` field of the mounted entry. * * @param mountpoint Pointer to the `fsEntry` structure representing the mount point. * @param mounted Pointer to the `fsEntry` structure representing the file system entry to be mounted. * * @return int Returns 0 on success, or -EBUSY if either the mount point is already occupied or the mounted entry is already mounted. * * @note The reference counts of both the mount point and the mounted entry are incremented. */ int fsEntryMount(struct fs_entry *mountpoint, struct fs_entry *mounted); /** * @brief Unmounts a file system entry. * * This function unmounts a file system entry (`mounted`) from its mount point. * It updates the `mountedFs` field of the mount point and the `mountpoint` field of the mounted entry. * * @param mounted Pointer to the `fsEntry` structure representing the file system entry to be unmounted. * * @return int Returns 0 on success, -ENOENT if the entry is not mounted, or -EBUSY if the entry is busy. * * @note The unmount operation fails if the mounted entry has children or other references. * @note The reference counts of both the mount point and the mounted entry are decremented. */ int fsEntryUmount(struct fs_entry *mounted);