From 331221232f1d1aca8002fa7e08ce16902c6ff0bf Mon Sep 17 00:00:00 2001 From: wangdi Date: Tue, 24 Aug 2004 12:12:41 +0000 Subject: [PATCH] update .snap on smfs --- lustre/include/linux/lustre_smfs.h | 6 +- lustre/lvfs/fsfilt_snap_ext3.c | 39 ++++++++--- lustre/smfs/file.c | 4 -- lustre/smfs/inode.c | 32 ++++----- lustre/smfs/smfs_cow.c | 140 ++++++++++++++++++++++++------------- lustre/smfs/smfs_lib.c | 4 +- 6 files changed, 145 insertions(+), 80 deletions(-) diff --git a/lustre/include/linux/lustre_smfs.h b/lustre/include/linux/lustre_smfs.h index 474095c..b51d628 100644 --- a/lustre/include/linux/lustre_smfs.h +++ b/lustre/include/linux/lustre_smfs.h @@ -324,8 +324,10 @@ static inline void post_smfs_inode(struct inode *inode, static inline void pre_smfs_inode(struct inode *inode, struct inode *cache_inode) { - if (inode && cache_inode) - duplicate_inode(cache_inode, inode); + if (inode && cache_inode) { + cache_inode->i_state = inode->i_state; + // duplicate_inode(cache_inode, inode); + } } /* instantiate a file handle to the cache file */ diff --git a/lustre/lvfs/fsfilt_snap_ext3.c b/lustre/lvfs/fsfilt_snap_ext3.c index e1ef83d..a133c28 100644 --- a/lustre/lvfs/fsfilt_snap_ext3.c +++ b/lustre/lvfs/fsfilt_snap_ext3.c @@ -60,7 +60,7 @@ #define EXT3_MAX_SNAP_DATA (sizeof(struct snap_ea)) #define EXT3_SNAP_INDEX EXT3_XATTR_INDEX_LUSTRE #define EXT3_SNAP_COUNT "@snapcount" - +#define EXT3_SNAP_ROOT_INO "@snap_rootino" #define SB_FEATURE_COMPAT(sb) (EXT3_SB(sb)->s_es->s_feature_compat) @@ -214,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) { + if(slot == -1 && table) { CDEBUG(D_INODE, "redirector not found, using primary\n"); inode = iget(primary->i_sb, primary->i_ino); } @@ -922,7 +922,7 @@ static ino_t fsfilt_ext3_get_indirect_ino(struct super_block *sb, ino_t ino = 0; int err; ENTRY; - if (index < 0 || index > EXT3_MAX_SNAPS || !primary) + if (index < 0 || index > EXT3_MAX_SNAPS) RETURN(0); primary = iget(sb, primary_ino); @@ -1571,6 +1571,10 @@ static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key, *vallen = sizeof(int); rc = 0; } + if (rc > 0) { + rc = 0; + *vallen = rc; + } RETURN(rc); } else if (keylen >= strlen(SNAP_COUNT) && strcmp(key, SNAP_COUNT) == 0) { @@ -1581,9 +1585,22 @@ static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key, *vallen = sizeof(int); rc = 0; } + if (rc > 0) { + rc = 0; + *vallen = rc; + } + RETURN(rc); + } else if (keylen >= strlen(SNAP_ROOT_INO) && + (strcmp(key, SNAP_ROOT_INO) == 0)) { + + rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX, + EXT3_SNAP_ROOT_INO, val, *vallen); + if (rc > 0) { + rc = 0; + *vallen = rc; + } RETURN(rc); } - RETURN(-EINVAL); } @@ -1631,10 +1648,16 @@ static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key, RETURN(rc); } else if (keylen >= strlen(SNAP_ROOT_INO) && (strcmp(key, SNAP_ROOT_INO) == 0)) { - - - - + handle_t *handle; + EXT3_JOURNAL_START(inode->i_sb, handle, + EXT3_XATTR_TRANS_BLOCKS, rc); + if(rc) + RETURN(rc); + rc = ext3_xattr_set_handle(handle, inode, EXT3_SNAP_INDEX, + EXT3_SNAP_ROOT_INO, val, *vallen, 0); + journal_stop(handle); + + RETURN(rc); } RETURN(-EINVAL); diff --git a/lustre/smfs/file.c b/lustre/smfs/file.c index 45602dd..3a79ddd 100644 --- a/lustre/smfs/file.c +++ b/lustre/smfs/file.c @@ -301,11 +301,9 @@ int smfs_open(struct inode *inode, struct file *filp) if ((rc = smfs_init_cache_file(inode, filp))) RETURN(rc); - pre_smfs_inode(inode, cache_inode); if (cache_inode->i_fop->open) rc = cache_inode->i_fop->open(cache_inode, F2CF(filp)); - post_smfs_inode(inode, cache_inode); duplicate_file(filp, F2CF(filp)); RETURN(rc); } @@ -327,12 +325,10 @@ int smfs_release(struct inode *inode, struct file *filp) LBUG(); cache_file = sfi->c_file; } - pre_smfs_inode(inode, cache_inode); if (cache_inode->i_fop->release) rc = cache_inode->i_fop->release(cache_inode, cache_file); post_smfs_inode(inode, cache_inode); - duplicate_file(filp, cache_file); smfs_cleanup_cache_file(filp); RETURN(rc); diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index b881397..5603b61 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -63,14 +63,17 @@ static void smfs_init_inode_info (struct inode *inode, void *opaque) static void smfs_clear_inode_info(struct inode *inode) { - struct inode *cache_inode = I2CI(inode); - - LASSERTF(atomic_read(&cache_inode->i_count) == 1, - "inode %lu i_count %d != 1\n", cache_inode->i_ino, - atomic_read(&cache_inode->i_count)); - - iput(cache_inode); - OBD_FREE(I2SMI(inode), sizeof(struct smfs_inode_info)); + if (I2SMI(inode)) { + struct inode *cache_inode = I2CI(inode); + LASSERTF(((atomic_read(&cache_inode->i_count) == 0) || + cache_inode == cache_inode->i_sb->s_root->d_inode), + "inode %p cache inode %p %lu i_count %d != 0 \n", + inode, cache_inode, cache_inode->i_ino, + atomic_read(&cache_inode->i_count)); + + OBD_FREE(I2SMI(inode), sizeof(struct smfs_inode_info)); + I2SMI(inode) = NULL; + } } static void smfs_read_inode2(struct inode *inode, void *opaque) @@ -130,8 +133,9 @@ struct inode *smfs_iget(struct super_block *sb, ino_t hash, if (inode) { if (inode->i_state & I_NEW) unlock_new_inode(inode); - CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino, - inode->i_generation, inode); + CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p) index %d ino %lu \n", + inode->i_ino, inode->i_generation, inode, sargs->s_index, + sargs->s_ino); inode->i_ino = hash; } return inode; @@ -267,13 +271,7 @@ static void smfs_put_inode(struct inode *inode) return; } - CDEBUG(D_INFO, "cache_inode i_count ino %lu i_count %d\n", - inode->i_ino, atomic_read(&inode->i_count)); - if (atomic_read(&cache_inode->i_count) > 1 /*&& - cache_inode != cache_inode->i_sb->s_root->d_inode*/) { - CDEBUG(D_INFO, "cache_inode i_count ino %lu i_count %d\n", - cache_inode->i_ino, - atomic_read(&cache_inode->i_count) - 1); + if (atomic_read(&cache_inode->i_count) > 0) { iput(cache_inode); } diff --git a/lustre/smfs/smfs_cow.c b/lustre/smfs/smfs_cow.c index d33d406..a6f241c 100644 --- a/lustre/smfs/smfs_cow.c +++ b/lustre/smfs/smfs_cow.c @@ -219,22 +219,24 @@ static int smfs_init_snap_inode_info(struct inode *inode, struct inode *dir, int } #define COWED_NAME_LEN (7 + 8 + 1) -static int smfs_init_cowed_dir(struct snap_info *snap_info, struct dentry* dir) +static int smfs_init_cowed_dir(struct snap_info *snap_info, struct inode* inode) { struct dentry *dentry = NULL; char name[COWED_NAME_LEN]; int rc = 0; ENTRY; - sprintf(name, ".cowed_%08x", (__u32)dir->d_inode->i_ino); + sprintf(name, ".cowed_%08x", (__u32)inode->i_ino); /*FIXME-WANGDI: will use simple_mkdir, when integrating snap to lustre*/ - dentry = smfs_simple_mkdir(dir, name, 0777, 1); + dentry = smfs_simple_mkdir(inode->i_sb->s_root, name, 0777, 1); if (IS_ERR(dentry)) { rc = PTR_ERR(dentry); CERROR("create cowed directory: rc = %d\n", rc); RETURN(rc); } snap_info->sni_cowed_dentry = dentry; + /*cleanup cowed inode attr for cowed dir*/ + SMFS_CLEAN_INODE_COWED(dentry->d_inode); RETURN(rc); } @@ -269,23 +271,19 @@ static int smfs_init_dotinfo(struct snap_info *snap_info) } static int smfs_init_snap_info(struct smfs_super_info *smb, - struct snap_info *snap_info, struct dentry *de) + struct snap_info *snap_info, struct inode *inode) { struct snap_table *snap_table = NULL; struct fsfilt_operations *snapcops; int rc = 0, size, table_size, vallen, i; - struct inode *root_inode = NULL; ENTRY; - root_inode = iget(smb->smsi_sb, de->d_inode->i_ino); - if (!root_inode || is_bad_inode(root_inode)) - RETURN(-EIO); snapcops = smb->smsi_snap_info->snap_cache_fsfilt; /*Initialized table */ /*get the maxsize of snaptable*/ vallen = sizeof(int); - rc = snapcops->fs_get_snap_info(root_inode, MAX_SNAPTABLE_COUNT, + rc = snapcops->fs_get_snap_info(I2CI(inode), MAX_SNAPTABLE_COUNT, strlen(MAX_SNAPTABLE_COUNT), &size, &vallen); if (size == 0) { @@ -308,7 +306,7 @@ static int smfs_init_snap_info(struct smfs_super_info *smb, for (i = 0; i < snap_table->sntbl_max_count; i++) snap_table->sntbl_items[i].sn_index = -1; /*get snaptable info*/ - rc = snapcops->fs_get_snap_info(root_inode, SNAPTABLE_INFO, + rc = snapcops->fs_get_snap_info(I2CI(inode), SNAPTABLE_INFO, strlen(SNAPTABLE_INFO), snap_table, &table_size); if (rc < 0) { @@ -326,23 +324,21 @@ static int smfs_init_snap_info(struct smfs_super_info *smb, } } init_MUTEX(&snap_info->sni_sema); - snap_info->sni_root_ino = de->d_inode->i_ino; - rc = smfs_init_cowed_dir(snap_info, de); + snap_info->sni_root_ino = inode->i_ino; + rc = smfs_init_cowed_dir(snap_info, inode); if (rc) { CERROR("Init cowed dir error rc=%d\n", rc); GOTO(exit, rc); } rc = smfs_init_dotinfo(snap_info); exit: - if (root_inode) - iput(root_inode); if (rc && snap_table) OBD_FREE(snap_table, table_size); RETURN(rc); } static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo, - struct dentry *dentry) + struct inode *inode) { struct snap_info *snap_info = NULL; int rc = 0; @@ -351,13 +347,13 @@ static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo, OBD_ALLOC(snap_info, sizeof(struct snap_info)); if (!snap_info) RETURN(ERR_PTR(-ENOMEM)); - rc = smfs_init_snap_info(sinfo, snap_info, dentry); + rc = smfs_init_snap_info(sinfo, snap_info, inode); if (rc) GOTO(exit, rc); /*set cow flags for the snap root inode*/ - I2SMI(dentry->d_inode)->smi_flags |= SM_DO_COW; - I2SNAPI(dentry->d_inode)->sn_root_ino = dentry->d_inode->i_ino; + I2SMI(inode)->smi_flags |= SM_DO_COW; + I2SNAPI(inode)->sn_root_ino = inode->i_ino; exit: if (rc) { OBD_FREE(snap_info, sizeof(struct snap_info)); @@ -436,7 +432,7 @@ int smfs_cow_init(struct super_block *sb) vallen = sizeof(int); rc = sops->fs_get_snap_info(root_inode, SNAP_COUNT, strlen(SNAP_COUNT), &snap_count, &vallen); - if (rc) + if (rc < 0) GOTO(exit, rc); if (snap_count > 0) { @@ -452,21 +448,18 @@ int smfs_cow_init(struct super_block *sb) rc = sops->fs_get_snap_info(root_inode, SNAP_ROOT_INO, strlen(SNAP_ROOT_INO), snap_root, &snap_root_size); - if (rc) { + if (rc < 0) { OBD_FREE(snap_root, sizeof(int) * snap_count); GOTO(exit, rc); } for (i = 0; i < snap_count; i++) { ino_t root_ino = le32_to_cpu(snap_root[i]); - struct dentry *tmp = smfs_info->smsi_sb->s_root; struct snap_info *snap_info; - struct dentry *dentry; root_inode = smfs_get_inode(sb, root_ino, NULL, 0); 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); + snap_info = smfs_create_snap_info(S2SMI(sb), root_inode); + iput(root_inode); if (IS_ERR(snap_info)) { OBD_FREE(snap_root, sizeof(int) * snap_count); GOTO(exit, rc = PTR_ERR(snap_info)); @@ -474,11 +467,11 @@ int smfs_cow_init(struct super_block *sb) list_add(&snap_info->sni_list, &(S2SNAPI(sb)->snap_list)); } - } + } + smfs_info->smsi_snap_info->snap_count = snap_count; exit: if (rc) smfs_cow_cleanup(smfs_info); - RETURN(rc); } @@ -509,6 +502,7 @@ int smfs_cleanup_snap_info(struct snap_info *snap_info) ENTRY; l_dput(snap_info->sni_cowed_dentry); + //d_unalloc(snap_info->sni_cowed_dentry); if (snap_table) { table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count); OBD_FREE(snap_info->sni_table, table_size); @@ -692,15 +686,17 @@ static int snap_add_item(struct smfs_super_info *smb, /* Wrote the whole snap_table to disk */ table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count); + snap_table->sntbl_count++; + snap_table->sntbl_generation++; rc = snapops->fs_set_snap_info(root_inode, SNAPTABLE_INFO, strlen(SNAPTABLE_INFO), snap_table, &table_size); if (rc) { + snap_table->sntbl_count--; + snap_table->sntbl_generation--; CERROR("Set snaptable error rc=%d\n", rc); GOTO(exit, rc); } - snap_table->sntbl_count++; - snap_table->sntbl_generation++; exit: up(&snap_info->sni_sema); if (root_inode) @@ -709,28 +705,69 @@ exit: } static struct snap_info * smfs_find_create_snap_info(struct super_block *sb, - struct dentry *dentry) + struct inode *inode) { struct snap_super_info *snap_sinfo = S2SNAPI(sb); + struct fsfilt_operations *sops = snap_sinfo->snap_cache_fsfilt; struct snap_info *snap_info, *tmp; + ino_t *snap_root; + int rino_size, snap_count_size, rc = 0; ENTRY; list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list, sni_list) { - if (snap_info->sni_root_ino == dentry->d_inode->i_ino) { + if (snap_info->sni_root_ino == inode->i_ino) { RETURN(snap_info); } } - CDEBUG(D_INFO, "create a new snap info root ino %lu\n", - dentry->d_inode->i_ino); + CDEBUG(D_INFO, "create a new snap info root ino %lu\n", inode->i_ino); - snap_info = smfs_create_snap_info(S2SMI(sb), dentry); + snap_info = smfs_create_snap_info(S2SMI(sb), inode); if (IS_ERR(snap_info)) RETURN(snap_info); + + snap_sinfo->snap_count++; + + rino_size = snap_sinfo->snap_count * sizeof(ino_t); + + OBD_ALLOC(snap_root, rino_size); + + if (!snap_root) + GOTO(exit, rc = -ENOMEM); + + rc = sops->fs_get_snap_info(I2CI(inode), SNAP_ROOT_INO, + strlen(SNAP_ROOT_INO), snap_root, + &rino_size); + if (rc < 0) { + if (rc == -ENODATA) { + rc = 0; + } else { + GOTO(exit, rc); + } + } + snap_root[snap_sinfo->snap_count - 1] = inode->i_ino; + + snap_count_size = sizeof(int); + rc = sops->fs_set_snap_info(I2CI(inode), SNAP_COUNT, strlen(SNAP_COUNT), + &snap_sinfo->snap_count, &snap_count_size); + if (rc) + GOTO(exit, rc); + + rc = sops->fs_set_snap_info(I2CI(inode), SNAP_ROOT_INO, + strlen(SNAP_ROOT_INO), snap_root, + &rino_size); + + if (rc) + GOTO(exit, rc); list_add(&snap_info->sni_list, &snap_sinfo->snap_list); +exit: + if (rc) { + smfs_cleanup_snap_info(snap_info); + OBD_FREE(snap_info, sizeof(struct snap_info)); + } RETURN(snap_info); } @@ -754,7 +791,7 @@ int smfs_add_snap_item(struct super_block *sb, char *path_name, char *name) CERROR("can not find snap_shot root by %s\n", path_name); RETURN(PTR_ERR(dentry)); } - snap_info = smfs_find_create_snap_info(sb, dentry); + snap_info = smfs_find_create_snap_info(sb, dentry->d_inode); if (IS_ERR(snap_info)) { CERROR("can not find snap_info by %s rc=%lu\n", path_name, PTR_ERR(snap_info)); @@ -813,10 +850,11 @@ static int link_cowed_inode(struct inode *inode) cowed_dir = snap_info->sni_cowed_dentry; + down(&cowed_dir->d_inode->i_sem); + fidlen = ll_fid2str(fidname, inode->i_ino, inode->i_generation); - down(&cowed_dir->d_inode->i_sem); - dchild = ll_lookup_one_len(fidname, cowed_dir, fidlen); + dchild = lookup_one_len(fidname, cowed_dir, fidlen); if (IS_ERR(dchild)) { rc = PTR_ERR(dchild); if (rc != -EPERM && rc != -EACCES) @@ -833,7 +871,9 @@ static int link_cowed_inode(struct inode *inode) * for linking and return real mode back then -bzzz */ mode = inode->i_mode; inode->i_mode = S_IFREG; - rc = vfs_link(tmp, cowed_dir->d_inode, dchild); + + rc = cowed_dir->d_inode->i_op->link(tmp, cowed_dir->d_inode, dchild); + post_smfs_dentry(tmp); if (rc) { CERROR("error linking cowed inode %s to COWED: rc = %d\n", @@ -843,12 +883,13 @@ static int link_cowed_inode(struct inode *inode) if ((mode & S_IFMT) == S_IFDIR) { dchild->d_inode->i_nlink++; cowed_dir->d_inode->i_nlink++; + mark_inode_dirty(cowed_dir->d_inode); + mark_inode_dirty(dchild->d_inode); } - mark_inode_dirty(dchild->d_inode); out_dput: + up(&cowed_dir->d_inode->i_sem); dput(dchild); out_lock: - up(&cowed_dir->d_inode->i_sem); RETURN(rc); } /* @@ -875,11 +916,13 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del) PTR_ERR(cache_ind)); RETURN(PTR_ERR(cache_ind)); } - iput(cache_ind); - if (!SMFS_DO_INODE_COWED(inode)) { - /*insert the inode to cowed inode*/ - SMFS_SET_INODE_COWED(inode); - link_cowed_inode(inode); + if (cache_ind) { + iput(cache_ind); + if (!SMFS_DO_INODE_COWED(inode)) { + /*insert the inode to cowed inode*/ + SMFS_SET_INODE_COWED(inode); + link_cowed_inode(inode); + } } RETURN(0); } @@ -1341,9 +1384,10 @@ int smfs_cow_lookup_post(struct inode *dir, void *de, void *data1, struct inode *cache_ind = NULL; cache_ind = sops->fs_get_indirect(I2CI(inode), NULL, index); - if (cache_ind->i_ino != I2CI(inode)->i_ino) { + if (cache_ind) { struct inode *ind_inode = NULL; - + + LASSERT(cache_ind->i_ino != I2CI(inode)->i_ino); ind_inode = smfs_get_inode(dir->i_sb, cache_ind->i_ino, dir, index); /*replace the ind_inode here*/ @@ -1351,6 +1395,8 @@ int smfs_cow_lookup_post(struct inode *dir, void *de, void *data1, iput(inode); d_instantiate(dentry, ind_inode); } + if (cache_ind) + iput(cache_ind); } inode = dentry->d_inode; diff --git a/lustre/smfs/smfs_lib.c b/lustre/smfs/smfs_lib.c index 33b017a..10a3bf9 100644 --- a/lustre/smfs/smfs_lib.c +++ b/lustre/smfs/smfs_lib.c @@ -163,6 +163,7 @@ err_out: static int smfs_umount_cache(struct smfs_super_info *smb) { + mntput(smb->smsi_mnt); smfs_cleanup_sm_ops(smb); smfs_cleanup_fsfilt_ops(smb); @@ -232,9 +233,8 @@ void smfs_put_super(struct super_block *sb) { struct smfs_super_info *smfs_info = S2SMI(sb); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) smfs_cleanup_hooks(smfs_info); -#endif + if (sb) smfs_umount_cache(smfs_info); smfs_cleanup_smb(sb); -- 1.8.3.1