diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-04-20 16:32:16 +0300 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-04-22 14:29:53 +0300 |
commit | 5fcab90f2d89d472bf0aa70682329e923689c449 (patch) | |
tree | 3e5e511e5ed8ee7478321c59b2f41fb4d5d245c4 /tests | |
parent | 9211a3ba80f0300b5476a9c015e4aa80c18e4fbf (diff) |
fs-tests: integck: simplify dirent manipulation
Teach 'add_dir_entry()' to allocate the file/dir/symlink object for
the client. This simplifies client's code. The only place where we
do not want to do this is when we are creating a hardling pointing
to an existing file.
Teach 'remove_dir_entry()' to free the file/dir/symlink object for
the client. Similarly, this simplifies client's code. The only place
where we do not want to do this is the rename function - when we
rename an object we want to only change its direntry, but not the
object itself.
But the main motivation for this change is not just to clean-up, but
to fix another memory leak. In the re-name function we free the
'rename_entry', but we did not free the corresponding object. This
patch fixes the situation.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/fs-tests/integrity/integck.c | 124 |
1 files changed, 62 insertions, 62 deletions
diff --git a/tests/fs-tests/integrity/integck.c b/tests/fs-tests/integrity/integck.c index 4b9b0f0..0d69ee4 100644 --- a/tests/fs-tests/integrity/integck.c +++ b/tests/fs-tests/integrity/integck.c @@ -378,8 +378,30 @@ static struct fd_info *add_fd(struct file_info *file, int fd) return fdi; } -static void add_dir_entry(struct dir_info *parent, char type, const char *name, - void *target) +/* + * Free all the information about writes to a file. + */ +static void free_writes_info(struct file_info *file) +{ + struct write_info *w, *next; + + w = file->writes; + while (w) { + next = w->next; + free(w); + w = next; + } + + w = file->raw_writes; + while (w) { + next = w->next; + free(w); + w = next; + } +} + +static void *add_dir_entry(struct dir_info *parent, char type, const char *name, + void *target) { struct dir_entry_info *entry; @@ -397,27 +419,37 @@ static void add_dir_entry(struct dir_info *parent, char type, const char *name, if (entry->type == 'f') { struct file_info *file = target; + if (!file) + file = zalloc(sizeof(struct file_info)); entry->file = file; entry->next_link = file->links; if (file->links) file->links->prev_link = entry; file->links = entry; file->link_count += 1; + return file; } else if (entry->type == 'd') { struct dir_info *dir = target; + if (!dir) + dir = zalloc(sizeof(struct dir_info)); entry->dir = dir; dir->entry = entry; dir->parent = parent; + return dir; } else if (entry->type == 's') { struct symlink_info *symlink = target; + if (!symlink) + symlink = zalloc(sizeof(struct symlink_info)); entry->symlink = symlink; symlink->entry = entry; - } + return symlink; + } else + assert(0); } -static void remove_dir_entry(struct dir_entry_info *entry) +static void remove_dir_entry(struct dir_entry_info *entry, int free_target) { entry->parent->number_of_entries -= 1; if (entry->parent->first == entry) @@ -439,6 +471,21 @@ static void remove_dir_entry(struct dir_entry_info *entry) file->link_count -= 1; if (file->link_count == 0) assert(file->links == NULL); + + /* Free struct file_info if file is not open and not linked */ + if (free_target && !file->fds && !file->links) { + free_writes_info(file); + free(file); + } + } + + if (free_target) { + if (entry->type == 'd') { + free(entry->dir); + } else if (entry->type == 's') { + free(entry->symlink->target_pathname); + free(entry->symlink); + } } free(entry->name); @@ -452,7 +499,6 @@ static void remove_dir_entry(struct dir_entry_info *entry) */ static int dir_new(struct dir_info *parent, const char *name) { - struct dir_info *dir; char *path; assert(parent); @@ -470,8 +516,7 @@ static int dir_new(struct dir_info *parent, const char *name) } free(path); - dir = zalloc(sizeof(struct dir_info)); - add_dir_entry(parent, 'd', name, dir); + add_dir_entry(parent, 'd', name, NULL); return 0; } @@ -510,9 +555,8 @@ static int dir_remove(struct dir_info *dir) } /* Remove entry from parent directory */ - remove_dir_entry(dir->entry); + remove_dir_entry(dir->entry, 1); free(path); - free(dir); return 0; } @@ -540,8 +584,7 @@ static int file_new(struct dir_info *parent, const char *name) } free(path); - file = zalloc(sizeof(struct file_info)); - add_dir_entry(parent, 'f', name, file); + file = add_dir_entry(parent, 'f', name, NULL); add_fd(file, fd); return 0; } @@ -592,33 +635,10 @@ static void file_close_all(struct file_info *file) } /* - * Free all the information about writes to a file. - */ -static void free_writes_info(struct file_info *file) -{ - struct write_info *w, *next; - - w = file->writes; - while (w) { - next = w->next; - free(w); - w = next; - } - - w = file->raw_writes; - while (w) { - next = w->next; - free(w); - w = next; - } -} - -/* * Unlink a directory entry for a file. */ static int file_unlink(struct dir_entry_info *entry) { - struct file_info *file = entry->file; char *path; int ret; @@ -633,14 +653,7 @@ static int file_unlink(struct dir_entry_info *entry) free(path); /* Remove file entry from parent directory */ - remove_dir_entry(entry); - - /* Free struct file_info if file is not open and not linked */ - if (!file->fds && !file->links) { - free_writes_info(file); - free(file); - } - + remove_dir_entry(entry, 1); return 0; } @@ -1755,8 +1768,8 @@ static int rename_entry(struct dir_entry_info *entry) add_dir_entry(parent, entry->type, name, entry->target); if (rename_entry) - remove_dir_entry(rename_entry); - remove_dir_entry(entry); + remove_dir_entry(rename_entry, 1); + remove_dir_entry(entry, 0); free(name); return 0; } @@ -1870,8 +1883,7 @@ static int symlink_new(struct dir_info *dir, const char *nm) } free(path); - s = zalloc(sizeof(struct symlink_info)); - add_dir_entry(dir, 's', name, s); + s = add_dir_entry(dir, 's', name, NULL); s->target_pathname = target; free(name); return 0; @@ -1888,9 +1900,7 @@ static int symlink_remove(struct symlink_info *symlink) return -1; } - remove_dir_entry(symlink->entry); - free(symlink->target_pathname); - free(symlink); + remove_dir_entry(symlink->entry, 1); free(path); return 0; } @@ -2642,23 +2652,13 @@ static void free_fs_info(struct dir_info *dir) if (entry->type == 'd') { struct dir_info *d = entry->dir; - remove_dir_entry(entry); + remove_dir_entry(entry, 0); free_fs_info(d); free(d); } else if (entry->type == 'f') { - struct file_info *file = entry->file; - - remove_dir_entry(entry); - if (!file->links) { - free_writes_info(file); - free(file); - } + remove_dir_entry(entry, 1); } else if (entry->type == 's') { - struct symlink_info *symlink = entry->symlink; - - remove_dir_entry(entry); - free(symlink->target_pathname); - free(symlink); + remove_dir_entry(entry, 1); } else assert(0); } |