From cb29b1e1a475795fbda0800a362b0b694a2892a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Bia=C5=82ow=C4=85s?= Date: Thu, 19 Aug 2021 14:43:19 +0200 Subject: [PATCH] dummyfs: fix memory leaks - deleted dirents for dummyfs root dir were never freed - fixed memory leaks in error paths - fixed ERRNO value Related to phoenix-rtos/phoenix-rtos-project#169 --- dummyfs/dir.c | 18 ++++++++++++------ dummyfs/dummyfs.c | 2 +- dummyfs/dummyfs.h | 3 +++ dummyfs/object.c | 1 + 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/dummyfs/dir.c b/dummyfs/dir.c index a757f859..1621f91a 100644 --- a/dummyfs/dir.c +++ b/dummyfs/dir.c @@ -19,14 +19,14 @@ #include #include "dummyfs.h" +#include "dir.h" int dir_find(dummyfs_object_t *dir, const char *name, oid_t *res) { dummyfs_dirent_t *e = dir->entries; - char *dirname = strdup(name); - char *end = strchr(dirname, '/'); + char *dirname, *end; int len; if (!S_ISDIR(dir->mode)) @@ -35,6 +35,8 @@ int dir_find(dummyfs_object_t *dir, const char *name, oid_t *res) if (e == NULL) return -ENOENT; + dirname = strdup(name); + end = strchr(dirname, '/'); if (end != NULL) *end = 0; @@ -60,8 +62,7 @@ int dir_replace(dummyfs_object_t *dir, const char *name, oid_t *new) { dummyfs_dirent_t *e = dir->entries; - char *dirname = strdup(name); - char *end = strchr(dirname, '/'); + char *dirname, *end; if (!S_ISDIR(dir->mode)) return -ENOTDIR; @@ -69,6 +70,8 @@ int dir_replace(dummyfs_object_t *dir, const char *name, oid_t *new) if (e == NULL) return -ENOENT; + dirname = strdup(name); + end = strchr(dirname, '/'); if (end != NULL) *end = 0; @@ -167,9 +170,12 @@ int dir_remove(dummyfs_object_t *dir, const char *name) do { if (!strcmp(e->name, (char *)name) && !e->deleted) { - dir->size -= strlen(e->name); + dir->size -= e->len; e->deleted = 1; - dir->dirty = 1; + + if (++dir->dirty > DUMMYFS_DIRTY_DIR_AUTOCLEANUP_THRESH) + dir_clean(dir); + return EOK; } e = e->next; diff --git a/dummyfs/dummyfs.c b/dummyfs/dummyfs.c index 6b28348f..caa29ae6 100644 --- a/dummyfs/dummyfs.c +++ b/dummyfs/dummyfs.c @@ -370,7 +370,7 @@ int dummyfs_unlink(oid_t *dir, const char *name) object_unlock(d); object_put(d); object_put(o); - return -EINVAL; + return -ENOTEMPTY; } ret = dir_remove(d, name); diff --git a/dummyfs/dummyfs.h b/dummyfs/dummyfs.h index 5cde7512..0023981b 100644 --- a/dummyfs/dummyfs.h +++ b/dummyfs/dummyfs.h @@ -23,6 +23,9 @@ #define DUMMYFS_SIZE_MAX 32 * 1024 * 1024 +/* threshold for cleaning directory from deleted dirents */ +#define DUMMYFS_DIRTY_DIR_AUTOCLEANUP_THRESH 8 + typedef struct _dummyfs_dirent_t { char *name; diff --git a/dummyfs/object.c b/dummyfs/object.c index 6f50d427..422804c2 100644 --- a/dummyfs/object.c +++ b/dummyfs/object.c @@ -57,6 +57,7 @@ dummyfs_object_t *object_create(void) } if (dummyfs_incsz(sizeof(dummyfs_object_t)) != EOK) { + free(r); mutexUnlock(dummyfs_common.mutex); mutexUnlock(olock); return NULL;