summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extmod/vfs_fat.h2
-rw-r--r--extmod/vfs_fat_file.c3
m---------lib/tinyusb0
-rwxr-xr-xmain.c7
-rw-r--r--shared-bindings/storage/__init__.c23
-rw-r--r--shared-bindings/storage/__init__.h2
-rw-r--r--shared-module/storage/__init__.c5
-rw-r--r--supervisor/filesystem.h9
-rw-r--r--supervisor/flash.h1
-rw-r--r--supervisor/shared/filesystem.c32
-rw-r--r--supervisor/shared/flash.c20
-rw-r--r--supervisor/shared/usb/usb_msc_flash.c4
12 files changed, 68 insertions, 40 deletions
diff --git a/extmod/vfs_fat.h b/extmod/vfs_fat.h
index dd5e5ffcb..08b03d0d1 100644
--- a/extmod/vfs_fat.h
+++ b/extmod/vfs_fat.h
@@ -38,6 +38,8 @@
#define FSUSER_NO_FILESYSTEM (0x0008) // the block device has no filesystem on it
// Device is writable over USB and read-only to MicroPython.
#define FSUSER_USB_WRITABLE (0x0010)
+// Bit set when the above flag is checked before opening a file for write.
+#define FSUSER_CONCURRENT_WRITE_PROTECTED (0x0020)
typedef struct _fs_user_mount_t {
mp_obj_base_t base;
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index 690073ce4..6aad1884c 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -34,6 +34,7 @@
#include "py/mperrno.h"
#include "lib/oofatfs/ff.h"
#include "extmod/vfs_fat.h"
+#include "supervisor/filesystem.h"
// this table converts from FRESULT to POSIX errno
const byte fresult_to_errno_table[20] = {
@@ -187,7 +188,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
}
}
assert(vfs != NULL);
- if ((vfs->flags & FSUSER_USB_WRITABLE) != 0 && (mode & FA_WRITE) != 0) {
+ if ((mode & FA_WRITE) != 0 && !filesystem_is_writable_by_python(vfs)) {
mp_raise_OSError(MP_EROFS);
}
diff --git a/lib/tinyusb b/lib/tinyusb
-Subproject 29b49199beb8e9b5fead83e5cd36105f8746f1d
+Subproject 55874813f82157b7509729b1a0c66e68f86e2d0
diff --git a/main.c b/main.c
index 68ee66d02..f0913db6e 100755
--- a/main.c
+++ b/main.c
@@ -323,12 +323,12 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
mp_hal_delay_ms(1500);
// USB isn't up, so we can write the file.
- filesystem_writable_by_python(true);
+ filesystem_set_internal_writable_by_usb(false);
f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
// Switch the filesystem back to non-writable by Python now instead of later,
// since boot.py might change it back to writable.
- filesystem_writable_by_python(false);
+ filesystem_set_internal_writable_by_usb(true);
// Write version info to boot_out.txt.
mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO);
@@ -416,7 +416,8 @@ int __attribute__((used)) main(void) {
// By default our internal flash is readonly to local python code and
// writable over USB. Set it here so that boot.py can change it.
- filesystem_writable_by_python(false);
+ filesystem_set_internal_concurrent_write_protection(true);
+ filesystem_set_internal_writable_by_usb(true);
run_boot_py(safe_mode);
diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c
index 3484b9af8..d7af48df0 100644
--- a/shared-bindings/storage/__init__.c
+++ b/shared-bindings/storage/__init__.c
@@ -48,16 +48,18 @@
//| directly.
//|
-//| .. function:: mount(filesystem, mount_path, \*, readonly=False)
+//| .. function:: mount(filesystem, mount_path, \*, readonly=False, disable_concurrent_write_protection=False)
//|
//| Mounts the given filesystem object at the given path.
//|
//| This is the CircuitPython analog to the UNIX ``mount`` command.
//|
+//| :param bool readonly: True when the filesystem should be readonly to CircuitPython.
+//|
mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_readonly };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} },
+ { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
// parse args
@@ -77,7 +79,7 @@ mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_arg
mp_raise_ValueError(translate("filesystem must provide mount method"));
}
- common_hal_storage_mount(vfs_obj, mnt_str, mp_obj_is_true(args[ARG_readonly].u_obj));
+ common_hal_storage_mount(vfs_obj, mnt_str, args[ARG_readonly].u_bool);
return mp_const_none;
}
@@ -101,14 +103,21 @@ mp_obj_t storage_umount(mp_obj_t mnt_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(storage_umount_obj, storage_umount);
-//| .. function:: remount(mount_path, readonly=False)
+//| .. function:: remount(mount_path, readonly=False, *, disable_concurrent_write_protection=False)
//|
//| Remounts the given path with new parameters.
//|
+//| :param bool readonly: True when the filesystem should be readonly to CircuitPython.
+//| :param bool disable_concurrent_write_protection: When True, the check that makes sure the
+//| underlying filesystem data is written by one computer is disabled. Disabling the protection
+//| allows CircuitPython and a host to write to the same filesystem with the risk that the
+//| filesystem will be corrupted.
+//|
mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_readonly };
+ enum { ARG_readonly, ARG_disable_concurrent_write_protection };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_readonly, MP_ARG_BOOL | MP_ARG_REQUIRED, {.u_bool = false} },
+ { MP_QSTR_readonly, MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_disable_concurrent_write_protection, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
// get the mount point
@@ -118,7 +127,7 @@ mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- common_hal_storage_remount(mnt_str, args[ARG_readonly].u_bool);
+ common_hal_storage_remount(mnt_str, args[ARG_readonly].u_bool, args[ARG_disable_concurrent_write_protection].u_bool);
return mp_const_none;
}
diff --git a/shared-bindings/storage/__init__.h b/shared-bindings/storage/__init__.h
index 6a0cb9fc7..7851b9e29 100644
--- a/shared-bindings/storage/__init__.h
+++ b/shared-bindings/storage/__init__.h
@@ -33,7 +33,7 @@
void common_hal_storage_mount(mp_obj_t vfs_obj, const char* path, bool readonly);
void common_hal_storage_umount_path(const char* path);
void common_hal_storage_umount_object(mp_obj_t vfs_obj);
-void common_hal_storage_remount(const char* path, bool readonly);
+void common_hal_storage_remount(const char* path, bool readonly, bool disable_concurrent_write_protection);
mp_obj_t common_hal_storage_getmount(const char* path);
void common_hal_storage_erase_filesystem(void);
diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c
index f09edd785..215e1356a 100644
--- a/shared-module/storage/__init__.c
+++ b/shared-module/storage/__init__.c
@@ -143,7 +143,7 @@ mp_obj_t common_hal_storage_getmount(const char *mount_path) {
return storage_object_from_path(mount_path);
}
-void common_hal_storage_remount(const char *mount_path, bool readonly) {
+void common_hal_storage_remount(const char *mount_path, bool readonly, bool disable_concurrent_write_protection) {
if (strcmp(mount_path, "/") != 0) {
mp_raise_OSError(MP_EINVAL);
}
@@ -156,7 +156,8 @@ void common_hal_storage_remount(const char *mount_path, bool readonly) {
}
#endif
- supervisor_flash_set_usb_writable(readonly);
+ filesystem_set_internal_writable_by_usb(readonly);
+ filesystem_set_internal_concurrent_write_protection(!disable_concurrent_write_protection);
}
void common_hal_storage_erase_filesystem(void) {
diff --git a/supervisor/filesystem.h b/supervisor/filesystem.h
index eb9e65c09..76f235f47 100644
--- a/supervisor/filesystem.h
+++ b/supervisor/filesystem.h
@@ -29,9 +29,16 @@
#include <stdbool.h>
+#include "extmod/vfs_fat.h"
+
void filesystem_init(bool create_allowed, bool force_create);
void filesystem_flush(void);
-void filesystem_writable_by_python(bool writable);
bool filesystem_present(void);
+void filesystem_set_internal_writable_by_usb(bool usb_writable);
+void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection);
+void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable);
+void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection);
+bool filesystem_is_writable_by_python(fs_user_mount_t *vfs);
+bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs);
#endif // MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H
diff --git a/supervisor/flash.h b/supervisor/flash.h
index ae6a44fd0..edf43f4b1 100644
--- a/supervisor/flash.h
+++ b/supervisor/flash.h
@@ -37,7 +37,6 @@
#include "supervisor/internal_flash.h"
#endif
-void supervisor_flash_set_usb_writable(bool usb_writable);
void supervisor_flash_init(void);
uint32_t supervisor_flash_get_block_size(void);
uint32_t supervisor_flash_get_block_count(void);
diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c
index 3382d28be..0ef978ef2 100644
--- a/supervisor/shared/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -24,6 +24,8 @@
* THE SOFTWARE.
*/
+#include "supervisor/filesystem.h"
+
#include "extmod/vfs_fat.h"
#include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h"
@@ -92,16 +94,42 @@ void filesystem_flush(void) {
supervisor_flash_flush();
}
-void filesystem_writable_by_python(bool writable) {
+void filesystem_set_internal_writable_by_usb(bool writable) {
fs_user_mount_t *vfs = &_internal_vfs;
- if (!writable) {
+ filesystem_set_writable_by_usb(vfs, writable);
+}
+
+void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable) {
+ if (usb_writable) {
vfs->flags |= FSUSER_USB_WRITABLE;
} else {
vfs->flags &= ~FSUSER_USB_WRITABLE;
}
}
+bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) {
+ return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 ||
+ (vfs->flags & FSUSER_USB_WRITABLE) == 0;
+}
+
+bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs) {
+ return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 ||
+ (vfs->flags & FSUSER_USB_WRITABLE) != 0;
+}
+
+void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection) {
+ filesystem_set_concurrent_write_protection(&_internal_vfs, concurrent_write_protection);
+}
+
+void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection) {
+ if (concurrent_write_protection) {
+ vfs->flags |= FSUSER_CONCURRENT_WRITE_PROTECTED;
+ } else {
+ vfs->flags &= ~FSUSER_CONCURRENT_WRITE_PROTECTED;
+ }
+}
+
bool filesystem_present(void) {
return true;
}
diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c
index 8be21e5d0..6b1f24b4b 100644
--- a/supervisor/shared/flash.c
+++ b/supervisor/shared/flash.c
@@ -33,26 +33,6 @@
#define PART1_START_BLOCK (0x1)
-void supervisor_flash_set_usb_writable(bool usb_writable) {
- mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
- for (uint8_t i = 0; current_mount != NULL; i++) {
- if (i == VFS_INDEX) {
- break;
- }
- current_mount = current_mount->next;
- }
- if (current_mount == NULL) {
- return;
- }
- fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
-
- if (usb_writable) {
- vfs->flags |= FSUSER_USB_WRITABLE;
- } else {
- vfs->flags &= ~FSUSER_USB_WRITABLE;
- }
-}
-
// there is a singleton Flash object
const mp_obj_type_t supervisor_flash_type;
STATIC const mp_obj_base_t supervisor_flash_obj = {&supervisor_flash_type};
diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c
index 658aab0d8..f6f0fa9c3 100644
--- a/supervisor/shared/usb/usb_msc_flash.c
+++ b/supervisor/shared/usb/usb_msc_flash.c
@@ -34,6 +34,7 @@
#include "lib/oofatfs/ff.h"
#include "py/mpstate.h"
+#include "supervisor/filesystem.h"
#include "supervisor/shared/autoreload.h"
#define MSC_FLASH_BLOCK_SIZE 512
@@ -148,8 +149,7 @@ bool tud_msc_is_writable_cb(uint8_t lun) {
if (vfs == NULL) {
return false;
}
- if (vfs->writeblocks[0] == MP_OBJ_NULL ||
- (vfs->flags & FSUSER_USB_WRITABLE) == 0) {
+ if (vfs->writeblocks[0] == MP_OBJ_NULL || !filesystem_is_writable_by_usb(vfs)) {
return false;
}
return true;