Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / smfs / inode.c
index d3e14fd..117d503 100644 (file)
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/lustre_idl.h>
 #include "smfs_internal.h" 
 
-void duplicate_inode(struct inode *cache_inode, struct inode *inode)
+static void duplicate_inode(struct inode *dst_inode, 
+                    struct inode *src_inode) 
 {
-       
-       inode->i_mode = cache_inode->i_mode;
-       inode->i_uid = cache_inode->i_uid;
-       inode->i_gid = cache_inode->i_gid;
-
-       inode->i_nlink = cache_inode->i_nlink;
-       inode->i_size = cache_inode->i_size;
-       inode->i_atime = cache_inode->i_atime;
-       inode->i_ctime = cache_inode->i_ctime;
-       inode->i_mtime = cache_inode->i_mtime;
-       inode->i_blksize = cache_inode->i_blksize; /* This is the optimal IO size
-                                        * (for stat), not the fs block
-                                        * size */  
-       inode->i_blocks = cache_inode->i_blocks;
-       inode->i_version = cache_inode->i_version;
-       inode->i_state = cache_inode->i_state;
+       dst_inode->i_mode = src_inode->i_mode;
+       dst_inode->i_uid = src_inode->i_uid;
+       dst_inode->i_gid = src_inode->i_gid;
+       dst_inode->i_nlink = src_inode->i_nlink;
+       dst_inode->i_size = src_inode->i_size;
+       dst_inode->i_atime = src_inode->i_atime;
+       dst_inode->i_ctime = src_inode->i_ctime;
+       dst_inode->i_mtime = src_inode->i_mtime;
+       dst_inode->i_blksize = src_inode->i_blksize;  
+       dst_inode->i_blocks = src_inode->i_blocks;
+       dst_inode->i_version = src_inode->i_version;
+       dst_inode->i_state = src_inode->i_state;
+}
+
+void post_smfs_inode(struct inode *inode, 
+                    struct inode *cache_inode)
+{
+       if (inode && cache_inode) {
+               duplicate_inode(inode, cache_inode);
+               /*Here we must release the cache_inode,
+                *Otherwise we will have no chance to
+                *do it
+                */
+               cache_inode->i_state &=~I_LOCK; 
+       }
+}
+void pre_smfs_inode(struct inode *inode,
+                   struct inode *cache_inode)
+{
+       if (inode && cache_inode) {
+               duplicate_inode(cache_inode, inode);
+       }
 }
+
 static void smfs_read_inode(struct inode *inode)
 {
        struct super_block *cache_sb;
@@ -49,7 +68,7 @@ static void smfs_read_inode(struct inode *inode)
        if(cache_sb && cache_sb->s_op->read_inode)
                cache_sb->s_op->read_inode(cache_inode);
 
-       duplicate_inode(cache_inode, inode);
+       post_smfs_inode(inode, cache_inode);
        sm_set_inode_ops(cache_inode, inode);
        
        CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", 
@@ -58,6 +77,7 @@ static void smfs_read_inode(struct inode *inode)
        iput(cache_inode);      
        return; 
 }
+
 /* Although some filesystem(such as ext3) do not have
  * clear_inode method, but we need it to free the 
  * cache inode 
@@ -74,14 +94,20 @@ static void smfs_clear_inode(struct inode *inode)
        cache_sb = S2CSB(inode->i_sb);
        cache_inode = I2CI(inode);
 
-       duplicate_inode(inode, cache_inode); 
-       
-       if (cache_sb->s_op->clear_inode)
-               cache_sb->s_op->clear_inode(cache_inode);
+       /*FIXME: because i_count of cache_inode may not 
+         * be 0 or 1 in before smfs_delete inode, So we 
+         * need to dec it to 1 before we call delete_inode
+         * of the bellow cache filesystem Check again latter*/
 
-       clear_inode(cache_inode);
-       duplicate_inode(inode, cache_inode);
+       if (atomic_read(&cache_inode->i_count) < 1)
+               BUG();
        
