Merge pull request #1584 from tannewt/disable_concurrent_write_protection
Add option to disable the concurrent write protection
This commit is contained in:
commit
d218069f03
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 29b49199beb8e9b5fead83e5cd36105f8746f1d7
|
||||
Subproject commit 55874813f82157b7509729b1a0c66e68f86e2d07
|
7
main.c
7
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);
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ SRC_C = \
|
|||
alloc.c \
|
||||
coverage.c \
|
||||
fatfs_port.c \
|
||||
supervisor/stub/filesystem.c \
|
||||
supervisor/stub/serial.c \
|
||||
supervisor/stub/stack.c \
|
||||
supervisor/shared/translate.c \
|
||||
|
|
|
@ -54,10 +54,12 @@
|
|||
//|
|
||||
//| 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -26,13 +26,17 @@
|
|||
|
||||
#include "supervisor/filesystem.h"
|
||||
|
||||
void filesystem_init(void) {
|
||||
void filesystem_init(bool create_allowed, bool force_create) {
|
||||
(void) create_allowed;
|
||||
(void) force_create;
|
||||
}
|
||||
|
||||
void filesystem_flush(void) {
|
||||
}
|
||||
|
||||
void filesystem_writable_by_python(bool writable) {
|
||||
bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) {
|
||||
(void) vfs;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool filesystem_present(void) {
|
||||
|
|
Loading…
Reference in New Issue