aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGurjant Kalsi <me@gurjantkalsi.com>2015-11-16 18:02:13 -0800
committerGurjant Kalsi <me@gurjantkalsi.com>2015-11-16 18:02:13 -0800
commit3ef46ccf8c0cd69b0194325cd1d6ecb3d2b8645e (patch)
tree1765656db73ce0b0bb52c0988c58c4be95f41c47 /lib
parente98e1657f47ac16f77af1ef16fa4b51e046e6ee2 (diff)
downloadcommon-3ef46ccf8c0cd69b0194325cd1d6ecb3d2b8645e.tar.gz
[spifs][fs] Bump dirents when files that they point to are deleted.
Diffstat (limited to 'lib')
-rw-r--r--lib/fs/spifs/spifs.c20
-rw-r--r--lib/fs/spifs/test/spifstest.c42
2 files changed, 57 insertions, 5 deletions
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) {