From: wangdi Date: Mon, 26 Jul 2004 13:03:28 +0000 (+0000) Subject: Update snapfs: 1) some fix on clonefs read in lustre X-Git-Tag: v1_7_100~2032 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=4ab521fae8e7540d4822a50f90688b75e75823fc Update snapfs: 1) some fix on clonefs read in lustre --- diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h index d6953fb..002a3f7 100644 --- a/lustre/include/linux/lustre_fsfilt.h +++ b/lustre/include/linux/lustre_fsfilt.h @@ -91,7 +91,8 @@ struct fsfilt_operations { int (* fs_read_record)(struct file *, void *, int size, loff_t *); int (* fs_setup)(struct obd_device *, struct super_block *); - int (* fs_post_setup)(struct obd_device *obd, struct vfsmount *mnt); + int (* fs_post_setup)(struct obd_device *obd, struct vfsmount *mnt, + struct dentry *dentry); int (* fs_post_cleanup)(struct obd_device *obd, struct vfsmount *mnt); int (* fs_get_reint_log_ctxt)(struct super_block *sb, struct llog_ctxt **ctxt); @@ -148,12 +149,10 @@ struct fsfilt_operations { int (* fs_set_indirect)(struct inode *pri, int index, ino_t ind_ino, ino_t parent_ino); int (* fs_snap_feature)(struct super_block *sb, int feature, int op); - int (* fs_set_snap_info)(struct super_block *sb, struct inode *inode, - void* key, __u32 keylen, void *val, - __u32 *vallen); - int (* fs_get_snap_info)(struct super_block *sb, struct inode *inode, - void* key, __u32 keylen, void *val, - __u32 *vallen); + int (* fs_set_snap_info)(struct inode *inode, void* key, __u32 keylen, + void *val, __u32 *vallen); + int (* fs_get_snap_info)(struct inode *inode, void* key, __u32 keylen, + void *val, __u32 *vallen); int (* fs_set_snap_item)(struct super_block *sb, char *name); }; @@ -585,11 +584,11 @@ fsfilt_precreate_rec(struct obd_device *obd, struct dentry *dentry, } static inline int -fsfilt_post_setup(struct obd_device *obd) +fsfilt_post_setup(struct obd_device *obd, struct dentry *de) { if (obd->obd_fsops->fs_post_setup) return obd->obd_fsops->fs_post_setup(obd, - obd->obd_lvfs_ctxt.pwdmnt); + obd->obd_lvfs_ctxt.pwdmnt, de); return 0; } diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index db2a810..bc2cf94 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -880,7 +880,9 @@ struct ptlbd_rsp { extern void lustre_swab_ptlbd_rsp (struct ptlbd_rsp *r); +#define CLONE_INFO_MAGIC 0x0218 struct clonefs_info { + int clone_magic; int clone_index; int clone_flags; }; diff --git a/lustre/include/linux/lustre_snap.h b/lustre/include/linux/lustre_snap.h index 77fd369..6421423 100644 --- a/lustre/include/linux/lustre_snap.h +++ b/lustre/include/linux/lustre_snap.h @@ -167,7 +167,8 @@ struct snap_table { struct snap_info { struct fsfilt_operations *snap_fsfilt; - struct fsfilt_operations *snap_cache_fsfilt; + struct fsfilt_operations *snap_cache_fsfilt; + struct dentry *snap_root; struct semaphore sntbl_sema; spinlock_t sntbl_lock; struct snap_table *sntbl; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 13b092c..304c718 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -124,25 +124,29 @@ int lustre_set_clone_info(struct super_block *sb, int clone_index) RETURN(0); if (sbi->ll_mdc_exp) { - struct obd_import *climp = class_exp2cliimp(sbi->ll_mdc_exp); - struct client_obd *cl_obd = &climp->imp_obd->u.cli; + struct obd_device *obd = class_exp2obd(sbi->ll_mdc_exp); + struct client_obd *cl_obd = &obd->u.cli; OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info)); if (!cl_obd->cl_clone_info) RETURN(-ENOMEM); SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index); SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS); + cl_obd->cl_clone_info->cl_clone_info->clone_magic = + cpu_to_le32(CLONE_INFO_MAGI); } if (sbi->ll_osc_exp) { - struct obd_import *climp = class_exp2cliimp(sbi->ll_osc_exp); - struct client_obd *cl_obd = &climp->imp_obd->u.cli; + struct obd_device *obd = class_exp2obd(sbi->ll_osc_exp); + struct client_obd *cl_obd = &obd->u.cli; OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info)); if (!cl_obd->cl_clone_info) RETURN(-ENOMEM); SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index); SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS); + cl_obd->cl_clone_info->cl_clone_info->clone_magic = + cpu_to_le32(CLONE_INFO_MAGI); } RETURN(0); } @@ -154,8 +158,8 @@ int lustre_cleanup_clone_info(struct super_block *sb) ENTRY; if (sbi->ll_mdc_exp) { - struct obd_import *climp = class_exp2cliimp(sbi->ll_mdc_exp); - struct client_obd *cl_obd = &climp->imp_obd->u.cli; + struct obd_device *obd = class_exp2obd(sbi->ll_mdc_exp); + struct client_obd *cl_obd = &obd->u.cli; if (!cl_obd->cl_clone_info) RETURN(0); @@ -164,8 +168,8 @@ int lustre_cleanup_clone_info(struct super_block *sb) } if (sbi->ll_osc_exp) { - struct obd_import *climp = class_exp2cliimp(sbi->ll_osc_exp); - struct client_obd *cl_obd = &climp->imp_obd->u.cli; + struct obd_device *obd = class_exp2obd(sbi->ll_osc_exp); + struct client_obd *cl_obd = &obd->u.cli; if (!cl_obd->cl_clone_info) RETURN(0); diff --git a/lustre/lvfs/fsfilt_smfs.c b/lustre/lvfs/fsfilt_smfs.c index af36a3b..7e4e96b 100644 --- a/lustre/lvfs/fsfilt_smfs.c +++ b/lustre/lvfs/fsfilt_smfs.c @@ -601,7 +601,8 @@ static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize, RETURN(rc); } -static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt) +static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt, + struct dentry *root_dentry) { struct super_block *sb = NULL; int rc = 0; @@ -613,8 +614,10 @@ static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt) if (SMFS_DO_REC(S2SMI(sb))) rc = smfs_start_rec(sb, mnt); #if CONFIG_SNAPFS - if (SMFS_DO_COW(S2SMI(sb))) - rc = smfs_start_cow(sb); + if (SMFS_DO_COW(S2SMI(sb))) { + S2SNAPI(sb)->snap_root = root_dentry; + rc = smfs_start_cow(sb); + } #endif if (rc) GOTO(exit, rc); diff --git a/lustre/lvfs/fsfilt_snap_ext3.c b/lustre/lvfs/fsfilt_snap_ext3.c index 11485c8..29f7c0d 100644 --- a/lustre/lvfs/fsfilt_snap_ext3.c +++ b/lustre/lvfs/fsfilt_snap_ext3.c @@ -600,7 +600,7 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, struct inode* parent, int del) { - struct inode *ind; + struct inode *ind = NULL; handle_t *handle = NULL; int err = 0; int has_orphan = 0; @@ -608,7 +608,7 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, if( pri == pri->i_sb->u.ext3_sb.s_journal_inode ){ CERROR("TRY TO COW JOUNRAL\n"); - RETURN(NULL); + RETURN(ERR_PTR(-EINVAL)); } CDEBUG(D_INODE, "creating indirect inode for %lu at index %d, %s pri\n", pri->i_ino, index, del ? "deleting" : "preserve"); @@ -616,8 +616,10 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, ind = fsfilt_ext3_get_indirect(pri, NULL, index); handle = ext3_journal_start(pri, SNAP_CREATEIND_TRANS_BLOCKS); - if( !handle ) - RETURN(NULL); + if( !handle ) { + CERROR("handle not NULL\n"); + RETURN(ERR_PTR(-EINVAL)); + } /* XXX ? We should pass an err argument to get_indirect and precisely * detect the errors, for some errors, we should exit right away. */ @@ -644,9 +646,11 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, if (ind && !IS_ERR(ind)) { CDEBUG(D_INODE, "existing indirect ino %lu for %lu: index %d\n", ind->i_ino, pri->i_ino, index); + GOTO(exit, err=0); - } - /* XXX: check this, ext3_new_inode, the first arg should be "dir" */ + } + + /* XXX: check this, ext3_new_inode, the first arg should be "dir" */ ind = ext3_new_inode(handle, pri, (int)pri->i_mode, 0); if (IS_ERR(ind)) GOTO(exit, err); @@ -780,9 +784,8 @@ exit: } iput(ind); ext3_journal_stop(handle, pri); - if (err) - CERROR("exiting with error %d\n", err); - RETURN(NULL); + + RETURN(ERR_PTR(err)); } static int fsfilt_ext3_snap_feature (struct super_block *sb, int feature, int op) { @@ -1482,8 +1485,8 @@ static int fsfilt_ext3_iterate(struct super_block *sb, } } -static int fsfilt_ext3_get_snap_info(struct super_block *sb,struct inode *inode, - void *key, __u32 keylen, void *val, +static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key, + __u32 keylen, void *val, __u32 *vallen) { int rc = 0; @@ -1501,7 +1504,7 @@ static int fsfilt_ext3_get_snap_info(struct super_block *sb,struct inode *inode, RETURN(rc); } else if (keylen >= strlen(SNAPTABLE_INFO) && strcmp(key, SNAPTABLE_INFO) == 0) { - rc = ext3_xattr_get(sb->s_root->d_inode, EXT3_SNAP_INDEX, + rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX, EXT3_SNAPTABLE_EA, val, *vallen); RETURN(rc); } else if (keylen >= strlen(SNAP_GENERATION) @@ -1519,8 +1522,8 @@ static int fsfilt_ext3_get_snap_info(struct super_block *sb,struct inode *inode, RETURN(-EINVAL); } -static int fsfilt_ext3_set_snap_info(struct super_block *sb,struct inode *inode, - void *key, __u32 keylen, void *val, +static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key, + __u32 keylen, void *val, __u32 *vallen) { int rc = 0; @@ -1533,15 +1536,14 @@ static int fsfilt_ext3_set_snap_info(struct super_block *sb,struct inode *inode, if (keylen >= strlen(SNAPTABLE_INFO) && strcmp(key, SNAPTABLE_INFO) == 0) { - struct inode *root_inode = sb->s_root->d_inode; handle_t *handle; - handle = ext3_journal_start(root_inode, EXT3_XATTR_TRANS_BLOCKS); + handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); if( !handle ) RETURN(-EINVAL); - rc = ext3_xattr_set(handle, root_inode, EXT3_SNAP_INDEX, + rc = ext3_xattr_set(handle, inode, EXT3_SNAP_INDEX, EXT3_SNAPTABLE_EA, val, *vallen, 0); - ext3_journal_stop(handle,root_inode); + ext3_journal_stop(handle, inode); RETURN(rc); } else if (keylen >= strlen(SNAP_GENERATION) diff --git a/lustre/lvfs/fsfilt_snap_smfs.c b/lustre/lvfs/fsfilt_snap_smfs.c index 764811d..9f5b75e 100644 --- a/lustre/lvfs/fsfilt_snap_smfs.c +++ b/lustre/lvfs/fsfilt_snap_smfs.c @@ -322,57 +322,50 @@ static int fsfilt_smfs_copy_block(struct inode *dst, struct inode *src, int blk) RETURN(rc); } -static int fsfilt_smfs_set_snap_info(struct super_block *sb,struct inode *inode, +static int fsfilt_smfs_set_snap_info(struct inode *inode, void* key, __u32 keylen, void *val, __u32 *vallen) { - struct super_block *csb = NULL; - struct inode *cache_inode = NULL; - struct fsfilt_operations *snap_fsfilt = NULL; - int rc = -EIO; - - if (sb) { - csb = S2CSB(sb); - snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt; - } else if (inode) { - cache_inode = I2CI(inode); - snap_fsfilt = I2SNAPCOPS(inode); - } + struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode); + struct inode *cache_inode = NULL; + int rc = -EIO; + if (snap_fsfilt == NULL) RETURN(rc); + cache_inode = I2CI(inode); + if (!cache_inode) + RETURN(rc); + + pre_smfs_inode(inode, cache_inode); + if (snap_fsfilt->fs_set_snap_info) - rc = snap_fsfilt->fs_set_snap_info(csb, cache_inode, key, + rc = snap_fsfilt->fs_set_snap_info(cache_inode, key, keylen, val, vallen); - + post_smfs_inode(inode, cache_inode); + RETURN(rc); } -static int fsfilt_smfs_get_snap_info(struct super_block *sb, struct inode *inode, - void *key, __u32 keylen, void *val, - __u32 *vallen) +static int fsfilt_smfs_get_snap_info(struct inode *inode, void *key, + __u32 keylen, void *val, __u32 *vallen) { - struct super_block *csb = NULL; - struct inode *cache_inode = NULL; - struct fsfilt_operations *snap_fsfilt = NULL; + struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode); + struct inode *cache_inode = NULL; int rc = -EIO; - if (sb) { - csb = S2CSB(sb); - snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt; - } else if (inode) { - cache_inode = I2CI(inode); - snap_fsfilt = I2SNAPCOPS(inode); - } - if (snap_fsfilt == NULL) RETURN(rc); - + + cache_inode = I2CI(inode); + if (!cache_inode) + RETURN(rc); + if (snap_fsfilt->fs_get_snap_info) - rc = snap_fsfilt->fs_get_snap_info(csb, cache_inode, key, + rc = snap_fsfilt->fs_get_snap_info(cache_inode, key, keylen, val, vallen); - + RETURN(rc); } struct fsfilt_operations fsfilt_smfs_snap_ops = { diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index c3bafd1..8c04ca2 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -175,16 +175,18 @@ int mdc_change_cbdata(struct obd_export *exp, struct ll_fid *fid, } #if CONFIG_SNAPFS -int mdc_set_clone_info(struct obd_import *climp, struct lustre_msg *msg, +int mdc_set_clone_info(struct obd_export *exp, struct lustre_msg *msg, int offset) { - struct client_obd *cli_obd = &climp->imp_obd->u.cli; + struct client_obd *cli_obd = &exp->exp_obd->u.cli; struct clonefs_info *cl_info; ENTRY; - - cl_info = (struct clonefs_info *)lustre_msg_buf(msg, offset, - sizeof (*cl_info)); - memcpy(cl_info, cli_obd->cl_clone_info, sizeof(*cl_info)); + + if (cli_obd->cl_clone_info) { + cl_info = (struct clonefs_info *)lustre_msg_buf(msg, offset, + sizeof (*cl_info)); + memcpy(cl_info, cli_obd->cl_clone_info, sizeof(*cl_info)); + } RETURN(0); } #endif @@ -277,27 +279,18 @@ int mdc_enqueue(struct obd_export *exp, /* pack the intended request */ mdc_getattr_pack(req->rq_reqmsg, valid, 2, it->it_flags, data); #if CONFIG_SNAPFS - mdc_set_clone_info(class_exp2cliimp(exp), req->rq_reqmsg, 4); + mdc_set_clone_info(exp, req->rq_reqmsg, 4); #endif /* get ready for the reply */ reply_buffers = 3; req->rq_replen = lustre_msg_size(3, repsize); } else if (it->it_op == IT_READDIR) { policy.l_inodebits.bits = MDS_INODELOCK_UPDATE; -#if CONFIG_SNAPFS - size[1] = sizeof(struct clonefs_info); - req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 2, - size, NULL); -#else req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 1, size, NULL); -#endif if (!req) RETURN(-ENOMEM); -#if CONFIG_SNAPFS - mdc_set_clone_info(class_exp2cliimp(exp), req->rq_reqmsg, 1); -#endif /* get ready for the reply */ reply_buffers = 1; req->rq_replen = lustre_msg_size(1, repsize); diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index 0561d6f..94be916 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -378,7 +378,7 @@ static int mds_fs_post_setup(struct obd_device *obd) struct dentry *de = mds_fid2dentry(mds, &mds->mds_rootfid, NULL); int rc = 0; - rc = fsfilt_post_setup(obd); + rc = fsfilt_post_setup(obd, de); if (rc) GOTO(out, rc); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index a078bb5..43c429c 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -1301,7 +1301,7 @@ static int filter_post_fs_setup(struct obd_device *obd) int rc = 0, j = 0; struct llog_ctxt *ctxt = NULL; - rc = fsfilt_post_setup(obd); + rc = fsfilt_post_setup(obd, filter->fo_dentry_O); if (rc) RETURN(rc); diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index 1420009..ccb130b 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -150,7 +150,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_PRE_COW(dir, dentry, NULL, NULL, SNAP_LOOKUP, "lookup", rc, exit); + SMFS_PRE_COW(dir, dentry, NULL, NULL, SNAP_LOOKUP, "lookup", rc2, exit); /* perform lookup in backing fs. */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) @@ -161,7 +161,7 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry, if (rc && IS_ERR(rc)) GOTO(exit, rc); - + if ((cache_inode = rc ? rc->d_inode : cache_dentry->d_inode)) { if (IS_ERR(cache_inode)) { dentry->d_inode = cache_inode; diff --git a/lustre/smfs/smfs_cow.c b/lustre/smfs/smfs_cow.c index d179915..a041bf9 100644 --- a/lustre/smfs/smfs_cow.c +++ b/lustre/smfs/smfs_cow.c @@ -46,6 +46,7 @@ static int smfs_init_snaptabe(struct super_block *sb) struct snap_info *snap_info = S2SNAPI(sb); struct snap_table *snap_table = NULL; struct fsfilt_operations *snapops = snap_info->snap_fsfilt; + struct dentry *d_root = snap_info->snap_root; int rc = 0, size, table_size, vallen, i; ENTRY; @@ -54,7 +55,7 @@ static int smfs_init_snaptabe(struct super_block *sb) /*Initialized table */ /*get the maxsize of snaptable*/ vallen = sizeof(int); - rc = snapops->fs_get_snap_info(sb, NULL, MAX_SNAPTABLE_COUNT, + rc = snapops->fs_get_snap_info(d_root->d_inode, MAX_SNAPTABLE_COUNT, strlen(MAX_SNAPTABLE_COUNT), &size, &vallen); if (size == 0) { @@ -79,7 +80,7 @@ static int smfs_init_snaptabe(struct super_block *sb) snap_table->sntbl_items[i].sn_index = -1; } /*get snaptable info*/ - rc = snapops->fs_get_snap_info(sb, NULL, SNAPTABLE_INFO, + rc = snapops->fs_get_snap_info(d_root->d_inode, SNAPTABLE_INFO, strlen(SNAPTABLE_INFO), snap_table, &table_size); if (rc < 0) { @@ -124,14 +125,9 @@ static int smfs_init_cowed_dir(struct super_block *sb, struct dentry* cowed_dir) } int smfs_start_cow(struct super_block *sb) { - struct smfs_super_info *smfs_info = S2SMI(sb); int rc = 0; ENTRY; - OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info)); - - if (!smfs_info->smsi_snap_info) - RETURN(-ENOMEM); /*init snap fsfilt operations*/ if (!S2SNAPI(sb)->snap_cache_fsfilt) { @@ -192,8 +188,6 @@ int smfs_stop_cow(struct super_block *sb) table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count); OBD_FREE(snap_info->sntbl, table_size); } - if (snap_info) - OBD_FREE(snap_info, sizeof(*snap_info)); RETURN(rc); } @@ -206,13 +200,23 @@ int smfs_cow_init(struct super_block *sb) SMFS_SET_COW(smfs_info); + OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info)); + + if (!smfs_info->smsi_snap_info) + RETURN(-ENOMEM); + RETURN(rc); } int smfs_cow_cleanup(struct super_block *sb) { + + struct snap_info *snap_info = S2SNAPI(sb); + ENTRY; SMFS_CLEAN_COW(S2SMI(sb)); + if (snap_info) + OBD_FREE(snap_info, sizeof(*snap_info)); RETURN(0); } @@ -231,7 +235,7 @@ int smfs_init_snap_inode_info(struct inode *inode, int flags) sni_info->sn_flags = flags; vallen = sizeof(sni_info->sn_gen); - rc = snapops->fs_get_snap_info(NULL, inode, SNAP_GENERATION, + rc = snapops->fs_get_snap_info(inode, SNAP_GENERATION, strlen(SNAP_GENERATION), &sni_info->sn_gen, &vallen); } @@ -299,6 +303,7 @@ int smfs_add_snap_item(struct super_block *sb, char *name) struct snap_info *snap_info = S2SNAPI(sb); struct fsfilt_operations *snapops = snap_info->snap_fsfilt; struct snap_table *snap_table = snap_info->sntbl; + struct dentry *d_root = snap_info->snap_root; struct snap *snap_item; int table_size, count = 0, index = 0, rc = 0; @@ -321,7 +326,7 @@ int smfs_add_snap_item(struct super_block *sb, char *name) /* Wrote the whole snap_table to disk */ table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count); - rc = snapops->fs_set_snap_info(sb, NULL, SNAPTABLE_INFO, + rc = snapops->fs_set_snap_info(d_root->d_inode, SNAPTABLE_INFO, strlen(SNAPTABLE_INFO), snap_table, &table_size); if (rc) { @@ -432,18 +437,24 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del) snap_last(inode->i_sb, &snap); ind = snapops->fs_create_indirect(inode, snap.sn_index, snap.sn_gen, dparent->d_inode, del); - if(!ind) - RETURN(-EINVAL); - if (!SMFS_DO_INODE_COWED(inode)) { - /*insert the inode to cowed inode*/ - SMFS_SET_INODE_COWED(inode); - link_cowed_inode(inode); + if(ind && IS_ERR(ind)) { + CERROR("Create ind inode %lu index %d gen %d del %d\n rc%d\n", + inode->i_ino, snap.sn_index, snap.sn_gen, del, + PTR_ERR(ind)); + RETURN(PTR_ERR(ind)); + } + 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; + + iput(ind); } - - I2SMI(ind)->sm_sninfo.sn_flags = 0; - I2SMI(ind)->sm_sninfo.sn_gen = snap.sn_gen; - - iput(ind); RETURN(0); } /*Dir inode will do cow*/ @@ -458,8 +469,8 @@ int smfs_cow_create(struct inode *dir, struct dentry *dentry, CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino); LASSERT(dentry->d_parent && dentry->d_parent->d_parent); dparent = dentry->d_parent->d_parent; - if ((snap_do_cow(dir, dparent, 0))) { - CERROR("Do cow error\n"); + if ((rc = snap_do_cow(dir, dparent, 0))) { + CERROR("Do cow error %d\n", rc); RETURN(-EINVAL); } }