vnode_t * fs_create_pseudofs_root(fs_t * newfs, int majornum) { int err; vnode_t * rootnode; /* * We use a little trick here and create a temporary vnode that will be * destroyed after succesful mount. */ rootnode = kzalloc(sizeof(vnode_t)); if (!rootnode) return NULL; /* Temp root dir */ rootnode->vn_next_mountpoint = rootnode; vrefset(rootnode, 1); mtx_init(&rootnode->vn_lock, VN_LOCK_TYPE, VN_LOCK_OPT); err = fs_mount(rootnode, "", "ramfs", 0, "", 1); if (err) { KERROR(KERROR_ERR, "Unable to create a pseudo fs root vnode for %s (%i)\n", newfs->fsname, err); return NULL; } rootnode = rootnode->vn_next_mountpoint; kfree(rootnode->vn_prev_mountpoint); rootnode->vn_prev_mountpoint = rootnode; rootnode->vn_next_mountpoint = rootnode; newfs->fs_majornum = majornum; newfs->sblist_head = rootnode->sb->fs->sblist_head; rootnode->sb->fs = newfs; rootnode->sb->vdev_id = DEV_MMTODEV(majornum, 0); return rootnode; }
static void mount_tmp_rootfs(void) { const char failed[] = "Failed to mount rootfs"; vnode_t * tmp = NULL; struct proc_info * kernel_proc; int ret; kernel_proc = proc_ref(0); if (!kernel_proc) { panic(failed); } /* No need to keep the ref because it won't go away. */ proc_unref(kernel_proc); /* Root dir */ tmp = kzalloc_crit(sizeof(vnode_t)); kernel_proc->croot = tmp; kernel_proc->croot->vn_next_mountpoint = kernel_proc->croot; kernel_proc->croot->vn_prev_mountpoint = kernel_proc->croot; mtx_init(&tmp->vn_lock, MTX_TYPE_SPIN, 0); vrefset(kernel_proc->croot, 2); ret = fs_mount(kernel_proc->croot, "", "ramfs", 0, "", 1); if (ret) { KERROR(KERROR_ERR, "%s : %i\n", failed, ret); goto out; } kernel_proc->croot->vn_next_mountpoint->vn_prev_mountpoint = kernel_proc->croot->vn_next_mountpoint; kernel_proc->croot = kernel_proc->croot->vn_next_mountpoint; kernel_proc->cwd = kernel_proc->croot; out: kfree(tmp); }
static vnode_t * create_root(struct fatfs_sb * fatfs_sb) { char * rootpath; long vn_hash; struct fatfs_inode * in; int err; rootpath = kzalloc(2); if (!rootpath) return NULL; vn_hash = hash32_str(rootpath, 0); err = create_inode(&in, fatfs_sb, rootpath, vn_hash, O_DIRECTORY | O_RDWR); if (err) { KERROR(KERROR_ERR, "Failed to init a root vnode for fatfs (%d)\n", err); return NULL; } in->in_fpath = rootpath; vrefset(&in->in_vnode, 1); return &in->in_vnode; }
/** * Create a inode. * @param fpath won't be duplicated. * @param oflags O_CREAT, O_DIRECTORY, O_RDONLY, O_WRONLY and O_RDWR * currently supported. * O_WRONLY/O_RDWR creates in write mode if possible, so this * should be always verified with stat. */ static int create_inode(struct fatfs_inode ** result, struct fatfs_sb * sb, char * fpath, long vn_hash, int oflags) { struct fatfs_inode * in = NULL; FILINFO fno; vnode_t * vn; vnode_t * xvp; mode_t vn_mode; ino_t inum; int err = 0, retval = 0; #ifdef configFATFS_DEBUG KERROR(KERROR_DEBUG, "create_inode(fpath \"%s\", vn_hash %u)\n", fpath, (uint32_t)vn_hash); #endif in = kzalloc(sizeof(struct fatfs_inode)); if (!in) { retval = -ENOMEM; goto fail; } in->in_fpath = fpath; vn = &in->in_vnode; in->open_count = ATOMIC_INIT(0); memset(&fno, 0, sizeof(fno)); if (oflags & O_DIRECTORY) { /* O_DIRECTORY was specified. */ /* TODO Maybe get mp stat? */ fno.fattrib = AM_DIR; } else if (oflags & O_CREAT) { if (sb->sb.mode_flags & MNT_RDONLY) return -EROFS; } else { err = f_stat(&sb->ff_fs, fpath, &fno); if (err) { retval = fresult2errno(err); goto fail; } } /* Try open */ if (fno.fattrib & AM_DIR) { /* it's a directory */ vn_mode = S_IFDIR; err = f_opendir(&in->dp, &sb->ff_fs, in->in_fpath); if (err) { #ifdef configFATFS_DEBUG KERROR(KERROR_DEBUG, "Can't open a dir (err: %d)\n", err); #endif retval = fresult2errno(err); goto fail; } inum = in->dp.ino; } else { /* it's a file */ unsigned char fomode = 0; fomode |= (oflags & O_CREAT) ? FA_OPEN_ALWAYS : FA_OPEN_EXISTING; /* The kernel should always have RW if possible. */ if (sb->sb.mode_flags & MNT_RDONLY) { fomode |= FA_READ; } else { fomode |= FA_READ | FA_WRITE; } vn_mode = S_IFREG; err = f_open(&in->fp, &sb->ff_fs, in->in_fpath, fomode); if (err) { #ifdef configFATFS_DEBUG KERROR(KERROR_DEBUG, "Can't open a file (err: %d)\n", err); #endif retval = fresult2errno(err); goto fail; } inum = in->fp.ino; } #ifdef configFATFS_DEBUG if (oflags & O_CREAT) KERROR(KERROR_DEBUG, "ff: Create & open ok\n"); else KERROR(KERROR_DEBUG, "ff: Open ok\n"); #endif init_fatfs_vnode(vn, inum, vn_mode, vn_hash, &(sb->sb)); /* Insert to the cache */ err = vfs_hash_insert(vn, vn_hash, &xvp, fatfs_vncmp, fpath); if (err) { retval = -ENOMEM; goto fail; } if (xvp) { /* TODO No idea what to do now */ KERROR(KERROR_WARN, "create_inode(): Found it during insert: \"%s\"\n", fpath); } #ifdef configFATFS_DEBUG KERROR(KERROR_DEBUG, "create_inode(): ok\n"); #endif *result = in; vrefset(vn, 1); /* Make ref for the caller. */ return 0; fail: #ifdef configFATFS_DEBUG KERROR(KERROR_DEBUG, "create_inode(): retval %i\n", retval); #endif kfree(in); return retval; }