Пример #1
0
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;
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
/**
 * 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;
}