diff --git a/lustre/smfs/cache.c b/lustre/smfs/cache.c index 8117b914146b5874af3534be2bfeff72e32dd91c..08d579fd87e2b5193669c3b6a2542cf004605e1b 100644 --- a/lustre/smfs/cache.c +++ b/lustre/smfs/cache.c @@ -74,41 +74,12 @@ void cleanup_smfs_cache() return; } -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) +static void setup_iops(struct inode *cache_inode, + struct inode_operations *iops, + struct inode_operations *cache_iops) { - - 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 && cache_iops && iops) { if (cache_inode->i_op->create) iops->create = cache_iops->create; if (cache_inode->i_op->create_it) @@ -174,12 +145,163 @@ static void setup_sm_file_ops(struct inode *cache_inode, if (cache_inode->i_op->removexattr) iops->removexattr = cache_iops->removexattr; } - if (cache_inode->i_fop) { +} +static void setup_fops(struct inode *cache_inode, + struct file_operations *fops, + struct file_operations *cache_fops) +{ + if (cache_inode->i_fop && cache_fops && fops) { + if (cache_inode->i_fop->llseek) + fops->llseek = cache_fops->llseek; + if (cache_inode->i_fop->read) + fops->read = cache_fops->read; + if (cache_inode->i_fop->write) + fops->write = cache_fops->write; + if (cache_inode->i_fop->readdir) + fops->readdir = cache_fops->readdir; + if (cache_inode->i_fop->poll) + fops->poll = cache_fops->poll; + if (cache_inode->i_fop->ioctl) + fops->ioctl = cache_fops->ioctl; + if (cache_inode->i_fop->mmap) + fops->mmap = cache_fops->mmap; + if (cache_inode->i_fop->open) + fops->open = cache_fops->open; + if (cache_inode->i_fop->flush) + fops->flush = cache_fops->flush; + if (cache_inode->i_fop->release) + fops->release = cache_fops->release; + if (cache_inode->i_fop->fsync) + fops->fsync = cache_fops->fsync; + if (cache_inode->i_fop->fasync) + fops->fasync = cache_fops->fasync; + if (cache_inode->i_fop->lock) + fops->lock = cache_fops->lock; + if (cache_inode->i_fop->readv) + fops->readv = cache_fops->readv; + if (cache_inode->i_fop->writev) + fops->writev = cache_fops->writev; + if (cache_inode->i_fop->sendpage) + fops->sendpage = cache_fops->sendpage; + if (cache_inode->i_fop->get_unmapped_area) + fops->get_unmapped_area = cache_fops->get_unmapped_area; + } +} +static void setup_aops(struct inode *cache_inode, + struct address_space_operations *aops, + struct address_space_operations *cache_aops) +{ + if (cache_inode && cache_inode->i_mapping && + aops && cache_aops) { + struct address_space_operations *caops = cache_inode->i_mapping->a_ops; + + if (caops->writepage) + aops->writepage = cache_aops->writepage; + if (caops->readpage) + aops->readpage = cache_aops->readpage; + if (caops->sync_page) + aops->sync_page = cache_aops->sync_page; + if (caops->prepare_write) + aops->prepare_write = cache_aops->prepare_write; + if (caops->commit_write) + aops->commit_write = cache_aops->commit_write; + if (caops->bmap) + aops->bmap = cache_aops->bmap; + if (caops->flushpage) + aops->flushpage = cache_aops->flushpage; + if (caops->releasepage) + aops->releasepage = cache_aops->releasepage; + if (caops->direct_IO) + aops->direct_IO = cache_aops->direct_IO; + if (caops->removepage) + aops->removepage = cache_aops->removepage; + } +}; + +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) +{ - } - if (cache_inode->i_mapping && cache_inode->i_mapping->a_ops) { + 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)); + + setup_iops(cache_inode, iops, cache_iops); + setup_fops(cache_inode, fops, cache_fops); + setup_aops(cache_inode, aops, cache_aops); + + return; +} + +static void setup_sm_dir_ops(struct inode *cache_inode, + struct inode *inode, + struct inode_operations *cache_dir_iops, + struct file_operations *cache_dir_fops) +{ + struct smfs_super_info *smb; + struct inode_operations *iops; + struct file_operations *fops; + + smb = S2SMI(inode->i_sb); + + if (smb->ops_check & DIR_OPS_CHECK) + return; + smb->ops_check |= DIR_OPS_CHECK; + + iops = cache_diops(&smfs_operations); + fops = cache_dfops(&smfs_operations); + + memset(iops, 0, sizeof (struct inode_operations)); + memset(fops, 0, sizeof (struct file_operations)); + + setup_iops(cache_inode, iops, cache_dir_iops); + setup_fops(cache_inode, fops, cache_dir_fops); + + return; +} + +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) +{ + struct smfs_super_info *smb; + struct inode_operations *iops; + struct file_operations *fops; + + smb = S2SMI(inode->i_sb); + + if (smb->ops_check & SYMLINK_OPS_CHECK) + return; + smb->ops_check |= SYMLINK_OPS_CHECK; + + iops = cache_siops(&smfs_operations); + fops = cache_sfops(&smfs_operations); + + memset(iops , 0 , sizeof (struct inode_operations)); + memset(fops , 0 , sizeof (struct file_operations)); + + setup_iops(cache_inode, iops, cache_sym_iops); + setup_fops(cache_inode, fops, cache_sym_fops); + return; } @@ -236,14 +358,17 @@ static void setup_sm_sb_ops(struct super_block *cache_sb, if (cache_sb->s_op->show_options) sops->show_options = smfs_sops->show_options; } - + return; } void sm_set_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); + setup_sm_dir_ops(cache_inode, inode, + &smfs_dir_iops, + &smfs_dir_fops); + inode->i_op = cache_diops(&smfs_operations); inode->i_fop = cache_dfops(&smfs_operations); } else if (S_ISREG(inode->i_mode)) { setup_sm_file_ops(cache_inode, inode, @@ -256,9 +381,8 @@ void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode) 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)) { + + } else if (S_ISLNK(inode->i_mode)) { setup_sm_symlink_ops(cache_inode, inode, &smfs_sym_iops, &smfs_sym_fops); diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index 3583f7be9c6a6e18163513129dab14140c25fab7..378df892afc86d6d309ddfc717af6a5f1b036da3 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -90,8 +90,48 @@ exit: d_unalloc(cache_dentry); RETURN(rc); } +static struct dentry *smfs_lookup(struct inode *dir, + struct dentry *dentry) +{ + struct inode *cache_dir; + struct inode *cache_inode, *inode; + struct dentry tmp; + struct dentry *cache_dentry; + struct dentry *rc = NULL; + + ENTRY; + + cache_dir = I2CI(dir); + if (!cache_dir) + RETURN(ERR_PTR(-ENOENT)); + prepare_parent_dentry(&tmp, cache_dir); + cache_dentry = d_alloc(&tmp, &dentry->d_name); + + if (!cache_dentry) + RETURN(ERR_PTR(-ENOENT)); -struct inode_operations smfs_dir_fops = { - create: smfs_create, -}; + if(cache_dir && cache_dir->i_op->lookup) + rc = cache_dir->i_op->lookup(cache_dir, cache_dentry); + + if (rc || !cache_dentry->d_inode || + is_bad_inode(cache_dentry->d_inode) || + IS_ERR(cache_dentry->d_inode)) { + GOTO(exit, rc); + } + cache_inode = cache_dentry->d_inode; + + inode = iget(dir->i_sb, cache_inode->i_ino); + + d_add(dentry, inode); +exit: + d_unalloc(cache_dentry); + RETURN(rc); +} +struct inode_operations smfs_dir_iops = { + create: smfs_create, + lookup: smfs_lookup, +}; +struct file_operations smfs_dir_fops = { + +}; diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index d9267de384654ca7e844822da68dd822a6e3e598..4057f941892d1cdcc07426fa4fcb085f87f7f5bc 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -50,15 +50,13 @@ 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); - CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", - inode->i_ino, atomic_read(&inode->i_count)); - duplicate_inode(cache_inode, inode); sm_set_inode_ops(cache_inode, inode); CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", inode->i_ino, atomic_read(&inode->i_count)); + iput(cache_inode); return; } /* Although some filesystem(such as ext3) do not have diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c index a47e644a1536d7752661b8f750e66b471e487616..2a4d1dcd6848d9927fe509e3eadc5b05365e510c 100644 --- a/lustre/smfs/super.c +++ b/lustre/smfs/super.c @@ -190,6 +190,14 @@ static char *parse_path2dev(struct super_block *sb, char *dev_path) memcpy(name, dev_path, strlen(dev_path) + 1); RETURN(name); } +static void duplicate_sb(struct super_block *csb, + struct super_block *sb) +{ + sb->s_blocksize = csb->s_blocksize; + sb->s_magic = csb->s_magic; + sb->s_blocksize_bits = csb->s_blocksize_bits; + sb->s_maxbytes = csb->s_maxbytes; +} extern struct super_operations smfs_super_ops; static int sm_mount_cache(struct super_block *sb, @@ -222,6 +230,8 @@ static int sm_mount_cache(struct super_block *sb, smb = S2SMI(sb); smb->smsi_sb = mnt->mnt_sb; smb->smsi_mnt = mnt; + + duplicate_sb(mnt->mnt_sb, sb); sm_set_sb_ops(mnt->mnt_sb, sb); err_out: if (dev_name) @@ -234,6 +244,7 @@ static int sm_umount_cache(struct super_block *sb) struct smfs_super_info *smb = S2SMI(sb); mntput(smb->smsi_mnt); + return 0; } void smfs_put_super(struct super_block *sb) @@ -249,8 +260,6 @@ smfs_read_super( void *data, int silent) { - struct smfs_inode_info *smi; - struct dentry *bottom_root; struct inode *root_inode = NULL; char *devstr = NULL, *typestr = NULL; char *cache_data; @@ -278,19 +287,10 @@ smfs_read_super( CERROR("Can not mount %s as %s\n", devstr, typestr); GOTO(out_err, 0); } - /* set up the super block */ - - bottom_root = dget(S2SMI(sb)->smsi_sb->s_root); - if (!bottom_root) { - CERROR("bottom not mounted\n"); - GOTO(out_err, err=-ENOENT); - } - root_ino = bottom_root->d_inode->i_ino; + root_ino = S2CSB(sb)->s_root->d_inode->i_ino; root_inode = iget(sb, root_ino); - smi = I2SMI(root_inode); - /*FIXME Intialize smi here*/ - + CDEBUG(D_SUPER, "readinode %p, root ino %ld, root inode at %p\n", sb->s_op->read_inode, root_ino, root_inode); @@ -299,13 +299,11 @@ smfs_read_super( if (!sb->s_root) { GOTO(out_err, err=-EINVAL); } - + CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n", (ulong) sb, (ulong) &sb->u.generic_sbp); - out_err: - if (root_inode) - iput(root_inode); +out_err: cleanup_option(); if (err) return NULL;