1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-25 07:48:10 +00:00

core/sdcard: fix invalid state when filesystem mounting fails

This commit is contained in:
matejcik 2020-02-21 15:53:16 +01:00 committed by matejcik
parent f9097b16e6
commit e9c275c24f
2 changed files with 46 additions and 12 deletions

View File

@ -7,7 +7,7 @@ if False:
class FilesystemWrapper:
_INSTANCE = None # type: Optional[FilesystemWrapper]
def __init__(self, mounted: bool = True) -> None:
def __init__(self, mounted: bool) -> None:
self.fs = FatFS()
self.mounted = mounted
self.counter = 0
@ -20,7 +20,14 @@ class FilesystemWrapper:
raise RuntimeError # cannot request mounted and non-mounted instance at the same time
return cls._INSTANCE
def _deinit_instance(self) -> None:
if self.mounted:
self.fs.unmount()
sdcard.power_off()
FilesystemWrapper._INSTANCE = None
def __enter__(self) -> "FatFS":
try:
if self.counter <= 0:
self.counter = 0
sdcard.power_on()
@ -28,15 +35,15 @@ class FilesystemWrapper:
self.fs.mount()
self.counter += 1
return self.fs
except Exception:
self._deinit_instance()
raise
def __exit__(self, exc_type: Any, exc_val: Any, tb: Any) -> None:
self.counter -= 1
if self.counter <= 0:
self.counter = 0
if self.mounted:
self.fs.unmount()
sdcard.power_off()
FilesystemWrapper._INSTANCE = None
self._deinit_instance()
def get_filesystem(mounted: bool = True) -> FilesystemWrapper:

View File

@ -62,6 +62,33 @@ class TestTrezorSdcard(unittest.TestCase):
with sdcard.get_filesystem(mounted=True):
pass
def test_failed_mount(self):
# set up a filesystem first
with sdcard.get_filesystem(mounted=False) as fs:
fs.mkfs()
with sdcard.get_filesystem() as fs:
# the following should succeed
fs.listdir("/")
# trash filesystem
io.sdcard.power_on()
io.sdcard.write(0, bytes([0xFF] * io.sdcard.BLOCK_SIZE))
io.sdcard.power_off()
# mounting should now fail
with self.assertRaises(OSError):
with sdcard.get_filesystem() as fs:
pass
# it should be possible to create an unmounted instance
with sdcard.get_filesystem(mounted=False) as fs:
fs.mkfs()
# mounting should now succeed
with sdcard.get_filesystem() as fs:
fs.listdir("/")
if __name__ == "__main__":