/* @brief Perform mount of the root file system * @param dev Path to the block device (e.g. /dev/sda1) * @param fs_type Name of the file system driver * * @return Negative error number * @retval 0 Ok * @revtal -ENOENT File system driver not found */ static int rootfs_mount(void) { const char *dev, *fs_type; struct dumb_fs_driver *fsdrv; struct block_dev *bdev = NULL; dev = OPTION_STRING_GET(bdev); fs_type = OPTION_STRING_GET(fstype); assert(fs_type); fsdrv = dumb_fs_driver_find(fs_type); if (fsdrv == NULL) return -ENOENT; if (dev) { block_devs_init(); bdev = block_dev_find(dev); } dvfs_update_root(); if (-1 == dvfs_mount(bdev, "/", (char *) fs_type, 0)) { return -errno; } return 0; }
static int fuse_fill_dentry(struct super_block *sb, char *dest) { struct dentry *d; struct lookup lookup; dvfs_lookup(dest, &lookup); if (lookup.item == NULL) return -ENOENT; assert(lookup.item->flags & S_IFDIR); if (!(lookup.item->flags & DVFS_DIR_VIRTUAL)) { /* Hide dentry of the directory */ dlist_del(&lookup.item->children_lnk); dvfs_cache_del(lookup.item); d = dvfs_alloc_dentry(); dentry_fill(sb, NULL, d, lookup.parent); strcpy(d->name, lookup.item->name); } else { d = lookup.item; /* TODO free related inode */ } d->flags |= S_IFDIR | DVFS_MOUNT_POINT; d->d_sb = sb, d->d_ops = sb ? sb->sb_dops : NULL, dentry_ref_inc(d); sb->root = d; d->d_inode = dvfs_alloc_inode(sb); *d->d_inode = (struct inode ) { .flags = S_IFDIR, .i_ops = sb->sb_iops, .i_sb = sb, .i_dentry = d, }; return 0; } static void *fuse_module_mount_process(void *arg) { struct fuse_mount_params *params; const struct cmd *cmd; struct super_block *sb; struct dumb_fs_driver *fs_drv; char *argv[3]; char argv0[0x20]; char argv1[0x20]; char argv2[0x20]; params = arg; cmd = cmd_lookup(params->fm->fuse_module_cmd_mount); assert(cmd); fs_drv = dumb_fs_driver_find(params->fm->fuse_module_cmd_mount); assert(fs_drv); strncpy(argv0, params->fm->fuse_module_cmd_mount, sizeof(argv0)); strncpy(argv1, params->dev, sizeof(argv1)); strncpy(argv2, params->dest, sizeof(argv2)); argv[0] = argv0; argv[1] = argv1; argv[2] = argv2; params->fm = NULL; sb = dvfs_alloc_sb(fs_drv, NULL); fuse_fill_dentry(sb, argv2); cmd_exec(cmd, 3, argv); /* will not return */ return NULL; } int fuse_module_mount(struct fuse_module *fm, char *dev, char *dest) { int res; struct fuse_mount_params params = {fm, dev, dest}; assert(fm); res = new_task(fm->fuse_module_cmd_mount, fuse_module_mount_process, ¶ms); if (res) { return res; } while (params.fm) { sleep(0); } return 0; }