From 3ef46ccf8c0cd69b0194325cd1d6ecb3d2b8645e Mon Sep 17 00:00:00 2001 From: Gurjant Kalsi Date: Mon, 16 Nov 2015 18:02:13 -0800 Subject: [spifs][fs] Bump dirents when files that they point to are deleted. --- lib/fs/spifs/spifs.c | 20 +++++++++++++++----- lib/fs/spifs/test/spifstest.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/fs/spifs/spifs.c b/lib/fs/spifs/spifs.c index 2b4df9b8..8f17b532 100644 --- a/lib/fs/spifs/spifs.c +++ b/lib/fs/spifs/spifs.c @@ -871,15 +871,25 @@ static status_t spifs_remove(fscookie *cookie, const char *name) spifs_file_t *file = find_file(spifs, name); - if (file) { - list_delete(&file->node); - free(file); - status = NO_ERROR; - } else { + if (!file) { status = ERR_NOT_FOUND; goto err; } + // Make sure there are no dirents open that point to the file that we're + // deleting. + dircookie *dcookie; + list_for_every_entry(&spifs->dcookies, dcookie, dircookie, node) { + if (dcookie->next_file == file) { + dcookie->next_file = list_next_type(&dcookie->fs->files, + &dcookie->next_file->node, + spifs_file_t, node); + } + } + + list_delete(&file->node); + free(file); + status = spifs_commit_toc(spifs); err: diff --git a/lib/fs/spifs/test/spifstest.c b/lib/fs/spifs/test/spifstest.c index ca3bb8b3..37c60daa 100644 --- a/lib/fs/spifs/test/spifstest.c +++ b/lib/fs/spifs/test/spifstest.c @@ -55,6 +55,7 @@ static bool test_rm_reclaim(const char *); static bool test_corrupt_toc(const char *); static bool test_write_with_offset(const char *); static bool test_read_write_big(const char *); +static bool test_rm_active_dirent(const char *); static test tests[] = { {&test_empty_after_format, "Test no files in ToC after format.", 1}, @@ -68,6 +69,7 @@ static test tests[] = { {&test_corrupt_toc, "Test that FS can be mounted with one corrupt ToC.", 1}, {&test_write_with_offset, "Test that files can be written to at an offset.", 1}, {&test_read_write_big, "Test that an unaligned ~10kb buffer can be written and read.", 1}, + {&test_rm_active_dirent, "Test that we can remove a file with an open dirent.", 1}, }; bool test_setup(const char *dev_name, uint32_t toc_pages) @@ -578,11 +580,51 @@ static bool test_read_write_big(const char *dev_name) } err: + success &= fs_close_file(handle) == NO_ERROR; + free(rbuf); free(wbuf); return success; } +static bool test_rm_active_dirent(const char *dev_name) +{ + filehandle *handle; + status_t status = fs_create_file(TEST_FILE_PATH, &handle, 0); + if (status != NO_ERROR) { + return false; + } + + status = fs_close_file(handle); + if (status != NO_ERROR) { + return false; + } + + dirhandle *dhandle; + status = fs_open_dir(MNT_PATH, &dhandle); + if (status != NO_ERROR) { + return false; + } + + // Dir handle should now be pointing to the only file in our FS. + status = fs_remove_file(TEST_FILE_PATH); + if (status != NO_ERROR) { + fs_close_dir(dhandle); + return false; + } + + bool success = true; + struct dirent *ent = malloc(sizeof(*ent)); + if (fs_read_dir(dhandle, ent) >= 0) { + success = false; + } + + success &= fs_close_dir(dhandle) == NO_ERROR; + free(ent); + + return success; +} + static int cmd_spifs(int argc, const cmd_args *argv) { if (argc < 3) { -- cgit v1.2.3