#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;
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",
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
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)
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)
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;
}
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;
}
if (!cache_inode || !cache_sb)
return;
-
if (cache_sb->s_op->put_inode)
cache_sb->s_op->put_inode(cache_inode);
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)
{