extmod/vfs: Introduce a C-level VFS protocol, with fast import_stat.

Following other C-level protocols, this VFS protocol is added to help
abstract away implementation details of the underlying VFS in an efficient
way.  As a starting point, the import_stat function is put into this
protocol so that the VFS sub-system does not need to know about every VFS
implementation in order to do an efficient stat for importing files.

In the future it might be worth adding other functions to this protocol.
This commit is contained in:
Damien George 2018-06-06 14:24:23 +10:00
parent fadd6bbe43
commit c117effddd
6 changed files with 24 additions and 19 deletions

View File

@ -34,9 +34,6 @@
#if MICROPY_VFS
#if MICROPY_VFS_POSIX
#include "extmod/vfs_posix.h"
#endif
#if MICROPY_VFS_FAT
#include "extmod/vfs_fat.h"
#endif
@ -128,17 +125,11 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
// Fast paths for known VFS types
#if MICROPY_VFS_POSIX
if (mp_obj_get_type(vfs->obj) == &mp_type_vfs_posix) {
return mp_vfs_posix_import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
// If the mounted object has the VFS protocol, call its import_stat helper
const mp_vfs_proto_t *proto = mp_obj_get_type(vfs->obj)->protocol;
if (proto != NULL) {
return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
}
#endif
#if MICROPY_VFS_FAT
if (mp_obj_get_type(vfs->obj) == &mp_fat_vfs_type) {
return fat_vfs_import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
}
#endif
// delegate to vfs.stat() method
mp_obj_t path_o = mp_obj_new_str(path_out, strlen(path_out));

View File

@ -45,6 +45,11 @@
#define BP_IOCTL_SEC_COUNT (4)
#define BP_IOCTL_SEC_SIZE (5)
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
typedef struct _mp_vfs_proto_t {
mp_import_stat_t (*import_stat)(void *self, const char *path);
} mp_vfs_proto_t;
typedef struct _mp_vfs_mount_t {
const char *str; // mount point with leading /
size_t len;

View File

@ -47,7 +47,8 @@
#define mp_obj_fat_vfs_t fs_user_mount_t
mp_import_stat_t fat_vfs_import_stat(fs_user_mount_t *vfs, const char *path) {
STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) {
fs_user_mount_t *vfs = vfs_in;
FILINFO fno;
assert(vfs != NULL);
FRESULT res = f_stat(&vfs->fatfs, path, &fno);
@ -421,11 +422,17 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
STATIC const mp_vfs_proto_t fat_vfs_proto = {
.import_stat = fat_vfs_import_stat,
};
const mp_obj_type_t mp_fat_vfs_type = {
{ &mp_type_type },
.name = MP_QSTR_VfsFat,
.make_new = fat_vfs_make_new,
.protocol = &fat_vfs_proto,
.locals_dict = (mp_obj_dict_t*)&fat_vfs_locals_dict,
};
#endif // MICROPY_VFS_FAT

View File

@ -58,7 +58,6 @@ extern const mp_obj_type_t mp_fat_vfs_type;
extern const mp_obj_type_t mp_type_vfs_fat_fileio;
extern const mp_obj_type_t mp_type_vfs_fat_textio;
mp_import_stat_t fat_vfs_import_stat(struct _fs_user_mount_t *vfs, const char *path);
MP_DECLARE_CONST_FUN_OBJ_3(fat_vfs_open_obj);
#endif // MICROPY_INCLUDED_EXTMOD_VFS_FAT_H

View File

@ -71,7 +71,8 @@ STATIC mp_obj_t vfs_posix_fun1_helper(mp_obj_t self_in, mp_obj_t path_in, int (*
return mp_const_none;
}
mp_import_stat_t mp_vfs_posix_import_stat(mp_obj_vfs_posix_t *self, const char *path) {
STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path) {
mp_obj_vfs_posix_t *self = self_in;
if (self->root_len != 0) {
self->root.len = self->root_len;
vstr_add_str(&self->root, path);
@ -347,10 +348,15 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
STATIC const mp_vfs_proto_t vfs_posix_proto = {
.import_stat = mp_vfs_posix_import_stat,
};
const mp_obj_type_t mp_type_vfs_posix = {
{ &mp_type_type },
.name = MP_QSTR_VfsPosix,
.make_new = vfs_posix_make_new,
.protocol = &vfs_posix_proto,
.locals_dict = (mp_obj_dict_t*)&vfs_posix_locals_dict,
};

View File

@ -29,13 +29,10 @@
#include "py/lexer.h"
#include "py/obj.h"
struct _mp_obj_vfs_posix_t;
extern const mp_obj_type_t mp_type_vfs_posix;
extern const mp_obj_type_t mp_type_vfs_posix_fileio;
extern const mp_obj_type_t mp_type_vfs_posix_textio;
mp_import_stat_t mp_vfs_posix_import_stat(struct _mp_obj_vfs_posix_t *self, const char *path_in);
mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_obj_t mode_in);
#endif // MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H