/* * Mount the file system. Obtain the root inode and send back its details. */ int fs_mount(dev_t __unused dev, unsigned int flags, struct fsdriver_node * root_node, unsigned int * res_flags) { struct inode *root; /* VTreeFS must not be mounted as a root file system. */ if (flags & REQ_ISROOT) return EINVAL; /* Get the root inode and increase its reference count. */ root = get_root_inode(); ref_inode(root); /* The system is now mounted. Call the initialization hook. */ if (vtreefs_hooks->init_hook != NULL) vtreefs_hooks->init_hook(); /* Return the root inode's properties. */ root_node->fn_ino_nr = get_inode_number(root); root_node->fn_mode = root->i_stat.mode; root_node->fn_size = root->i_stat.size; root_node->fn_uid = root->i_stat.uid; root_node->fn_gid = root->i_stat.gid; root_node->fn_dev = NO_DEV; *res_flags = RES_NOFLAGS; return OK; }
/* * Resolve a path string to an inode. */ int fs_lookup(ino_t dir_nr, char * name, struct fsdriver_node * node_details, int * is_mountpt) { struct inode *node, *child; int r; if ((node = find_inode(dir_nr)) == NULL) return EINVAL; if (!S_ISDIR(node->i_stat.mode)) return ENOTDIR; if (strlen(name) > PNAME_MAX) return ENAMETOOLONG; if (!strcmp(name, ".")) { /* Stay in the given directory. */ child = node; } else if (!strcmp(name, "..")) { /* Progress into the parent directory. */ if ((child = get_parent_inode(node)) == NULL) return ENOENT; /* deleted? should not be possible */ } else { /* Progress into a directory entry. Call the lookup hook, if * present, before doing the actual lookup. */ if (!is_inode_deleted(node) && vtreefs_hooks->lookup_hook != NULL) { r = vtreefs_hooks->lookup_hook(node, name, get_inode_cbdata(node)); if (r != OK) return r; } if ((child = get_inode_by_name(node, name)) == NULL) return ENOENT; } /* On success, open the resulting file and return its details. */ ref_inode(child); node_details->fn_ino_nr = get_inode_number(child); node_details->fn_mode = child->i_stat.mode; node_details->fn_size = child->i_stat.size; node_details->fn_uid = child->i_stat.uid; node_details->fn_gid = child->i_stat.gid; node_details->fn_dev = child->i_stat.dev; *is_mountpt = FALSE; return OK; }
/*===========================================================================* * fs_readsuper * *===========================================================================*/ int fs_readsuper(void) { /* This function gets the root inode and sends back its details. */ struct inode *root; /* Get the device number, for stat requests. */ fs_dev = fs_m_in.REQ_DEV; /* The VTreeFS must not be mounted as a root file system. */ if (fs_m_in.REQ_FLAGS & REQ_ISROOT) return EINVAL; /* Get the root inode and increase its reference count. */ root = get_root_inode(); ref_inode(root); /* The system is now mounted. Call the initialization hook. */ if (vtreefs_hooks->init_hook != NULL) vtreefs_hooks->init_hook(); /* Return the root inode's properties. */ fs_m_out.RES_INODE_NR = get_inode_number(root); fs_m_out.RES_MODE = root->i_stat.mode; fs_m_out.RES_FILE_SIZE_HI = 0; fs_m_out.RES_FILE_SIZE_LO = root->i_stat.size; fs_m_out.RES_UID = root->i_stat.uid; fs_m_out.RES_GID = root->i_stat.gid; fs_m_out.RES_DEV = NO_DEV; fs_m_out.RES_CONREQS = 1;/* We can handle only 1 request at a time */ fs_mounted = TRUE; return OK; }