#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
-static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
+void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
{
atomic_set(&dentry->d_count, 1);
dentry->d_vfs_flags = 0;
GOTO(exit, rc);
atomic_inc(&inode->i_count);
- duplicate_inode(cache_old_dentry->d_inode, inode);
+ post_smfs_inode(inode, cache_old_dentry->d_inode);
d_instantiate(dentry, inode);
exit:
rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
- duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
- duplicate_inode(cache_dir, dir);
+ post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
+ post_smfs_inode(dir, cache_dir);
igrab(cache_dentry->d_inode);
rc = post_kml_mkdir(dir, dentry);
GOTO(exit, rc);
}
- duplicate_inode(cache_dir, dir);
+ post_smfs_inode(dir, cache_dir);
exit:
unlock_kernel();
smfs_trans_commit(handle);
if (cache_dir->i_op->rmdir)
rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
- duplicate_inode(cache_dir, dir);
- duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
-
+ post_smfs_inode(dir, cache_dir);
+ post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
d_unalloc(cache_dentry);
RETURN(rc);
}
inode = iget(dir->i_sb, cache_inode->i_ino);
d_instantiate(dentry, inode);
- duplicate_inode(cache_dir, dir);
- duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
+ post_smfs_inode(dir, cache_dir);
+ post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
exit:
d_unalloc(cache_dentry);
RETURN(rc);
rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
cache_new_dir, cache_new_dentry);
- duplicate_inode(cache_old_dir, old_dir);
- duplicate_inode(cache_new_dir, new_dir);
+ post_smfs_inode(old_dir, cache_old_dir) ;
+ post_smfs_inode(new_dir, cache_new_dir);
if (cache_new_dentry->d_inode) {
igrab(cache_new_dentry->d_inode);
}
rc = cache_inode->i_fop->write(&open_file, buf, count, cache_ppos);
*ppos = *cache_ppos;
- duplicate_inode(cache_inode, inode);
+ post_smfs_inode(inode, cache_inode);
smfs_update_file(filp, &open_file);
RETURN(rc);
if (cache_inode->i_fop->ioctl)
rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
- duplicate_inode(cache_inode, inode);
+ post_smfs_inode(inode, cache_inode);
smfs_update_file(filp, &open_file);
RETURN(rc);
}
rc = cache_inode->i_fop->read(&open_file, buf, count, cache_ppos);
*ppos = *cache_ppos;
- duplicate_inode(cache_inode, inode);
+ post_smfs_inode(inode, cache_inode);
smfs_update_file(filp, &open_file);
RETURN(rc);
}
if (cache_inode->i_fop->llseek)
rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
- duplicate_inode(cache_inode, dentry->d_inode);
+ post_smfs_inode(dentry->d_inode, cache_inode);
smfs_update_file(file, &open_file);
RETURN(rc);
if (cache_inode->i_fop->mmap)
rc = cache_inode->i_fop->mmap(&open_file, vma);
- duplicate_inode(cache_inode, inode);
+ post_smfs_inode(inode, cache_inode);
smfs_update_file(file, &open_file);
RETURN(rc);
if (cache_inode->i_fop->open)
rc = cache_inode->i_fop->open(cache_inode, &open_file);
- duplicate_inode(cache_inode, inode);
+ post_smfs_inode(inode, cache_inode);
smfs_update_file(filp, &open_file);
RETURN(rc);
if (cache_inode->i_fop->release)
rc = cache_inode->i_fop->release(cache_inode, &open_file);
- duplicate_inode(cache_inode, inode);
+ post_smfs_inode(inode, cache_inode);
smfs_update_file(filp, &open_file);
RETURN(rc);
if (cache_inode->i_fop->fsync)
rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
- duplicate_inode(cache_inode, inode);
+ post_smfs_inode(inode, cache_inode);
smfs_update_file(file, &open_file);
RETURN(rc);
if (cache_inode->i_op->truncate)
cache_inode->i_op->truncate(cache_inode);
- duplicate_inode(inode, cache_inode);
+ post_smfs_inode(inode, cache_inode);
return;
}
RETURN(-ENOENT);
smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+ pre_smfs_inode(dentry->d_inode, cache_inode);
if (cache_inode->i_op->setattr)
rc = cache_inode->i_op->setattr(&open_dentry, attr);
- duplicate_inode(cache_inode, dentry->d_inode);
+ post_smfs_inode(dentry->d_inode, cache_inode);
RETURN(rc);
}
if (!cache_inode)
RETURN(-ENOENT);
+ pre_smfs_inode(dentry->d_inode, cache_inode);
smfs_prepare_cache_dentry(&open_dentry, cache_inode);
if (cache_inode->i_op->setattr)
rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
- duplicate_inode(cache_inode, dentry->d_inode);
+ post_smfs_inode(dentry->d_inode, cache_inode);
RETURN(rc);
}
RETURN(-ENOENT);
smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+ pre_smfs_inode(dentry->d_inode, cache_inode);
if (cache_inode->i_op->setattr)
rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
- duplicate_inode(cache_inode, dentry->d_inode);
+ post_smfs_inode(dentry->d_inode, cache_inode);
RETURN(rc);
}
RETURN(-ENOENT);
smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+ pre_smfs_inode(dentry->d_inode, cache_inode);
if (cache_inode->i_op->listxattr)
rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
- duplicate_inode(cache_inode, dentry->d_inode);
+ post_smfs_inode(dentry->d_inode, cache_inode);
RETURN(rc);
}
RETURN(-ENOENT);
smfs_prepare_cache_dentry(&open_dentry, cache_inode);
+ pre_smfs_inode(dentry->d_inode, cache_inode);
if (cache_inode->i_op->removexattr)
rc = cache_inode->i_op->removexattr(&open_dentry, name);
- duplicate_inode(cache_inode, dentry->d_inode);
+ post_smfs_inode(dentry->d_inode, cache_inode);
RETURN(rc);
}
#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)
+{
+ 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)
+{
+ 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
atomic_dec(&cache_inode->i_count);
}
- duplicate_inode(inode, cache_inode);
+ pre_smfs_inode(inode, cache_inode);
list_del(&cache_inode->i_hash);
INIT_LIST_HEAD(&cache_inode->i_hash);
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;
if (!cache_inode || !cache_sb)
return;
- duplicate_inode(inode, cache_inode);
+ 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;
- duplicate_inode(inode, cache_inode);
+ 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;
}
static int smfs_readlink(struct dentry * dentry, char * buffer, int buflen)
{
struct inode *cache_inode = I2CI(dentry->d_inode);
+ struct inode *cache_dir = NULL;
struct dentry *cache_dentry;
+ struct dentry parent;
int rc = 0;
if (!cache_inode)
RETURN(-ENOENT);
-
- cache_dentry = d_alloc(NULL, &dentry->d_name);
+ if (dentry->d_parent && dentry->d_parent->d_inode){
+ cache_dir = I2CI(dentry->d_parent->d_inode);
+ prepare_parent_dentry(&parent, cache_dir);
+ }
+ cache_dentry = d_alloc(&parent, &dentry->d_name);
d_add(cache_dentry, cache_inode);
igrab(cache_inode);
static int smfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *cache_inode = I2CI(dentry->d_inode);
+ struct inode *cache_dir = NULL;
struct dentry *cache_dentry;
+ struct dentry parent;
int rc = 0;
if (!cache_inode)
RETURN(-ENOENT);
-
- cache_dentry = d_alloc(NULL, &dentry->d_name);
+
+ if (dentry->d_parent && dentry->d_parent->d_inode){
+ cache_dir = I2CI(dentry->d_parent->d_inode);
+ prepare_parent_dentry(&parent, cache_dir);
+ }
+
+ cache_dentry = d_alloc(&parent, &dentry->d_name);
+
d_add(cache_dentry, cache_inode);
igrab(cache_inode);
-
+
if (cache_inode->i_op && cache_inode->i_op->follow_link)
rc = cache_inode->i_op->follow_link(cache_dentry, nd);
d_unalloc(cache_dentry);
return rc;
-
}
struct inode_operations smfs_sym_iops = {
readlink: smfs_readlink,