
On 09/12/2017 10:40 PM, Rob Clark wrote:
A new fatbuf was allocated by get_fs_info() (called by fat_itr_root()), but not freed, resulting in eventually running out of memory. Spotted by running 'ls -r' in a large FAT filesystem from Shell.efi.
fatbuf is mainly used to cache FAT entry lookups (get_fatent()).. possibly once fat_write.c it can move into the iterator to simplify this.
Signed-off-by: Rob Clark robdclark@gmail.com
I can squash this back in to the earlier readdir patches and resend them if that is preferred.
fs/fat/fat.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/fs/fat/fat.c b/fs/fat/fat.c index f5f74c12ff..f0284398b4 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1042,6 +1042,7 @@ int fat_exists(const char *filename) return 0;
ret = fat_itr_resolve(itr, filename, TYPE_ANY);
- free(fsdata.fatbuf); return ret == 0; }
@@ -1061,17 +1062,19 @@ int fat_size(const char *filename, loff_t *size) * Directories don't have size, but fs_size() is not * expected to fail if passed a directory path: */
fat_itr_root(itr, &fsdata); if (!fat_itr_resolve(itr, filename, TYPE_DIR)) { *size = 0;free(fsdata.fatbuf);
return 0;
}ret = 0;
return ret;
goto out;
}
*size = FAT2CPU32(itr->dent->size);
- return 0;
+out:
free(fsdata.fatbuf);
return ret; }
int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
@@ -1087,10 +1090,14 @@ int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
ret = fat_itr_resolve(itr, filename, TYPE_FILE); if (ret)
return ret;
goto out;
printf("reading %s\n", filename);
- return get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread);
- ret = get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread);
+out:
free(fsdata.fatbuf);
return ret; }
int file_fat_read(const char *filename, void *buffer, int maxsize)
@@ -1126,7 +1133,7 @@ typedef struct {
int fat_opendir(const char *filename, struct fs_dir_stream **dirsp) {
- fat_dir *dir = malloc(sizeof(*dir));
fat_dir *dir = calloc(1, sizeof(*dir)); int ret;
if (!dir)
@@ -1144,6 +1151,7 @@ int fat_opendir(const char *filename, struct fs_dir_stream **dirsp) return 0;
fail:
- free(dir->fsdata.fatbuf); free(dir); return ret; }
@@ -1174,6 +1182,7 @@ int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp) void fat_closedir(struct fs_dir_stream *dirs) { fat_dir *dir = (fat_dir *)dirs;
- free(dir->fsdata.fatbuf); free(dir); }
Reviewed-by: Łukasz Majewski lukma@denx.de