logfs: destroy the reserved inodes while unmounting
authorPrasad Joshi <prasadjoshi.linux@gmail.com>
Fri, 9 Mar 2012 00:57:12 +0000 (06:27 +0530)
committerPrasad Joshi <prasadjoshi.linux@gmail.com>
Mon, 2 Apr 2012 03:50:33 +0000 (09:20 +0530)
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>
fs/logfs/inode.c
fs/logfs/readwrite.c
fs/logfs/segment.c

index a422f42238b250764011fa421d24a1a0858dd153..df093d9e4da1884b76c3b8e46f1e5111cc126a78 100644 (file)
@@ -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--;
index e3ab5e5a904c23a238fdda580447988efc0941ce..c8ea8664699c223289e4774a3cdf8a45d6db0aec 100644 (file)
@@ -2189,7 +2189,6 @@ void logfs_evict_inode(struct inode *inode)
                return;
        }
 
-       BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS);
        page = inode_to_page(inode);
        BUG_ON(!page); /* FIXME: Use emergency page */
        logfs_put_write_page(page);
index e28d090c98d6bbb2986d40fd4ae57e795cf7415c..038da0991794a39962fac3d4ef7ed5b18008c6f9 100644 (file)
@@ -886,7 +886,7 @@ static struct logfs_area *alloc_area(struct super_block *sb)
 
 static void map_invalidatepage(struct page *page, unsigned long l)
 {
-       BUG();
+       return;
 }
 
 static int map_releasepage(struct page *page, gfp_t g)
This page took 0.032543 seconds and 5 git commands to generate.