diff options
author | Prasad Joshi <prasadjoshi.linux@gmail.com> | 2012-03-09 06:27:12 +0530 |
---|---|---|
committer | Prasad Joshi <prasadjoshi.linux@gmail.com> | 2012-04-02 09:20:33 +0530 |
commit | d2dcd9083f101584e029cbd4f0e1a4e573170d43 (patch) | |
tree | 1b64355958937bd425901f950342be58fa2a6286 /fs/logfs/inode.c | |
parent | dd775ae2549217d3ae09363e3edb305d0fa19928 (diff) | |
download | linux-d2dcd9083f101584e029cbd4f0e1a4e573170d43.tar.gz linux-d2dcd9083f101584e029cbd4f0e1a4e573170d43.tar.bz2 linux-d2dcd9083f101584e029cbd4f0e1a4e573170d43.zip |
logfs: destroy the reserved inodes while unmounting
We were assuming that the evict_inode() would never be called on
reserved inodes. However, (after the commit 8e22c1a4e logfs: get rid
of magical inodes) while unmounting the file system, in put_super, we
call iput() on all of the reserved inodes.
The following simple test used to cause a kernel panic on LogFS:
1. Mount a LogFS file system on /mnt
2. Create a file
$ touch /mnt/a
3. Try to unmount the FS
$ umount /mnt
The simple fix would be to drop the assumption and properly destroy
the reserved inodes.
Signed-off-by: Prasad Joshi <prasadjoshi.linux@gmail.com>
Diffstat (limited to 'fs/logfs/inode.c')
-rw-r--r-- | fs/logfs/inode.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index a422f42238b2..df093d9e4da1 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c @@ -156,10 +156,26 @@ static void __logfs_destroy_inode(struct inode *inode) call_rcu(&inode->i_rcu, logfs_i_callback); } +static void __logfs_destroy_meta_inode(struct inode *inode) +{ + struct logfs_inode *li = logfs_inode(inode); + BUG_ON(li->li_block); + call_rcu(&inode->i_rcu, logfs_i_callback); +} + static void logfs_destroy_inode(struct inode *inode) { struct logfs_inode *li = logfs_inode(inode); + if (inode->i_ino < LOGFS_RESERVED_INOS) { + /* + * The reserved inodes are never destroyed unless we are in + * unmont path. + */ + __logfs_destroy_meta_inode(inode); + return; + } + BUG_ON(list_empty(&li->li_freeing_list)); spin_lock(&logfs_inode_lock); li->li_refcount--; |