Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+17 -2
+16
fs/logfs/inode.c
··· 156 156 call_rcu(&inode->i_rcu, logfs_i_callback); 157 157 } 158 158 159 + static void __logfs_destroy_meta_inode(struct inode *inode) 160 + { 161 + struct logfs_inode *li = logfs_inode(inode); 162 + BUG_ON(li->li_block); 163 + call_rcu(&inode->i_rcu, logfs_i_callback); 164 + } 165 + 159 166 static void logfs_destroy_inode(struct inode *inode) 160 167 { 161 168 struct logfs_inode *li = logfs_inode(inode); 169 + 170 + if (inode->i_ino < LOGFS_RESERVED_INOS) { 171 + /* 172 + * The reserved inodes are never destroyed unless we are in 173 + * unmont path. 174 + */ 175 + __logfs_destroy_meta_inode(inode); 176 + return; 177 + } 162 178 163 179 BUG_ON(list_empty(&li->li_freeing_list)); 164 180 spin_lock(&logfs_inode_lock);
-1
fs/logfs/readwrite.c
··· 2189 2189 return; 2190 2190 } 2191 2191 2192 - BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS); 2193 2192 page = inode_to_page(inode); 2194 2193 BUG_ON(!page); /* FIXME: Use emergency page */ 2195 2194 logfs_put_write_page(page);
+1 -1
fs/logfs/segment.c
··· 886 886 887 887 static void map_invalidatepage(struct page *page, unsigned long l) 888 888 { 889 - BUG(); 889 + return; 890 890 } 891 891 892 892 static int map_releasepage(struct page *page, gfp_t g)