From 5afbafc6872e31a9244efbc9deacc648bc132870 Mon Sep 17 00:00:00 2001 From: roy Date: Sun, 19 May 2024 20:42:07 +0800 Subject: [PATCH 1/2] Fix sb_read cache not be freed --- dir.c | 6 ++++-- inode.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dir.c b/dir.c index 3c665ef..b9d4e24 100644 --- a/dir.c +++ b/dir.c @@ -60,9 +60,11 @@ static int simplefs_iterate(struct file *dir, struct dir_context *ctx) goto release_bh; } dblock = (struct simplefs_dir_block *) bh2->b_data; - if (dblock->files[0].inode == 0) + if (dblock->files[0].inode == 0) { + brelse(bh2); + bh2 = NULL; break; - + } /* Iterate every file in one block */ for (; fi < SIMPLEFS_FILES_PER_BLOCK; fi++) { f = &dblock->files[fi]; diff --git a/inode.c b/inode.c index 7cb19c7..ce7b585 100644 --- a/inode.c +++ b/inode.c @@ -749,8 +749,8 @@ static int simplefs_rename(struct inode *old_dir, break; } } - if (new_pos < 0) - brelse(bh2); + + brelse(bh2); } } From cc21eeeab47ec0438eecf5a6c5b8816c810ef943 Mon Sep 17 00:00:00 2001 From: roy Date: Sun, 4 Aug 2024 22:01:03 +0800 Subject: [PATCH 2/2] Fix cache leak in umount simplefs 1. When the cache be destoryed, we should call rcu_barrier() to prevent call_rcu() still works and this also prevent the cache be reused. 2. After simplefs_destroy_inode_cache() function, we need rcu_barrier() to make sure all memory have be freed. --- fs.c | 4 ++++ super.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/fs.c b/fs.c index da7e187..7bd6ac3 100644 --- a/fs.c +++ b/fs.c @@ -58,6 +58,8 @@ static int __init simplefs_init(void) err_inode: simplefs_destroy_inode_cache(); + /* Only after rcu_barrier() is the memory guaranteed to be freed. */ + rcu_barrier(); err: return ret; } @@ -69,6 +71,8 @@ static void __exit simplefs_exit(void) pr_err("Failed to unregister file system\n"); simplefs_destroy_inode_cache(); + /* Only after rcu_barrier() is the memory guaranteed to be freed. */ + rcu_barrier(); pr_info("module unloaded\n"); } diff --git a/super.c b/super.c index 1a7a303..36f0c56 100644 --- a/super.c +++ b/super.c @@ -37,6 +37,9 @@ int simplefs_init_inode_cache(void) /* De-allocate the inode cache */ void simplefs_destroy_inode_cache(void) { + /* wait for call_rcu() and prevent the free cache be used */ + rcu_barrier(); + kmem_cache_destroy(simplefs_inode_cache); }