From fca50869babc9baca284b5c4392581ca739ef3ed Mon Sep 17 00:00:00 2001 From: wangdi Date: Thu, 19 Aug 2004 16:45:48 +0000 Subject: [PATCH] update .snap on smfs --- lustre/include/linux/lustre_smfs.h | 8 +- lustre/lvfs/fsfilt_smfs.c | 5 +- lustre/lvfs/fsfilt_snap_ext3.c | 12 +- lustre/lvfs/fsfilt_snap_smfs.c | 4 +- lustre/smfs/dir.c | 62 ++++--- lustre/smfs/file.c | 14 +- lustre/smfs/inode.c | 21 ++- lustre/smfs/ioctl.c | 1 - lustre/smfs/kml.c | 16 +- lustre/smfs/smfs_cow.c | 321 ++++++++++++++++++++++--------------- lustre/smfs/smfs_internal.h | 5 +- lustre/smfs/smfs_lib.c | 1 - lustre/smfs/symlink.c | 4 +- 13 files changed, 261 insertions(+), 213 deletions(-) diff --git a/lustre/include/linux/lustre_smfs.h b/lustre/include/linux/lustre_smfs.h index 710569c..ac5f5f3 100644 --- a/lustre/include/linux/lustre_smfs.h +++ b/lustre/include/linux/lustre_smfs.h @@ -412,15 +412,11 @@ static inline void smfs_free_dentry_name(struct qstr *str) static inline struct dentry *pre_smfs_dentry(struct dentry *parent_dentry, struct inode *cache_inode, - struct dentry *dentry, - int *index) + struct dentry *dentry) { struct dentry *cache_dentry = NULL; - struct qstr name; - smfs_get_dentry_name_index(dentry, &name, index); - cache_dentry = d_alloc(parent_dentry, &name); - smfs_free_dentry_name(&name); + cache_dentry = d_alloc(parent_dentry, &dentry->d_name); if (!cache_dentry) RETURN(NULL); if (!parent_dentry) diff --git a/lustre/lvfs/fsfilt_smfs.c b/lustre/lvfs/fsfilt_smfs.c index 9661a6a..f986514 100644 --- a/lustre/lvfs/fsfilt_smfs.c +++ b/lustre/lvfs/fsfilt_smfs.c @@ -76,8 +76,7 @@ static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso, return NULL; cache_inode = I2CI(fso->fso_dentry->d_inode); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry, - NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry); if (!cache_dentry) GOTO(exit, rc = ERR_PTR(-ENOMEM)); @@ -171,7 +170,7 @@ static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle, cache_inode = I2CI(dentry->d_inode); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) GOTO(exit, rc = -ENOMEM); diff --git a/lustre/lvfs/fsfilt_snap_ext3.c b/lustre/lvfs/fsfilt_snap_ext3.c index 546b44e..e1ef83d 100644 --- a/lustre/lvfs/fsfilt_snap_ext3.c +++ b/lustre/lvfs/fsfilt_snap_ext3.c @@ -176,7 +176,7 @@ static struct inode *fsfilt_ext3_get_indirect(struct inode *primary, int *table, struct snap_ea *snaps; ino_t ino; struct inode *inode = NULL; - int rc = 0, index = 0; + int rc = 0; ENTRY; @@ -197,16 +197,14 @@ static struct inode *fsfilt_ext3_get_indirect(struct inode *primary, int *table, /* if table is NULL and there is a slot */ if( !table && slot >= 0) { - index = slot; - ino = le32_to_cpu(snaps->ino[index]); + ino = le32_to_cpu(snaps->ino[slot]); if(ino) inode = iget(primary->i_sb, ino); GOTO(err_free, rc); } /* if table is not NULL */ - while (!inode && slot >= 0 && table) { - index = table[slot]; - ino = le32_to_cpu(snaps->ino[index]); + while (!inode && slot >= 0 ) { + ino = le32_to_cpu(snaps->ino[slot]); CDEBUG(D_INODE, "snap inode at slot %d is %lu\n", slot, ino); if (!ino) { @@ -216,7 +214,7 @@ static struct inode *fsfilt_ext3_get_indirect(struct inode *primary, int *table, inode = iget(primary->i_sb, ino); GOTO(err_free, rc); } - if( slot == -1 && table ) { + if( slot == -1) { CDEBUG(D_INODE, "redirector not found, using primary\n"); inode = iget(primary->i_sb, primary->i_ino); } diff --git a/lustre/lvfs/fsfilt_snap_smfs.c b/lustre/lvfs/fsfilt_snap_smfs.c index ac32239..268db4b 100644 --- a/lustre/lvfs/fsfilt_snap_smfs.c +++ b/lustre/lvfs/fsfilt_snap_smfs.c @@ -371,11 +371,11 @@ static int fsfilt_smfs_get_snap_info(struct inode *inode, void *key, static int fsfilt_smfs_read_dotsnap_dir_page(struct file *file, char *buf, size_t count, loff_t *off) { +#if 0 struct inode *inode = file->f_dentry->d_inode; struct fsfilt_operations *snap_cops = I2SNAPCOPS(inode); int i = 0, size = 0, off_count = 0, buf_off = 0, rc = 0; ENTRY; -#if 0 /*Get the offset of dir ent*/ //struct snap_table *stbl = S2SNAPI(inode->i_sb)->sni_table; while (size < *off && off_count < stbl->sntbl_count) { @@ -400,7 +400,7 @@ static int fsfilt_smfs_read_dotsnap_dir_page(struct file *file, char *buf, #else #warning "still not implement read .snap dir page for fsfilt Wangdi" #endif - RETURN(rc); + RETURN(0); } struct fsfilt_operations fsfilt_smfs_snap_ops = { diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index d964ba2..a9c2434 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -69,8 +69,8 @@ static int smfs_create(struct inode *dir, struct dentry *dentry, lock_kernel(); SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle, PRE_HOOK, rc, exit); - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry); + cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry); if (!cache_dentry || !cache_parent) GOTO(exit, rc = -ENOMEM); @@ -88,8 +88,7 @@ static int smfs_create(struct inode *dir, struct dentry *dentry, if (rc) GOTO(exit, rc); - SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, - rc, exit); + SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); d_instantiate(dentry, inode); post_smfs_inode(dir, cache_dir); @@ -118,7 +117,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry, struct dentry *cache_parent = NULL; struct dentry *rc = NULL; void *handle = NULL; - int rc2 = 0, index = 0; + int rc2 = 0; ENTRY; @@ -126,8 +125,8 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry, RETURN(ERR_PTR(-ENOENT)); /* preparing artificial backing fs dentries. */ - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, &index); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent); + cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry); if (!cache_dentry || !cache_parent) GOTO(exit, rc = ERR_PTR(-ENOMEM)); @@ -135,7 +134,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry, if (!cache_dir && cache_dir->i_op->lookup) GOTO(exit, rc = ERR_PTR(-ENOENT)); - SMFS_HOOK(dir, dentry, &index, NULL, HOOK_LOOKUP, handle, + SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, PRE_HOOK, rc2, exit); /* perform lookup in backing fs. */ @@ -152,8 +151,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry, dentry->d_inode = cache_inode; GOTO(exit, rc = NULL); } - SMFS_GET_INODE(dir->i_sb, cache_inode, dir, index, inode, rc2, - exit); + SMFS_GET_INODE(dir->i_sb, cache_inode, dir, inode, rc2, exit); } else { d_add(dentry, NULL); GOTO(exit, rc); @@ -197,14 +195,13 @@ static int smfs_link(struct dentry * old_dentry, SMFS_HOOK(dir, old_dentry, NULL, NULL, HOOK_LINK, handle, PRE_HOOK, rc, exit); - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry); + cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry); if (!cache_parent || !cache_dentry) GOTO(exit, rc = -ENOMEM); - cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode, - old_dentry, NULL); + cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode, old_dentry); if (!cache_old_dentry) GOTO(exit, rc = -ENOMEM); @@ -254,8 +251,8 @@ static int smfs_unlink(struct inode * dir, SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_UNLINK, handle, PRE_HOOK, rc, exit); - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry, NULL); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry); + cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry); if (!cache_parent || !cache_dentry) GOTO(exit, rc = -ENOMEM); @@ -299,8 +296,8 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry, SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_SYMLINK, handle, PRE_HOOK, rc, exit); - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry); + cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry); if (!cache_parent || !cache_dentry) GOTO(exit, rc = -ENOMEM); @@ -311,8 +308,7 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry, post_smfs_inode(dir, cache_dir); - SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, - rc, exit); + SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); if (inode) d_instantiate(dentry, inode); else @@ -352,8 +348,8 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry, SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, PRE_HOOK, rc, exit); - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry); + cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry); if (!cache_parent || !cache_dentry) GOTO(exit, rc = -ENOMEM); @@ -366,8 +362,7 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry, if (rc) GOTO(exit, rc); - SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, - rc, exit); + SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); d_instantiate(dentry, inode); post_smfs_inode(dir, cache_dir); @@ -404,8 +399,8 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry) SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_RMDIR, handle, PRE_HOOK, rc, exit); - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry, NULL); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry); + cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry); if (!cache_parent || !cache_dentry) GOTO(exit, rc = -ENOMEM); @@ -456,8 +451,8 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry, SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, PRE_HOOK, rc, exit); - cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent, NULL); - cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry, NULL); + cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent); + cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry); if (!cache_parent || !cache_dentry) GOTO(exit, rc = -ENOMEM); @@ -471,8 +466,7 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry, mode, rdev))) GOTO(exit, rc); - SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, 0, inode, - rc, exit); + SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); d_instantiate(dentry, inode); @@ -521,15 +515,15 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry, SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME, handle, PRE_HOOK, rc, exit); - cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry, NULL); + cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry); cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode, - old_dentry, NULL); + old_dentry); if (!cache_old_parent || !cache_old_dentry) GOTO(exit, rc = -ENOMEM); - cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry, NULL); + cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry); cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode, - new_dentry, NULL); + new_dentry); if (!cache_new_parent || !cache_new_dentry) GOTO(exit, rc = -ENOMEM); diff --git a/lustre/smfs/file.c b/lustre/smfs/file.c index 37e9d63..45602dd 100644 --- a/lustre/smfs/file.c +++ b/lustre/smfs/file.c @@ -242,7 +242,7 @@ static int smfs_init_cache_file(struct inode *inode, struct file *filp) sfi->magic = SMFS_FILE_MAGIC; - cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry); if (!cache_dentry) GOTO(err_exit, rc = -ENOMEM); @@ -350,7 +350,7 @@ int smfs_fsync(struct file *file, struct dentry *dentry, int datasync) if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) RETURN(-ENOMEM); @@ -418,7 +418,7 @@ int smfs_setattr(struct dentry *dentry, struct iattr *attr) if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) RETURN(-ENOMEM); @@ -454,7 +454,7 @@ int smfs_setxattr(struct dentry *dentry, const char *name, const void *value, if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) RETURN(-ENOMEM); @@ -481,7 +481,7 @@ int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer, if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) RETURN(-ENOMEM); @@ -507,7 +507,7 @@ ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size) if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) RETURN(-ENOMEM); @@ -532,7 +532,7 @@ int smfs_removexattr(struct dentry *dentry, const char *name) if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) RETURN(-ENOMEM); diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index 8ed305c..59badd4 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -42,10 +42,7 @@ static void smfs_init_inode_info (struct inode *inode, void *opaque) struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque; struct inode *cache_inode = NULL; - if (sargs) - cache_inode = iget(S2CSB(inode->i_sb), sargs->s_ino); - else - cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino); + cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino); OBD_ALLOC(I2SMI(inode), sizeof(struct smfs_inode_info)); LASSERT(I2SMI(inode)); @@ -60,11 +57,6 @@ static void smfs_init_inode_info (struct inode *inode, void *opaque) if (dir) I2SMI(inode)->smi_flags = I2SMI(dir)->smi_flags; -#if CONFIG_SNAPFS - if (SMFS_DO_COW(S2SMI(inode->i_sb))) { - smfs_init_snap_inode_info(inode, sargs); - } -#endif } } @@ -101,8 +93,15 @@ static int smfs_test_inode(struct inode *inode, unsigned long ino, static int smfs_test_inode(struct inode *inode, void *opaque) #endif { - if (!opaque) + struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque; + + LASSERT(sargs); + if (!sargs) return 1; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + if (inode->i_ino != sargs->s_ino) + return 0; +#endif #ifdef CONFIG_SNAPFS if (SMFS_DO_COW(S2SMI(inode->i_sb)) && !smfs_snap_test_inode(inode, opaque)) @@ -131,8 +130,6 @@ struct inode *smfs_iget(struct super_block *sb, ino_t hash, unlock_new_inode(inode); CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino, inode->i_generation, inode); - - inode->i_ino = hash; } return inode; } diff --git a/lustre/smfs/ioctl.c b/lustre/smfs/ioctl.c index 0a3019a..82413c3 100644 --- a/lustre/smfs/ioctl.c +++ b/lustre/smfs/ioctl.c @@ -50,7 +50,6 @@ static struct super_block *smfs_get_sb_by_path(char *path, int len) { struct super_block *sb; struct nameidata nd; - int error = 0; ENTRY; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) diff --git a/lustre/smfs/kml.c b/lustre/smfs/kml.c index 8275ba2..242c0e2 100644 --- a/lustre/smfs/kml.c +++ b/lustre/smfs/kml.c @@ -68,31 +68,29 @@ int smfs_rec_init(struct super_block *sb) SMFS_SET_REC(smfs_info); - ost_rec_pack_init(sb); - mds_rec_pack_init(sb); + ost_rec_pack_init(smfs_info); + mds_rec_pack_init(smfs_info); rec_hops = smfs_alloc_hook_ops(KML_HOOK, NULL, smfs_rec_post_hook); if (!rec_hops) { RETURN(-ENOMEM); } - - rc = smfs_register_hook_ops(sb, rec_hops); - + rc = smfs_register_hook_ops(smfs_info, rec_hops); if (rc && rec_hops) { - smfs_unregister_hook_ops(sb, rec_hops->smh_name); + smfs_unregister_hook_ops(smfs_info, rec_hops->smh_name); smfs_free_hook_ops(rec_hops); } RETURN(rc); } -int smfs_rec_cleanup(struct super_block *sb) +int smfs_rec_cleanup(struct smfs_super_info *smfs_info) { struct smfs_hook_ops *rec_hops; int rc = 0; - rec_hops = smfs_unregister_hook_ops(sb, KML_HOOK); + rec_hops = smfs_unregister_hook_ops(smfs_info, KML_HOOK); smfs_free_hook_ops(rec_hops); - SMFS_CLEAN_REC(S2SMI(sb)); + SMFS_CLEAN_REC(smfs_info); RETURN(rc); } diff --git a/lustre/smfs/smfs_cow.c b/lustre/smfs/smfs_cow.c index 84c30c0..8505482 100644 --- a/lustre/smfs/smfs_cow.c +++ b/lustre/smfs/smfs_cow.c @@ -128,6 +128,95 @@ out_up: return dchild; } +static struct snap_info *smfs_find_snap_info(struct inode *inode) +{ + struct snap_inode_info *snap_iinfo = I2SNAPI(inode); + struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb); + struct snap_info *snap_info = NULL, *tmp; + + ENTRY; + list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list, + sni_list) { + if (snap_info->sni_root_ino == snap_iinfo->sn_root_ino) + RETURN(snap_info); + } + RETURN(NULL); +} + +static int smfs_dotsnap_dir_size(struct inode *inode) +{ + struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb); + struct fsfilt_operations *snapops = snap_sinfo->snap_cache_fsfilt; + int size = 0, dir_size = 0, blocks, i = 0; + struct snap_table *snap_table = NULL; + struct snap_info *snap_info = NULL; + ENTRY; + + snap_info = smfs_find_snap_info(inode); + + if (!snap_info) { + CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode); + RETURN(0); + } + snap_table = snap_info->sni_table; + for (i = 0; i < snap_table->sntbl_count; i++) { + char *name = snap_table->sntbl_items[i].sn_name; + size += snapops->fs_dir_ent_size(name); + } + /*FIXME this is only for ext3 dir format, may need fix for other FS*/ + blocks = (size + inode->i_sb->s_blocksize - 1) >> + inode->i_sb->s_blocksize_bits; + + dir_size = blocks * inode->i_sb->s_blocksize; + RETURN(dir_size); + +} + +static int smfs_init_snap_inode_info(struct inode *inode, struct inode *dir, int index) +{ + int rc = 0; + ENTRY; + + if (dir) { + I2SNAPI(inode)->sn_flags = I2SNAPI(dir)->sn_flags; + I2SNAPI(inode)->sn_gen = I2SNAPI(dir)->sn_gen; + I2SNAPI(inode)->sn_root_ino = I2SNAPI(dir)->sn_root_ino; + I2SNAPI(inode)->sn_index = I2SNAPI(inode)->sn_index; + } else { + I2SNAPI(inode)->sn_flags = 0; + I2SNAPI(inode)->sn_gen = 0; + } + + I2SNAPI(inode)->sn_index = index; + + if (smfs_dotsnap_inode(inode)) { + struct snap_info *snap_info; + + snap_info = smfs_find_snap_info(inode); + if (!snap_info) { + RETURN(-EIO); + } + /*init dot_snap inode info*/ + inode->i_size = (loff_t)smfs_dotsnap_dir_size(inode); + inode->i_nlink = snap_info->sni_table->sntbl_count + 2; + inode->i_uid = 0; + inode->i_gid = 0; + } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) && + (I2SMI(inode)->smi_flags & SM_DO_COW) && + smfs_primary_inode(inode)) { + struct snap_inode_info *sni_info = I2SNAPI(inode); + struct fsfilt_operations *sops = I2SNAPCOPS(inode); + int vallen = 0; + + vallen = sizeof(sni_info->sn_gen); + + rc = sops->fs_get_snap_info(I2CI(inode), SNAP_GENERATION, + strlen(SNAP_GENERATION), + &sni_info->sn_gen, &vallen); + } + RETURN(rc); +} + #define COWED_NAME_LEN (7 + 8 + 1) static int smfs_init_cowed_dir(struct snap_info *snap_info, struct dentry* dir) { @@ -265,13 +354,19 @@ static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo, GOTO(exit, snap_info = ERR_PTR(rc)); /*set cow flags for the snap root inode*/ - I2SMI(dentry->d_inode)->smi_flags |= SM_DO_COW; + I2SMI(dentry->d_inode)->smi_flags |= SM_DO_COW; + I2SNAPI(dentry->d_inode)->sn_root_ino = dentry->d_inode->i_ino; exit: if (rc) OBD_FREE(snap_info, sizeof(struct snap_info)); RETURN(snap_info); } +static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir, + void *new_dentry, int op); + +static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir, + void *new_dentry, int op); #define COW_HOOK "cow_hook" static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry, void *data1, void *data2, int op, void *handle) @@ -279,11 +374,29 @@ static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry, int rc = 0; ENTRY; - if (smfs_do_cow(inode)) { - rc = smfs_cow(inode, dentry, data1, data2, op); + if (smfs_do_cow(inode)) { + /*FIXME:WANGDI, get index from the dentry*/ + #if 0 + int index = 0; + smfs_get_dentry_name_index(dentry, &name, index); + smfs_free_dentry_name(&name); + #endif + rc = smfs_cow_pre(inode, dentry, data1, data2, op); } RETURN(rc); } +static int smfs_cow_post_hook(struct inode *inode, struct dentry *dentry, + void *data1, void *data2, int op, void *handle) +{ + int rc = 0; + ENTRY; + + if (smfs_do_cow(inode)) { + rc = smfs_cow_post(inode, dentry, data1, data2, op); + } + RETURN(rc); +} + int smfs_cow_init(struct super_block *sb) { struct smfs_super_info *smfs_info = S2SMI(sb); @@ -296,7 +409,8 @@ int smfs_cow_init(struct super_block *sb) SMFS_SET_COW(smfs_info); - cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook, NULL); + cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook, + smfs_cow_post_hook); if (!cow_hops) { RETURN(-ENOMEM); } @@ -345,15 +459,16 @@ int smfs_cow_init(struct super_block *sb) struct dentry *dentry; root_inode = smfs_get_inode(sb, root_ino, NULL, 0); - dentry = pre_smfs_dentry(NULL, root_inode, tmp, - NULL); + smfs_init_snap_inode_info(root_inode, NULL, 0); + dentry = pre_smfs_dentry(NULL, root_inode, tmp); snap_info = smfs_create_snap_info(S2SMI(sb), dentry); post_smfs_dentry(dentry); if (IS_ERR(snap_info)) { OBD_FREE(snap_root, sizeof(int) * snap_count); GOTO(exit, rc = PTR_ERR(snap_info)); } - list_add(&snap_info->sni_list, &(S2SNAPI(sb)->snap_list)); + list_add(&snap_info->sni_list, + &(S2SNAPI(sb)->snap_list)); } } exit: @@ -432,48 +547,6 @@ int smfs_cow_cleanup(struct smfs_super_info *smb) RETURN(rc); } -static struct snap_info *smfs_find_snap_info(struct inode *inode) -{ - struct snap_inode_info *snap_iinfo = I2SNAPI(inode); - struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb); - struct snap_info *snap_info = NULL, *tmp; - - ENTRY; - list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list, - sni_list) { - if (snap_info->sni_root_ino == snap_iinfo->sn_root_ino) - RETURN(snap_info); - } - RETURN(NULL); -} -static int smfs_dotsnap_dir_size(struct inode *inode) -{ - struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb); - struct fsfilt_operations *snapops = snap_sinfo->snap_cache_fsfilt; - int size = 0, dir_size = 0, blocks, i = 0; - struct snap_table *snap_table = NULL; - struct snap_info *snap_info = NULL; - ENTRY; - - snap_info = smfs_find_snap_info(inode); - - if (!snap_info) { - CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode); - RETURN(0); - } - snap_table = snap_info->sni_table; - for (i = 0; i < snap_table->sntbl_count; i++) { - char *name = snap_table->sntbl_items[i].sn_name; - size += snapops->fs_dir_ent_size(name); - } - /*FIXME this is only for ext3 dir format, may need fix for other FS*/ - blocks = (size + inode->i_sb->s_blocksize - 1) >> - inode->i_sb->s_blocksize_bits; - - dir_size = blocks * inode->i_sb->s_blocksize; - RETURN(dir_size); - -} int smfs_snap_test_inode(struct inode *inode, void *args) { struct smfs_iget_args *sargs = (struct smfs_iget_args*)args; @@ -483,63 +556,15 @@ int smfs_snap_test_inode(struct inode *inode, void *args) dir = sargs->s_inode; - if (dir){ - if (I2SNAPI(inode)->sn_index != I2SNAPI(dir)->sn_index) - return 0; - } else { + if (sargs->s_index > 0) { if (I2SNAPI(inode)->sn_index != sargs->s_index) - return 0; + return 0; + }else { + if (dir && I2SNAPI(inode)->sn_index != I2SNAPI(dir)->sn_index) + return 0; } return 1; } - -/*FIXME Note indirect and primary inode -* should be recorgnized here*/ -int smfs_init_snap_inode_info(struct inode *inode, struct smfs_iget_args *args) -{ - struct inode *dir; - int vallen, rc = 0; - ENTRY; - - LASSERT(args); - - I2SNAPI(inode)->sn_index = args->s_index; - - dir = args->s_inode; - if (dir) { - I2SNAPI(inode)->sn_flags = I2SNAPI(dir)->sn_flags; - I2SNAPI(inode)->sn_gen = I2SNAPI(dir)->sn_gen; - } else { - I2SNAPI(inode)->sn_flags = 0; - I2SNAPI(inode)->sn_gen = 0; - } - - if (smfs_dotsnap_inode(inode)) { - struct snap_info *snap_info; - - snap_info = smfs_find_snap_info(inode); - if (!snap_info) { - RETURN(-EIO); - } - /*init dot_snap inode info*/ - inode->i_size = (loff_t)smfs_dotsnap_dir_size(inode); - inode->i_nlink = snap_info->sni_table->sntbl_count + 2; - inode->i_uid = 0; - inode->i_gid = 0; - } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) && - (I2SMI(inode)->smi_flags & SM_DO_COW) && - smfs_primary_inode(inode)) { - struct snap_inode_info *sni_info = I2SNAPI(inode); - struct fsfilt_operations *sops = I2SNAPCOPS(inode); - - vallen = sizeof(sni_info->sn_gen); - - rc = sops->fs_get_snap_info(I2CI(inode), SNAP_GENERATION, - strlen(SNAP_GENERATION), - &sni_info->sn_gen, &vallen); - } - RETURN(rc); -} /* latest snap: returns - the index of the latest snapshot before NOW - hence it returns 0 in case all the volume snapshots lie in the future @@ -799,7 +824,7 @@ static int link_cowed_inode(struct inode *inode) LASSERT(dchild->d_inode == inode); GOTO(out_dput, rc = 0); } - tmp = pre_smfs_dentry(NULL, inode, cowed_dir, NULL); + tmp = pre_smfs_dentry(NULL, inode, cowed_dir); /* link() is semanticaly-wrong for S_IFDIR, so we set S_IFREG * for linking and return real mode back then -bzzz */ mode = inode->i_mode; @@ -830,8 +855,7 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del) { struct fsfilt_operations *snapops = I2SNAPCOPS(inode); struct snap snap; - struct inode *ind = NULL, *cache_ind = NULL; - ino_t ind_ino; + struct inode *cache_ind = NULL; ENTRY; if (!snapops || !snapops->fs_create_indirect) @@ -845,24 +869,13 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del) CERROR("Create ind inode %lu index %d gen %d del %d rc%lu\n", inode->i_ino, snap.sn_index, snap.sn_gen, del, PTR_ERR(cache_ind)); - RETURN(PTR_ERR(ind)); + RETURN(PTR_ERR(cache_ind)); } - ind_ino = cache_ind->i_ino; iput(cache_ind); - /*FIXME: get indirect inode set_cow flags*/ - ind = smfs_get_inode(inode->i_sb, ind_ino, inode, 0); - if (ind) { - if (!SMFS_DO_INODE_COWED(inode)) { - /*insert the inode to cowed inode*/ - SMFS_SET_INODE_COWED(inode); - link_cowed_inode(inode); - } - - I2SMI(ind)->sm_sninfo.sn_flags = 0; - I2SMI(ind)->sm_sninfo.sn_gen = snap.sn_gen; - I2SMI(ind)->sm_sninfo.sn_index = snap.sn_index; - - iput(ind); + if (!SMFS_DO_INODE_COWED(inode)) { + /*insert the inode to cowed inode*/ + SMFS_SET_INODE_COWED(inode); + link_cowed_inode(inode); } RETURN(0); } @@ -1123,6 +1136,7 @@ static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry, CERROR("Can not find cino %lu inode\n", cino); RETURN(-ENOENT); } + smfs_init_snap_inode_info(inode, dir, index); d_add(dentry, inode); } RETURN(0); @@ -1156,6 +1170,7 @@ int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1, dot_inode = smfs_get_inode(inode->i_sb, inode->i_ino, inode, DOT_SNAP_INDEX); + smfs_init_snap_inode_info(dot_inode, inode, DOT_SNAP_INDEX); d_add(dentry, dot_inode); rc = 1; RETURN(rc); @@ -1231,7 +1246,7 @@ EXPORT_SYMBOL(smfs_cow_get_ind); typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry, void *new_dir, void *new_dentry); -static cow_funcs smfs_cow_funcs[HOOK_MAX + 1] = { +static cow_funcs smfs_cow_pre_funcs[HOOK_MAX + 1] = { [HOOK_CREATE] smfs_cow_create, [HOOK_LOOKUP] smfs_cow_lookup, [HOOK_LINK] smfs_cow_link, @@ -1244,12 +1259,66 @@ static cow_funcs smfs_cow_funcs[HOOK_MAX + 1] = { [HOOK_SETATTR] smfs_cow_setattr, [HOOK_WRITE] smfs_cow_write, }; +int smfs_cow_lookup_post(struct inode *dir, struct dentry *dentry, void *data1, + void *data2) +{ + struct inode *inode = dentry->d_inode; + struct fsfilt_operations *sops = I2SNAPCOPS(inode); + int index = I2SNAPI(dir)->sn_index; + ENTRY; + + LASSERT(inode); + + if (index > 0) { + struct inode *cache_ind = NULL; + + cache_ind = sops->fs_get_indirect(I2CI(inode), NULL, index); + if (cache_ind->i_ino != I2CI(inode)->i_ino) { + struct inode *ind_inode = NULL; + + ind_inode = smfs_get_inode(dir->i_sb, cache_ind->i_ino, + dir, index); + /*replace the ind_inode here*/ + list_del_init(&dentry->d_alias); + iput(inode); + d_instantiate(dentry, ind_inode); + } + } + inode = dentry->d_inode; + + smfs_init_snap_inode_info(inode, dir, index); + + RETURN(0); +} + +static cow_funcs smfs_cow_post_funcs[HOOK_MAX + 1] = { + [HOOK_CREATE] NULL, + [HOOK_LOOKUP] smfs_cow_lookup_post, + [HOOK_LINK] NULL, + [HOOK_UNLINK] NULL, + [HOOK_SYMLINK] NULL, + [HOOK_MKDIR] NULL, + [HOOK_RMDIR] NULL, + [HOOK_MKNOD] NULL, + [HOOK_RENAME] NULL, + [HOOK_SETATTR] NULL, + [HOOK_WRITE] NULL, +}; + +static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir, + void *new_dentry, int op) +{ + if (smfs_cow_pre_funcs[op]) { + return smfs_cow_pre_funcs[op](dir, dentry, new_dir, new_dentry); + } + return 0; +} -int smfs_cow(struct inode *dir, struct dentry *dentry, void *new_dir, - void *new_dentry, int op) +static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir, + void *new_dentry, int op) { - if (smfs_cow_funcs[op]) { - return smfs_cow_funcs[op](dir, dentry, new_dir, new_dentry); + if (smfs_cow_post_funcs[op]) { + return smfs_cow_post_funcs[op](dir, dentry, new_dir, new_dentry); } return 0; } diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h index a9ead26..dfc6446 100644 --- a/lustre/smfs/smfs_internal.h +++ b/lustre/smfs/smfs_internal.h @@ -322,10 +322,10 @@ do { \ GOTO(label, rc); \ } while(0) \ -#define SMFS_GET_INODE(sb, cache_inode, dir, index, inode, rc, label) \ +#define SMFS_GET_INODE(sb, cache_inode, dir, inode, rc, label) \ do { \ LASSERT(cache_inode); \ - inode = smfs_get_inode(sb, cache_inode->i_ino, dir, index); \ + inode = smfs_get_inode(sb, cache_inode->i_ino, dir, 0); \ iput(cache_inode); \ if (!inode) \ GOTO(label, rc = -ENOENT); \ @@ -335,7 +335,6 @@ do { \ #if CONFIG_SNAPFS int smfs_cow_init(struct super_block *sb); int smfs_cow_cleanup(struct smfs_super_info *smb); -int smfs_init_snap_inode_info(struct inode *inode, struct smfs_iget_args *args); int smfs_snap_test_inode(struct inode *inode, void *args); #else #define SMFS_PRE_COW(dir, dentry, new_dir, new_dentry, op, name, rc, label) diff --git a/lustre/smfs/smfs_lib.c b/lustre/smfs/smfs_lib.c index dc4809c..f0a23b5 100644 --- a/lustre/smfs/smfs_lib.c +++ b/lustre/smfs/smfs_lib.c @@ -50,7 +50,6 @@ static char *smfs_options(char *data, char **devstr, char **namestr, { struct option *opt_value = NULL; char *pos; - int opt_len = 0; LASSERT(opts && flags); diff --git a/lustre/smfs/symlink.c b/lustre/smfs/symlink.c index b8388f8..99e839f 100644 --- a/lustre/smfs/symlink.c +++ b/lustre/smfs/symlink.c @@ -48,7 +48,7 @@ static int smfs_readlink(struct dentry *dentry, char *buffer, int buflen) if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) GOTO(exit, rc = -ENOMEM); if (cache_inode->i_op && cache_inode->i_op->readlink) @@ -69,7 +69,7 @@ static int smfs_follow_link(struct dentry *dentry, struct nameidata *nd) if (!cache_inode) RETURN(-ENOENT); - cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry, NULL); + cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry); if (!cache_dentry) GOTO(exit, rc = -ENOMEM); -- 1.8.3.1