예제 #1
0
파일: devfs.c 프로젝트: Zeke-OS/zeke
int devfs_lookup(vnode_t ** result, char * str)
{
    vnode_t * vnode = NULL;
    const int oflags = 0;
    int err;

    err = lookup_vnode(&vnode, vn_devfs, str, oflags);
    if (err)
        return err;
    if (result)
        *result = vnode;
    else
        vrele(vnode);
    return 0;
}
예제 #2
0
파일: fatfs.c 프로젝트: htchiang/zeke
/**
 * Mount a new fatfs.
 * @param mode      mount flags.
 * @param param     contains optional mount parameters.
 * @param parm_len  length of param string.
 * @param[out] sb   Returns the superblock of the new mount.
 * @return error code, -errno.
 */
static int fatfs_mount(const char * source, uint32_t mode,
                       const char * parm, int parm_len,
                       struct fs_superblock ** sb)
{
    static dev_t fatfs_vdev_minor;
    struct fatfs_sb * fatfs_sb = NULL;
    vnode_t * vndev;
    char pdrv;
    int err, retval = 0;

    /* Get device vnode */
    err = lookup_vnode(&vndev, curproc->croot, source, 0);
    if (err) {
#ifdef configFATFS_DEBUG
        KERROR(KERROR_DEBUG, "fatfs source not found\n");
#endif
        return err;
    }
    if (!S_ISBLK(vndev->vn_mode))
        return -ENOTBLK;

    /* Allocate superblock */
    fatfs_sb = kzalloc(sizeof(struct fatfs_sb));
    if (!fatfs_sb)
        return -ENOMEM;

    fs_fildes_set(&fatfs_sb->ff_devfile, vndev, O_RDWR);
    fatfs_sb->sb.vdev_id = DEV_MMTODEV(VDEV_MJNR_FATFS, fatfs_vdev_minor++);

    /* Insert sb to fatfs_sb_arr lookup array */
    fatfs_sb_arr[DEV_MINOR(fatfs_sb->sb.vdev_id)] = fatfs_sb;

    /* Mount */
    pdrv = (char)DEV_MINOR(fatfs_sb->sb.vdev_id);
    err = f_mount(&fatfs_sb->ff_fs, 0);
    if (err) {
#ifdef configFATFS_DEBUG
        KERROR(KERROR_DEBUG, "Can't init a work area for FAT (%d)\n", err);
#endif
        retval = fresult2errno(err);
        goto fail;
    }
#ifdef configFATFS_DEBUG
    KERROR(KERROR_DEBUG, "Initialized a work area for FAT\n");
#endif

#if (_FS_NOFSINFO == 0) /* Commit full scan of free clusters */
    DWORD nclst;

    f_getfree(&fatfs_sb->ff_fs, &nclst);
#endif

    /* Init super block */
    fs_init_superblock(&fatfs_sb->sb, &fatfs_fs);
    /* TODO Detect if target dev is rdonly */
    fatfs_sb->sb.mode_flags = mode;
    fatfs_sb->sb.root = create_root(fatfs_sb);
    fatfs_sb->sb.sb_dev = vndev;
    fatfs_sb->sb.sb_hashseed = fatfs_sb->sb.vdev_id;
    /* Function pointers to superblock methods */
    fatfs_sb->sb.get_vnode = NULL; /* Not implemented for FAT. */
    fatfs_sb->sb.delete_vnode = fatfs_delete_vnode;
    fatfs_sb->sb.umount = NULL;

    if (!fatfs_sb->sb.root) {
        KERROR(KERROR_ERR, "Root of fatfs not found\n");

        return -EIO;
    }
    fs_insert_superblock(&fatfs_fs, &fatfs_sb->sb);

fail:
    if (retval) {
        fatfs_sb_arr[DEV_MINOR(fatfs_sb->sb.vdev_id)] = NULL;
        kfree(fatfs_sb);
    }

    *sb = &fatfs_sb->sb;
    return retval;
}
예제 #3
0
파일: fs_syscall.c 프로젝트: tjjh89017/zeke
static int sys_filestat(void * user_args)
{
    struct _fs_stat_args * args = 0;
    vnode_t * vnode;
    struct stat stat_buf;
    int err, retval = -1;

    err = copyinstruct(user_args, (void **)(&args),
            sizeof(struct _fs_stat_args),
            GET_STRUCT_OFFSETS(struct _fs_stat_args,
                path, path_len));
    if (err) {
        set_errno(-err);
        goto out;
    }

    if (!useracc(args->buf, sizeof(struct stat), VM_PROT_WRITE)) {
        set_errno(EFAULT);
        goto out;
    }

    /* Validate path string */
    if (!strvalid(args->path, args->path_len)) {
        set_errno(ENAMETOOLONG);
        goto out;
    }

    if (args->flags & AT_FDARG) { /* by fildes */
        file_t * fildes;
        /* Note: AT_SYMLINK_NOFOLLOW == O_NOFOLLOW */
        const int ofalgs = (args->flags & AT_SYMLINK_NOFOLLOW);

        fildes = fs_fildes_ref(curproc->files, args->fd, 1);
        if (!fildes) {
            set_errno(EBADF);
            goto out;
        }

        err = fildes->vnode->vnode_ops->stat(fildes->vnode, &stat_buf);
        if (!err) {
            /* Check if fildes was opened with O_SEARCH or if not then if we
             * have a permission to search by file permissions. */
            if (fildes->oflags & O_SEARCH || chkperm_cproc(&stat_buf, O_EXEC))
                err = lookup_vnode(&vnode, fildes->vnode, args->path, ofalgs);
            else /* No permission to search */
                err = -EACCES;
        }

        fs_fildes_ref(curproc->files, args->fd, -1);
        if (err) { /* Handle previous error */
            set_errno(-err);
            goto out;
        }
    } else { /* search by path */
        if (fs_namei_proc(&vnode, -1, (char *)args->path, AT_FDCWD)) {
            set_errno(ENOENT);
            goto out;
        }
    }

    if ((args->flags & AT_FDARG) &&
        (args->flags & O_EXEC)) { /* Get stat of given fildes, which we have
                                   * have in stat_buf. */
        goto ready;
    }

    err = vnode->vnode_ops->stat(vnode, &stat_buf);
    if (err) {
        set_errno(-err);
        goto out;
    }

ready:
    copyout(&stat_buf, args->buf, sizeof(struct stat));
    retval = 0;
out:
    freecpystruct(args);
    return retval;
}