]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/inode.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[karo-tx-linux.git] / fs / inode.c
index a2de294f6b77fcfade161dafc9e16fb59d5ff4d3..78a17b8859e191735f8cf4f307074fa15acc8295 100644 (file)
@@ -31,7 +31,7 @@
  * inode->i_sb->s_inode_list_lock protects:
  *   inode->i_sb->s_inodes, inode->i_sb_list
  * bdi->wb.list_lock protects:
- *   bdi->wb.b_{dirty,io,more_io,dirty_time}, inode->i_wb_list
+ *   bdi->wb.b_{dirty,io,more_io,dirty_time}, inode->i_io_list
  * inode_hash_lock protects:
  *   inode_hashtable, inode->i_hash
  *
@@ -357,7 +357,7 @@ void inode_init_once(struct inode *inode)
        memset(inode, 0, sizeof(*inode));
        INIT_HLIST_NODE(&inode->i_hash);
        INIT_LIST_HEAD(&inode->i_devices);
-       INIT_LIST_HEAD(&inode->i_wb_list);
+       INIT_LIST_HEAD(&inode->i_io_list);
        INIT_LIST_HEAD(&inode->i_lru);
        address_space_init_once(&inode->i_data);
        i_size_ordered_init(inode);
@@ -525,8 +525,8 @@ static void evict(struct inode *inode)
        BUG_ON(!(inode->i_state & I_FREEING));
        BUG_ON(!list_empty(&inode->i_lru));
 
-       if (!list_empty(&inode->i_wb_list))
-               inode_wb_list_del(inode);
+       if (!list_empty(&inode->i_io_list))
+               inode_io_list_del(inode);
 
        inode_sb_list_del(inode);
 
@@ -575,6 +575,7 @@ static void dispose_list(struct list_head *head)
                list_del_init(&inode->i_lru);
 
                evict(inode);
+               cond_resched();
        }
 }
 
@@ -592,6 +593,7 @@ void evict_inodes(struct super_block *sb)
        struct inode *inode, *next;
        LIST_HEAD(dispose);
 
+again:
        spin_lock(&sb->s_inode_list_lock);
        list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
                if (atomic_read(&inode->i_count))
@@ -607,6 +609,18 @@ void evict_inodes(struct super_block *sb)
                inode_lru_list_del(inode);
                spin_unlock(&inode->i_lock);
                list_add(&inode->i_lru, &dispose);
+
+               /*
+                * We can have a ton of inodes to evict at unmount time given
+                * enough memory, check to see if we need to go to sleep for a
+                * bit so we don't livelock.
+                */
+               if (need_resched()) {
+                       spin_unlock(&sb->s_inode_list_lock);
+                       cond_resched();
+                       dispose_list(&dispose);
+                       goto again;
+               }
        }
        spin_unlock(&sb->s_inode_list_lock);