Whamcloud - gitweb
Update snapfs: 1) some fix on clonefs read in lustre
authorwangdi <wangdi>
Mon, 26 Jul 2004 13:03:28 +0000 (13:03 +0000)
committerwangdi <wangdi>
Mon, 26 Jul 2004 13:03:28 +0000 (13:03 +0000)
12 files changed:
lustre/include/linux/lustre_fsfilt.h
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_snap.h
lustre/llite/llite_lib.c
lustre/lvfs/fsfilt_smfs.c
lustre/lvfs/fsfilt_snap_ext3.c
lustre/lvfs/fsfilt_snap_smfs.c
lustre/mdc/mdc_locks.c
lustre/mds/mds_fs.c
lustre/obdfilter/filter.c
lustre/smfs/dir.c
lustre/smfs/smfs_cow.c

index d6953fb..002a3f7 100644 (file)
@@ -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;
 }
 
index db2a810..bc2cf94 100644 (file)
@@ -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;
 };
index 77fd369..6421423 100644 (file)
@@ -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;
index 13b092c..304c718 100644 (file)
@@ -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); 
index af36a3b..7e4e96b 100644 (file)
@@ -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);
index 11485c8..29f7c0d 100644 (file)
@@ -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) 
index 764811d..9f5b75e 100644 (file)
@@ -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 = {
index c3bafd1..8c04ca2 100644 (file)
@@ -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);
index 0561d6f..94be916 100644 (file)
@@ -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);
  
index a078bb5..43c429c 100644 (file)
@@ -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);
         
index 1420009..ccb130b 100644 (file)
@@ -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;
index d179915..a041bf9 100644 (file)
@@ -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);
                }
        }