New method - evict_inode()
[firefly-linux-kernel-4.4.55.git] / fs / inode.c
index 722860b323a9b40e0dc9f8b2e27e68563eb293c1..474a72f571a49f8397a8a259d6968c23986becf2 100644 (file)
@@ -317,10 +317,25 @@ void clear_inode(struct inode *inode)
                bd_forget(inode);
        if (S_ISCHR(inode->i_mode) && inode->i_cdev)
                cd_forget(inode);
-       inode->i_state = I_CLEAR;
+       inode->i_state = I_FREEING | I_CLEAR;
 }
 EXPORT_SYMBOL(clear_inode);
 
+static void evict(struct inode *inode, int delete)
+{
+       const struct super_operations *op = inode->i_sb->s_op;
+
+       if (op->evict_inode) {
+               op->evict_inode(inode);
+       } else if (delete && op->delete_inode) {
+               op->delete_inode(inode);
+       } else {
+               if (inode->i_data.nrpages)
+                       truncate_inode_pages(&inode->i_data, 0);
+               clear_inode(inode);
+       }
+}
+
 /*
  * dispose_list - dispose of the contents of a local list
  * @head: the head of the list to free
@@ -338,9 +353,7 @@ static void dispose_list(struct list_head *head)
                inode = list_first_entry(head, struct inode, i_list);
                list_del(&inode->i_list);
 
-               if (inode->i_data.nrpages)
-                       truncate_inode_pages(&inode->i_data, 0);
-               clear_inode(inode);
+               evict(inode, 0);
 
                spin_lock(&inode_lock);
                hlist_del_init(&inode->i_hash);
@@ -553,7 +566,7 @@ repeat:
                        continue;
                if (!test(inode, data))
                        continue;
-               if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
+               if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
                        __wait_on_freeing_inode(inode);
                        goto repeat;
                }
@@ -578,7 +591,7 @@ repeat:
                        continue;
                if (inode->i_sb != sb)
                        continue;
-               if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
+               if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
                        __wait_on_freeing_inode(inode);
                        goto repeat;
                }
@@ -840,7 +853,7 @@ EXPORT_SYMBOL(iunique);
 struct inode *igrab(struct inode *inode)
 {
        spin_lock(&inode_lock);
-       if (!(inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)))
+       if (!(inode->i_state & (I_FREEING|I_WILL_FREE)))
                __iget(inode);
        else
                /*
@@ -1089,7 +1102,7 @@ int insert_inode_locked(struct inode *inode)
                                continue;
                        if (old->i_sb != sb)
                                continue;
-                       if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+                       if (old->i_state & (I_FREEING|I_WILL_FREE))
                                continue;
                        break;
                }
@@ -1128,7 +1141,7 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
                                continue;
                        if (!test(old, data))
                                continue;
-                       if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+                       if (old->i_state & (I_FREEING|I_WILL_FREE))
                                continue;
                        break;
                }
@@ -1194,8 +1207,6 @@ EXPORT_SYMBOL(remove_inode_hash);
  */
 void generic_delete_inode(struct inode *inode)
 {
-       const struct super_operations *op = inode->i_sb->s_op;
-
        list_del_init(&inode->i_list);
        list_del_init(&inode->i_sb_list);
        WARN_ON(inode->i_state & I_NEW);
@@ -1203,22 +1214,13 @@ void generic_delete_inode(struct inode *inode)
        inodes_stat.nr_inodes--;
        spin_unlock(&inode_lock);
 
-       if (op->delete_inode) {
-               void (*delete)(struct inode *) = op->delete_inode;
-               /* Filesystems implementing their own
-                * s_op->delete_inode are required to call
-                * truncate_inode_pages and clear_inode()
-                * internally */
-               delete(inode);
-       } else {
-               truncate_inode_pages(&inode->i_data, 0);
-               clear_inode(inode);
-       }
+       evict(inode, 1);
+
        spin_lock(&inode_lock);
        hlist_del_init(&inode->i_hash);
        spin_unlock(&inode_lock);
        wake_up_inode(inode);
-       BUG_ON(inode->i_state != I_CLEAR);
+       BUG_ON(inode->i_state != (I_FREEING | I_CLEAR));
        destroy_inode(inode);
 }
 EXPORT_SYMBOL(generic_delete_inode);
@@ -1268,9 +1270,7 @@ static void generic_forget_inode(struct inode *inode)
 {
        if (!generic_detach_inode(inode))
                return;
-       if (inode->i_data.nrpages)
-               truncate_inode_pages(&inode->i_data, 0);
-       clear_inode(inode);
+       evict(inode, 0);
        wake_up_inode(inode);
        destroy_inode(inode);
 }
@@ -1322,7 +1322,7 @@ static inline void iput_final(struct inode *inode)
 void iput(struct inode *inode)
 {
        if (inode) {
-               BUG_ON(inode->i_state == I_CLEAR);
+               BUG_ON(inode->i_state & I_CLEAR);
 
                if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
                        iput_final(inode);