diff options
| author | Damien George <damien@micropython.org> | 2020-07-29 01:01:48 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2020-08-25 17:35:19 +1000 |
| commit | 2acc087880de39d7e17abc9344b8d2faba3478dd (patch) | |
| tree | e7a8e21a14bad32ef1b78b351c8d754962e18d1c /extmod/vfs_lfsx.c | |
| parent | ee50a6effebf315c38d4a129dc9f65ee722eb5b6 (diff) | |
extmod/vfs_lfs: Add mtime support to littlefs files.
This commit adds support for modification time of files on littlefs v2
filesystems, using file attributes. For some background see issue #6114.
Features/properties of this implementation:
- Only supported on littlefs2 (not littlefs1).
- Uses littlefs2's general file attributes to store the timestamp.
- The timestamp is 64-bits and stores nanoseconds since 1970/1/1 (if the
range to the year 2554 is not enough then additional bits can be added to
this timestamp by adding another file attribute).
- mtime is enabled by default but can be disabled in the constructor, eg:
uos.mount(uos.VfsLfs2(bdev, mtime=False), '/flash')
- It's fully backwards compatible, existing littlefs2 filesystems will work
without reformatting and timestamps will be added transparently to
existing files (once they are opened for writing).
- Files without timestamps will open correctly, and stat will just return 0
for their timestamp.
- mtime can be disabled or enabled each mount time and timestamps will only
be updated if mtime is enabled (otherwise they will be untouched).
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'extmod/vfs_lfsx.c')
| -rw-r--r-- | extmod/vfs_lfsx.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index 24816433b..511b741b0 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2019 Damien P. George + * Copyright (c) 2019-2020 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +34,7 @@ #include "py/objstr.h" #include "py/mperrno.h" #include "extmod/vfs.h" +#include "lib/timeutils/timeutils.h" STATIC int MP_VFS_LFSx(dev_ioctl)(const struct LFSx_API (config) * c, int cmd, int arg, bool must_return_int) { mp_obj_t ret = mp_vfs_blockdev_ioctl(c->context, cmd, arg); @@ -120,6 +121,9 @@ STATIC mp_obj_t MP_VFS_LFSx(make_new)(const mp_obj_type_t * type, size_t n_args, self->base.type = type; vstr_init(&self->cur_dir, 16); vstr_add_byte(&self->cur_dir, '/'); + #if LFS_BUILD_VERSION == 2 + self->enable_mtime = args[LFS_MAKE_ARG_mtime].u_bool; + #endif MP_VFS_LFSx(init_config)(self, args[LFS_MAKE_ARG_bdev].u_obj, args[LFS_MAKE_ARG_readsize].u_int, args[LFS_MAKE_ARG_progsize].u_int, args[LFS_MAKE_ARG_lookahead].u_int); int ret = LFSx_API(mount)(&self->lfs, &self->config); @@ -352,6 +356,19 @@ STATIC mp_obj_t MP_VFS_LFSx(stat)(mp_obj_t self_in, mp_obj_t path_in) { mp_raise_OSError(-ret); } + mp_uint_t mtime = 0; + #if LFS_BUILD_VERSION == 2 + uint8_t mtime_buf[8]; + lfs2_ssize_t sz = lfs2_getattr(&self->lfs, path, LFS_ATTR_MTIME, &mtime_buf, sizeof(mtime_buf)); + if (sz == sizeof(mtime_buf)) { + uint64_t ns = 0; + for (size_t i = sizeof(mtime_buf); i > 0; --i) { + ns = ns << 8 | mtime_buf[i - 1]; + } + mtime = timeutils_seconds_since_2000_from_nanoseconds_since_1970(ns); + } + #endif + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); t->items[0] = MP_OBJ_NEW_SMALL_INT(info.type == LFSx_MACRO(_TYPE_REG) ? MP_S_IFREG : MP_S_IFDIR); // st_mode t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino @@ -360,9 +377,9 @@ STATIC mp_obj_t MP_VFS_LFSx(stat)(mp_obj_t self_in, mp_obj_t path_in) { t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid t->items[6] = mp_obj_new_int_from_uint(info.size); // st_size - t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // st_atime - t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // st_mtime - t->items[9] = MP_OBJ_NEW_SMALL_INT(0); // st_ctime + t->items[7] = MP_OBJ_NEW_SMALL_INT(mtime); // st_atime + t->items[8] = MP_OBJ_NEW_SMALL_INT(mtime); // st_mtime + t->items[9] = MP_OBJ_NEW_SMALL_INT(mtime); // st_ctime return MP_OBJ_FROM_PTR(t); } |
