From 3128827f2d3814ec5c14b44ad249a68905817e46 Mon Sep 17 00:00:00 2001 From: wangdi Date: Sun, 1 Feb 2004 17:42:36 +0000 Subject: [PATCH] update smfs, add some files dir.c cache.c inode.c still many problems, will fix them soon --- lustre/smfs/Makefile.am | 2 +- lustre/smfs/cache.c | 216 ++++++++++++++++++++++++++++++++++++++++++++ lustre/smfs/dir.c | 97 ++++++++++++++++++++ lustre/smfs/inode.c | 72 +++++++++++++++ lustre/smfs/smfs_internal.h | 35 ++++++- lustre/smfs/super.c | 8 +- 6 files changed, 425 insertions(+), 5 deletions(-) create mode 100644 lustre/smfs/cache.c create mode 100644 lustre/smfs/dir.c create mode 100644 lustre/smfs/inode.c diff --git a/lustre/smfs/Makefile.am b/lustre/smfs/Makefile.am index 1dcfa95..764dcfd 100644 --- a/lustre/smfs/Makefile.am +++ b/lustre/smfs/Makefile.am @@ -10,7 +10,7 @@ MODULE = smfs modulefs_DATA = smfs.o EXTRA_PROGRAMS = smfs -smfs_SOURCES = super.c options.c +smfs_SOURCES = super.c options.c inode.c cache.c dir.c include $(top_srcdir)/Rules diff --git a/lustre/smfs/cache.c b/lustre/smfs/cache.c new file mode 100644 index 0000000..5008615 --- /dev/null +++ b/lustre/smfs/cache.c @@ -0,0 +1,216 @@ +/* + * snapfs/cache.c + */ + +#define DEBUG_SUBSYSTEM S_SM + +#include +#include +#include +#include +#include +#include +#include "smfs_internal.h" +struct sm_ops smfs_operations; + +extern struct inode_operations smfs_file_iops; +extern struct file_operations smfs_file_fops; +extern struct address_space_operations smfs_file_aops; +extern struct inode_operations smfs_sym_iops; +extern struct file_operations smfs_sym_fops; + +inline struct super_operations *cache_sops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_sb_ops; +} + +inline struct inode_operations *cache_diops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_dir_iops; +} + +inline struct inode_operations *cache_fiops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_file_iops; +} + +inline struct inode_operations *cache_siops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_sym_iops; +} + +inline struct file_operations *cache_dfops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_dir_fops; +} + +inline struct file_operations *cache_ffops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_file_fops; +} + +inline struct address_space_operations *cache_faops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_file_aops; +} + +inline struct file_operations *cache_sfops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_sym_fops; +} + +inline struct dentry_operations *cache_dops(struct sm_ops *smfs_ops) +{ + return &smfs_ops->sm_dentry_ops; +} + +void init_smfs_cache() +{ + memset(&smfs_operations, 0, sizeof(struct sm_ops)); +} +void cleanup_smfs_cache() +{ + +} + +static void setup_sm_symlink_ops(struct inode *cache_inode, + struct inode *inode, + struct inode_operations *cache_sym_iops, + struct file_operations *cache_sym_fops) +{ + return; +} + +static void setup_sm_file_ops(struct inode *cache_inode, + struct inode *inode, + struct inode_operations *cache_iops, + struct file_operations *cache_fops, + struct address_space_operations *cache_aops) +{ + + struct smfs_super_info *smb; + struct inode_operations *iops; + struct file_operations *fops; + struct address_space_operations *aops; + + smb = S2SMI(inode->i_sb); + + if (smb->ops_check & FILE_OPS_CHECK) + return; + smb->ops_check |= FILE_OPS_CHECK; + + iops = cache_fiops(&smfs_operations); + fops = cache_ffops(&smfs_operations); + aops = cache_faops(&smfs_operations); + + memset(iops , 0 , sizeof (struct inode_operations)); + memset(fops , 0 , sizeof (struct file_operations)); + memset(aops , 0 , sizeof (struct address_space_operations)); + + if (cache_inode->i_op) { + if (cache_inode->i_op->create) + iops->create = cache_iops->create; + if (cache_inode->i_op->create_it) + iops->create_it = cache_iops->create_it; + if (cache_inode->i_op->lookup) + iops->lookup = cache_iops->lookup; + if (cache_inode->i_op->lookup_raw) + iops->lookup_raw = cache_iops->lookup_raw; + if (cache_inode->i_op->lookup_it) + iops->lookup_it = cache_iops->lookup_it; + if (cache_inode->i_op->link) + iops->link = cache_iops->link; + if (cache_inode->i_op->link_raw) + iops->link_raw = cache_iops->link_raw; + if (cache_inode->i_op->unlink) + iops->unlink = cache_iops->unlink; + if (cache_inode->i_op->unlink_raw) + iops->unlink_raw = cache_iops->unlink_raw; + if (cache_inode->i_op->symlink) + iops->symlink = cache_iops->symlink; + if (cache_inode->i_op->symlink_raw) + iops->symlink_raw = cache_iops->symlink_raw; + if (cache_inode->i_op->mkdir) + iops->mkdir = cache_iops->mkdir; + if (cache_inode->i_op->mkdir_raw) + iops->mkdir_raw = cache_iops->mkdir_raw; + if (cache_inode->i_op->rmdir) + iops->rmdir = cache_iops->rmdir; + if (cache_inode->i_op->rmdir_raw) + iops->rmdir_raw = cache_iops->rmdir_raw; + if (cache_inode->i_op->mknod) + iops->mknod = cache_iops->mknod; + if (cache_inode->i_op->mknod_raw) + iops->mknod_raw = cache_iops->mknod_raw; + if (cache_inode->i_op->rename) + iops->rename = cache_iops->rename; + if (cache_inode->i_op->rename_raw) + iops->rename_raw = cache_iops->rename_raw; + if (cache_inode->i_op->readlink) + iops->readlink = cache_iops->readlink; + if (cache_inode->i_op->follow_link) + iops->follow_link = cache_iops->follow_link; + if (cache_inode->i_op->truncate) + iops->truncate = cache_iops->truncate; + if (cache_inode->i_op->permission) + iops->permission = cache_iops->permission; + if (cache_inode->i_op->revalidate) + iops->revalidate = cache_iops->revalidate; + if (cache_inode->i_op->revalidate_it) + iops->revalidate_it = cache_iops->revalidate_it; + if (cache_inode->i_op->setattr) + iops->setattr = cache_iops->setattr; + if (cache_inode->i_op->setattr_raw) + iops->setattr_raw = cache_iops->setattr_raw; + if (cache_inode->i_op->getattr) + iops->getattr = cache_iops->getattr; + if (cache_inode->i_op->setxattr) + iops->setxattr = cache_iops->setxattr; + if (cache_inode->i_op->getxattr) + iops->getxattr = cache_iops->getxattr; + if (cache_inode->i_op->listxattr) + iops->setxattr = cache_iops->setxattr; + if (cache_inode->i_op->removexattr) + iops->removexattr = cache_iops->removexattr; + } + if (cache_inode->i_fop) { + + } + if (cache_inode->i_mapping && cache_inode->i_mapping->a_ops) { + + } + return; +} +void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode) +{ + /* XXX now set the correct snap_{file,dir,sym}_iops */ + if (S_ISDIR(inode->i_mode)) { + inode->i_op = cache_diops(&smfs_operations); + inode->i_fop = cache_dfops(&smfs_operations); + } else if (S_ISREG(inode->i_mode)) { + if (!cache_fiops(&smfs_operations) ) { + setup_sm_file_ops(cache_inode, inode, + &smfs_file_iops, + &smfs_file_fops, + &smfs_file_aops); + } + CDEBUG(D_INODE, "inode %lu, i_op at %p\n", + inode->i_ino, inode->i_op); + inode->i_fop = cache_ffops(&smfs_operations); + inode->i_op = cache_fiops(&smfs_operations); + if (inode->i_mapping) + inode->i_mapping->a_ops = cache_faops(&smfs_operations); + + } + else if (S_ISLNK(inode->i_mode)) { + if (!cache_siops(&smfs_operations)) { + setup_sm_symlink_ops(cache_inode, inode, + &smfs_sym_iops, &smfs_sym_fops); + } + inode->i_op = cache_siops(&smfs_operations); + inode->i_fop = cache_sfops(&smfs_operations); + CDEBUG(D_INODE, "inode %lu, i_op at %p\n", + inode->i_ino, inode->i_op); + } +} + diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c new file mode 100644 index 0000000..b0108b2 --- /dev/null +++ b/lustre/smfs/dir.c @@ -0,0 +1,97 @@ +/* + * dir.c + */ +#define DEBUG_SUBSYSTEM S_SNAP + +#include +#include +#include +#include +#include +#include + +#include "smfs_internal.h" + +static void d_unalloc(struct dentry *dentry) +{ + if (dentry) { + list_del(&dentry->d_hash); + INIT_LIST_HEAD(&dentry->d_hash); + dput(dentry); + } +} +static struct inode *sm_create_inode(struct super_block *sb, + struct inode *cache_inode) +{ + struct inode *inode; + + inode = new_inode(sb); + if (inode) { + /*FIXME there are still some + * other attributes need to + * duplicated*/ + inode->i_ino = cache_inode->i_ino; + inode->i_mode = cache_inode->i_mode; + } + + return inode; +} + +static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode) +{ + atomic_set(&dentry->d_count, 1); + dentry->d_vfs_flags = 0; + dentry->d_flags = 0; + dentry->d_inode = inode; + dentry->d_op = NULL; + dentry->d_fsdata = NULL; + dentry->d_mounted = 0; + INIT_LIST_HEAD(&dentry->d_hash); + INIT_LIST_HEAD(&dentry->d_lru); + INIT_LIST_HEAD(&dentry->d_subdirs); + INIT_LIST_HEAD(&dentry->d_alias); +} + +static int smfs_create(struct inode *dir, + struct dentry *dentry, + int mode) +{ + struct inode *cache_dir; + struct inode *cache_inode, *inode; + struct dentry tmp; + struct dentry *cache_dentry; + int rc; + + ENTRY; + + cache_dir = I2CI(dir); + if (!cache_dir) + RETURN(-ENOENT); + + prepare_parent_dentry(&tmp, cache_dir); + cache_dentry = d_alloc(&tmp, &dentry->d_name); + + if (!cache_dentry) + RETURN(-ENOENT); + + if(cache_dir && cache_dir->i_op->create) + rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode); + if (rc) + GOTO(exit, rc); + + cache_inode = cache_dentry->d_inode; + inode = sm_create_inode(dir->i_sb, cache_inode); + + if (!inode) + GOTO(exit, rc); + + sm_setup_inode_ops(cache_inode, inode); +exit: + d_unalloc(cache_dentry); + RETURN(rc); +} + +struct inode_operations smfs_dir_fops = { + create: smfs_create, +}; + diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c new file mode 100644 index 0000000..37b86ed --- /dev/null +++ b/lustre/smfs/inode.c @@ -0,0 +1,72 @@ +/* + * fs/snap/snap.c + * + * A snap shot file system. + * + */ + +#define DEBUG_SUBSYSTEM S_SM + +#include +#include +#include +#include +#include +#include "smfs_internal.h" + + +static void smfs_read_inode(struct inode *inode) +{ + struct super_block *cache_sb; + struct inode *cache_inode; + ENTRY; + + if (!inode) + return; + + CDEBUG(D_INODE, "read_inode ino %lu\n", inode->i_ino); + cache_sb = S2CSB(inode->i_sb); + + cache_inode = new_inode(cache_sb); + I2CI(inode) = cache_inode; + + if(cache_sb && cache_sb->s_op->read_inode) + cache_sb->s_op->read_inode(cache_inode); + + CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", + inode->i_ino, atomic_read(&inode->i_count)); + + sm_setup_inode_ops(cache_inode, inode); + + CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", + inode->i_ino, atomic_read(&inode->i_count)); + + return; +} +/* Although some filesystem(such as ext3) do not have + * clear_inode method, but we need it to free the + * cache inode + */ +static void smfs_clear_inode(struct inode *inode) +{ + struct super_block *cache_sb; + struct inode *cache_inode; + + ENTRY; + + if (!inode) return; + + cache_sb = S2CSB(inode->i_sb); + cache_inode = I2CI(inode); + clear_inode(cache_inode); + return; +} +struct super_operations currentfs_super_ops = { + read_inode: smfs_read_inode, + clear_inode: smfs_clear_inode, +}; + + + + + diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h index 6150a93..fe6b574 100644 --- a/lustre/smfs/smfs_internal.h +++ b/lustre/smfs/smfs_internal.h @@ -7,13 +7,40 @@ struct smfs_inode_info { struct smfs_super_info { struct super_block *smsi_sb; - struct vfsmnt *smsi_mnt; /* mount the cache kere with kern_do_mount (like MDS) */ + struct vfsmount *smsi_mnt; /* mount the cache kere with kern_do_mount (like MDS) */ + int ops_check; }; #define I2SMI(inode) ((struct smfs_inode_info *) (&(inode->u.generic_ip))) #define S2SMI(sb) ((struct smfs_super_info *) (&(sb->u.generic_sbp))) +#define S2CSB(sb) (((struct smfs_super_info *) (&(sb->u.generic_sbp)))->smsi_sb) +#define I2CI(inode) (((struct smfs_inode_info*) (&(inode->u.generic_ip)))->smi_inode) + +#define SB_OPS_CHECK 0x1 +#define INODE_OPS_CHECK 0x2 +#define FILE_OPS_CHECK 0x4 +#define DENTRY_OPS_CHECK 0x8 +#define DEV_OPS_CHECK 0x10 +#define SYMLINK_OPS_CHECK 0x20 +#define DIR_OPS_CHECK 0x40 #include "smfs_support.h" +struct sm_ops { + /* operations on the file store */ + struct super_operations sm_sb_ops; + + struct inode_operations sm_dir_iops; + struct inode_operations sm_file_iops; + struct inode_operations sm_sym_iops; + + struct file_operations sm_dir_fops; + struct file_operations sm_file_fops; + struct file_operations sm_sym_fops; + + struct address_space_operations sm_file_aops; + struct dentry_operations sm_dentry_ops; +}; + struct option { char *opt; char *value; @@ -23,6 +50,12 @@ struct option { extern int get_opt(struct option **option, char **pos); extern void cleanup_option(void); extern int init_option(char *data); +/*cache.c*/ +void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode); +void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb); +void init_smfs_cache(void); +void cleanup_smfs_cache(void); + /*sysctl.c*/ extern int sm_debug_level; extern int sm_inodes; diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c index 8a86d82..53fe4f1 100644 --- a/lustre/smfs/super.c +++ b/lustre/smfs/super.c @@ -122,6 +122,7 @@ static int sm_mount_cache(struct super_block *sb, smb = S2SMI(sb); smb->smsi_sb = mnt->mnt_sb; smb->smsi_mnt = mnt; + sm_set_sb_ops(mnt->mnt_sb, sb); err_out: if (dev_name) SM_FREE(dev_name, strlen(dev_name) + 2); @@ -165,7 +166,6 @@ smfs_read_super( GOTO(out_err, 0); } /* set up the super block */ - sb->s_op = &smfs_super_ops; bottom_root = dget(S2SMI(sb)->smsi_sb->s_root); if (!bottom_root) { @@ -200,23 +200,25 @@ static DECLARE_FSTYPE(smfs_type, "smfs", smfs_read_super, 0); int init_smfs(void) { - int err; + int err = 0; err = register_filesystem(&smfs_type); if (err) { CERROR("smfs: failed in register Storage Management filesystem!\n"); } + init_smfs_cache(); return err; } int cleanup_smfs(void) { - int err; + int err = 0; ENTRY; err = unregister_filesystem(&smfs_type); if (err) { CERROR("smfs: failed to unregister Storage Management filesystem!\n"); } + cleanup_smfs_cache(); return 0; } -- 1.8.3.1