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/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/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); } } 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); }