Skip to content

Commit c117eff

Browse files
committed
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.
1 parent fadd6bb commit c117eff

File tree

6 files changed

+24
-19
lines changed

6 files changed

+24
-19
lines changed

extmod/vfs.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@
3434

3535
#if MICROPY_VFS
3636

37-
#if MICROPY_VFS_POSIX
38-
#include "extmod/vfs_posix.h"
39-
#endif
4037
#if MICROPY_VFS_FAT
4138
#include "extmod/vfs_fat.h"
4239
#endif
@@ -128,17 +125,11 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
128125
return MP_IMPORT_STAT_NO_EXIST;
129126
}
130127

131-
// Fast paths for known VFS types
132-
#if MICROPY_VFS_POSIX
133-
if (mp_obj_get_type(vfs->obj) == &mp_type_vfs_posix) {
134-
return mp_vfs_posix_import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
135-
}
136-
#endif
137-
#if MICROPY_VFS_FAT
138-
if (mp_obj_get_type(vfs->obj) == &mp_fat_vfs_type) {
139-
return fat_vfs_import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
128+
// If the mounted object has the VFS protocol, call its import_stat helper
129+
const mp_vfs_proto_t *proto = mp_obj_get_type(vfs->obj)->protocol;
130+
if (proto != NULL) {
131+
return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
140132
}
141-
#endif
142133

143134
// delegate to vfs.stat() method
144135
mp_obj_t path_o = mp_obj_new_str(path_out, strlen(path_out));

extmod/vfs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
#define BP_IOCTL_SEC_COUNT (4)
4646
#define BP_IOCTL_SEC_SIZE (5)
4747

48+
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
49+
typedef struct _mp_vfs_proto_t {
50+
mp_import_stat_t (*import_stat)(void *self, const char *path);
51+
} mp_vfs_proto_t;
52+
4853
typedef struct _mp_vfs_mount_t {
4954
const char *str; // mount point with leading /
5055
size_t len;

extmod/vfs_fat.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747

4848
#define mp_obj_fat_vfs_t fs_user_mount_t
4949

50-
mp_import_stat_t fat_vfs_import_stat(fs_user_mount_t *vfs, const char *path) {
50+
STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) {
51+
fs_user_mount_t *vfs = vfs_in;
5152
FILINFO fno;
5253
assert(vfs != NULL);
5354
FRESULT res = f_stat(&vfs->fatfs, path, &fno);
@@ -421,11 +422,17 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
421422
};
422423
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
423424

425+
STATIC const mp_vfs_proto_t fat_vfs_proto = {
426+
.import_stat = fat_vfs_import_stat,
427+
};
428+
424429
const mp_obj_type_t mp_fat_vfs_type = {
425430
{ &mp_type_type },
426431
.name = MP_QSTR_VfsFat,
427432
.make_new = fat_vfs_make_new,
433+
.protocol = &fat_vfs_proto,
428434
.locals_dict = (mp_obj_dict_t*)&fat_vfs_locals_dict,
435+
429436
};
430437

431438
#endif // MICROPY_VFS_FAT

extmod/vfs_fat.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ extern const mp_obj_type_t mp_fat_vfs_type;
5858
extern const mp_obj_type_t mp_type_vfs_fat_fileio;
5959
extern const mp_obj_type_t mp_type_vfs_fat_textio;
6060

61-
mp_import_stat_t fat_vfs_import_stat(struct _fs_user_mount_t *vfs, const char *path);
6261
MP_DECLARE_CONST_FUN_OBJ_3(fat_vfs_open_obj);
6362

6463
#endif // MICROPY_INCLUDED_EXTMOD_VFS_FAT_H

extmod/vfs_posix.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ STATIC mp_obj_t vfs_posix_fun1_helper(mp_obj_t self_in, mp_obj_t path_in, int (*
7171
return mp_const_none;
7272
}
7373

74-
mp_import_stat_t mp_vfs_posix_import_stat(mp_obj_vfs_posix_t *self, const char *path) {
74+
STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path) {
75+
mp_obj_vfs_posix_t *self = self_in;
7576
if (self->root_len != 0) {
7677
self->root.len = self->root_len;
7778
vstr_add_str(&self->root, path);
@@ -347,10 +348,15 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
347348
};
348349
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
349350

351+
STATIC const mp_vfs_proto_t vfs_posix_proto = {
352+
.import_stat = mp_vfs_posix_import_stat,
353+
};
354+
350355
const mp_obj_type_t mp_type_vfs_posix = {
351356
{ &mp_type_type },
352357
.name = MP_QSTR_VfsPosix,
353358
.make_new = vfs_posix_make_new,
359+
.protocol = &vfs_posix_proto,
354360
.locals_dict = (mp_obj_dict_t*)&vfs_posix_locals_dict,
355361
};
356362

extmod/vfs_posix.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,10 @@
2929
#include "py/lexer.h"
3030
#include "py/obj.h"
3131

32-
struct _mp_obj_vfs_posix_t;
33-
3432
extern const mp_obj_type_t mp_type_vfs_posix;
3533
extern const mp_obj_type_t mp_type_vfs_posix_fileio;
3634
extern const mp_obj_type_t mp_type_vfs_posix_textio;
3735

38-
mp_import_stat_t mp_vfs_posix_import_stat(struct _mp_obj_vfs_posix_t *self, const char *path_in);
3936
mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_obj_t mode_in);
4037

4138
#endif // MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H

0 commit comments

Comments
 (0)