+       while (atomic_read(&cache_inode->i_count) != 1) {
+               atomic_dec(&cache_inode->i_count);
+       }
+       iput(cache_inode);
+       
+       I2CI(inode) = NULL;
        return; 
 }
 static void smfs_delete_inode(struct inode *inode)
@@ -93,16 +119,37 @@ static void smfs_delete_inode(struct inode *inode)
        cache_inode = I2CI(inode);
        cache_sb = S2CSB(inode->i_sb);
 
-       if (!cache_inode || !cache_sb)
+       if (!cache_inode || !cache_sb)  
                return;
-               
-       duplicate_inode(inode, cache_inode); 
+
+       /*FIXME: because i_count of cache_inode may not 
+         * be 0 or 1 in before smfs_delete inode, So we 
+         * need to dec it to 1 before we call delete_inode
+         * of the bellow cache filesystem Check again latter*/
+
+       if (atomic_read(&cache_inode->i_count) < 1)
+               BUG();
+       
+       while (atomic_read(&cache_inode->i_count) != 1) {
+               atomic_dec(&cache_inode->i_count);
+       }
+       
+       pre_smfs_inode(inode, cache_inode);
+       
+       list_del(&cache_inode->i_hash);
+        INIT_LIST_HEAD(&cache_inode->i_hash);
+        list_del(&cache_inode->i_list);
+        INIT_LIST_HEAD(&cache_inode->i_list);
+       
+       if (cache_inode->i_data.nrpages)
+               truncate_inode_pages(&cache_inode->i_data, 0);
        
        if (cache_sb->s_op->delete_inode)
                cache_sb->s_op->delete_inode(cache_inode);
 
-       duplicate_inode(cache_inode, inode); 
+       post_smfs_inode(inode, cache_inode);
        
+       I2CI(inode) = NULL;
        return;
 }
 static void smfs_write_inode(struct inode *inode, int wait)
@@ -117,10 +164,12 @@ static void smfs_write_inode(struct inode *inode, int wait)
        if (!cache_inode || !cache_sb)
                return;
                
+       pre_smfs_inode(inode, cache_inode);
+       
        if (cache_sb->s_op->write_inode)
                cache_sb->s_op->write_inode(cache_inode, wait);
 
-       duplicate_inode(cache_inode, inode); 
+       post_smfs_inode(inode, cache_inode);
        
        return;
 }
@@ -136,10 +185,11 @@ static void smfs_dirty_inode(struct inode *inode)
        if (!cache_inode || !cache_sb)
                return;
                
+       pre_smfs_inode(inode, cache_inode);
        if (cache_sb->s_op->dirty_inode)
                cache_sb->s_op->dirty_inode(cache_inode);
 
-       duplicate_inode(cache_inode, inode); 
+       post_smfs_inode(inode, cache_inode);
        return;
 }
 
@@ -154,7 +204,6 @@ static void smfs_put_inode(struct inode *inode)
 
        if (!cache_inode || !cache_sb)
                return;
-               
        if (cache_sb->s_op->put_inode)
                cache_sb->s_op->put_inode(cache_inode);
 
@@ -211,21 +260,23 @@ static void smfs_unlockfs(struct super_block *sb)
        duplicate_sb(cache_sb, sb);
        return;
 }
-static void smfs_statfs(struct super_block * sb, struct statfs * buf) 
+static int smfs_statfs(struct super_block * sb, struct statfs * buf) 
 {
        struct super_block *cache_sb;
+       int     rc = 0;
 
        ENTRY;
        cache_sb = S2CSB(sb);
 
        if (!cache_sb)
-               return;
+               RETURN(-EINVAL);
                
        if (cache_sb->s_op->statfs)
-               cache_sb->s_op->statfs(cache_sb, buf);
+               rc = cache_sb->s_op->statfs(cache_sb, buf);
 
        duplicate_sb(cache_sb, sb);
-       return;
+       
+       return rc;
 }
 static int smfs_remount(struct super_block * sb, int * flags, char * data)
 {