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; }
/** * 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; }
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; }