diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h
index 67e9211a61a29285ee3130ad70b98e57dbecf444..988f8e62aae208c9d07ceeaeeaa7a6dff23a154f 100644
--- a/lustre/include/linux/lustre_fsfilt.h
+++ b/lustre/include/linux/lustre_fsfilt.h
@@ -95,8 +95,8 @@ struct fsfilt_operations {
         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);
-        int     (* fs_set_kml_flags)(struct inode *inode);
-        int     (* fs_clear_kml_flags)(struct inode *inode);
+        int     (* fs_set_fs_flags)(struct inode *inode, int flags);
+        int     (* fs_clear_fs_flags)(struct inode *inode, int flags);
         int     (* fs_set_ost_flags)(struct super_block *sb);
         int     (* fs_set_mds_flags)(struct super_block *sb);
         int     (* fs_precreate_rec)(struct dentry *dentry, int *num, 
@@ -544,18 +544,18 @@ llog_fsfilt_write_record(struct llog_ctxt *ctxt, struct file *file,
 }
 
 static inline int 
-fsfilt_set_kml_flags(struct obd_device *obd, struct inode *inode)
+fsfilt_set_fs_flags(struct obd_device *obd, struct inode *inode, int flags)
 {
-        if (obd->obd_fsops->fs_set_kml_flags)
-                return obd->obd_fsops->fs_set_kml_flags(inode);
+        if (obd->obd_fsops->fs_set_fs_flags)
+                return obd->obd_fsops->fs_set_fs_flags(inode, flags);
         return 0;
 }
 
 static inline int 
-fsfilt_clear_kml_flags(struct obd_device *obd, struct inode *inode)
+fsfilt_clear_fs_flags(struct obd_device *obd, struct inode *inode, int flags)
 {
-        if (obd->obd_fsops->fs_clear_kml_flags)
-                return obd->obd_fsops->fs_clear_kml_flags(inode);
+        if (obd->obd_fsops->fs_clear_fs_flags)
+                return obd->obd_fsops->fs_clear_fs_flags(inode, flags);
         return 0;
 }
 static inline int 
diff --git a/lustre/lvfs/fsfilt_smfs.c b/lustre/lvfs/fsfilt_smfs.c
index 98f138321e621123d31cfe54e3a99b27ccf607ff..d034cca3fe888efbadd802a1fedfd9292079b316 100644
--- a/lustre/lvfs/fsfilt_smfs.c
+++ b/lustre/lvfs/fsfilt_smfs.c
@@ -618,19 +618,23 @@ static int fsfilt_smfs_post_cleanup(struct obd_device *obd,
         RETURN(rc);
 }
 
-static int fsfilt_smfs_set_kml_flags(struct inode *inode)
+static int fsfilt_smfs_set_fs_flags(struct inode *inode, int flags)
 {
         int rc = 0;
-        if (SMFS_DO_REC(S2SMI(inode->i_sb)))
+        if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
                 SMFS_SET_INODE_REC(inode);
+        if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
+                SMFS_SET_INODE_COW(inode);
         RETURN(rc);
 }
 
-static int fsfilt_smfs_clear_kml_flags(struct inode *inode)
+static int fsfilt_smfs_clear_fs_flags(struct inode *inode, int flags)
 {
         int rc = 0;
-        if (SMFS_DO_REC(S2SMI(inode->i_sb)))
+        if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
                 SMFS_CLEAN_INODE_REC(inode);
+        if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
+                SMFS_CLEAN_INODE_COW(inode);
         RETURN(rc);
 }
 
@@ -939,8 +943,8 @@ static struct fsfilt_operations fsfilt_smfs_ops = {
         .fs_setup               = fsfilt_smfs_setup,
         .fs_post_setup          = fsfilt_smfs_post_setup,
         .fs_post_cleanup        = fsfilt_smfs_post_cleanup,
-        .fs_set_kml_flags       = fsfilt_smfs_set_kml_flags,
-        .fs_clear_kml_flags     = fsfilt_smfs_clear_kml_flags,
+        .fs_set_fs_flags       = fsfilt_smfs_set_fs_flags,
+        .fs_clear_fs_flags     = fsfilt_smfs_clear_fs_flags,
         .fs_set_ost_flags       = fsfilt_smfs_set_ost_flags,
         .fs_set_mds_flags       = fsfilt_smfs_set_mds_flags,
         .fs_precreate_rec       = fsfilt_smfs_precreate_rec,
diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c
index 7194c3bbe691d4e0329ac47a1004de2d067e8381..fccf34f80a78c18297cee1d3c9fdc79bb7e8b598 100644
--- a/lustre/mds/mds_fs.c
+++ b/lustre/mds/mds_fs.c
@@ -41,6 +41,7 @@
 #include <linux/lustre_fsfilt.h>
 #include <portals/list.h>
 
+#include <linux/lustre_smfs.h>
 #include "mds_internal.h"
 
 /* This limit is arbitrary, but for now we fit it in 1 page (32k clients) */
@@ -374,9 +375,10 @@ static int  mds_fs_post_setup(struct obd_device *obd)
         if (rc)
                 GOTO(out, rc);
  
-        fsfilt_set_kml_flags(obd, de->d_inode);
-        fsfilt_set_kml_flags(obd, mds->mds_pending_dir->d_inode);
-        
+        fsfilt_set_fs_flags(obd, de->d_inode, 
+                              SM_DO_REC | SM_DO_COW);
+        fsfilt_set_fs_flags(obd, mds->mds_pending_dir->d_inode, 
+                              SM_DO_REC | SM_DO_COW);
         fsfilt_set_mds_flags(obd, mds->mds_sb);
 out:
         l_dput(de);
diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c
index 474e7151bf06c4124f455dce926b32889eaeb820..81bcd9ba5c017b6468ef29b5d9398276d3a67abe 100644
--- a/lustre/obdfilter/filter.c
+++ b/lustre/obdfilter/filter.c
@@ -55,6 +55,7 @@
 #include <linux/lustre_commit_confd.h>
 #include <portals/list.h>
 
+#include <linux/lustre_smfs.h>
 #include "filter_internal.h"
 
 static struct lvfs_callback_ops filter_lvfs_ops;
@@ -1268,7 +1269,7 @@ static int filter_post_fs_cleanup(struct obd_device *obd)
         RETURN(rc);
 }
 
-static int filter_group_set_kml_flags(struct obd_device *obd, int group)
+static int filter_group_set_fs_flags(struct obd_device *obd, int group)
 {
         struct filter_obd *filter = &obd->u.filter;
         int rc = 0, i = 0;
@@ -1280,7 +1281,8 @@ static int filter_group_set_kml_flags(struct obd_device *obd, int group)
         for (i = 0; i < filter->fo_subdir_count; i++) {
                 struct dentry *dentry;
                 dentry = (filter->fo_subdirs + group)->dentry[i];
-                rc = fsfilt_set_kml_flags(obd, dentry->d_inode);
+                rc = fsfilt_set_fs_flags(obd, dentry->d_inode, 
+                                         SM_DO_REC | SM_DO_COW);
                 if (rc)
                         RETURN(rc);
         }
@@ -1297,7 +1299,7 @@ static int filter_post_fs_setup(struct obd_device *obd)
                 RETURN(rc);
         
         for (j = 0; j < filter->fo_group_count; j++) {
-                rc = filter_group_set_kml_flags(obd, j);
+                rc = filter_group_set_fs_flags(obd, j);
                 if (rc)
                         return rc;
         } 
@@ -2133,7 +2135,8 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa,
                 cleanup_phase = 1;
 
                 /*only do precreate rec record. so clean kml flags here*/
-                fsfilt_clear_kml_flags(obd, dparent->d_inode);
+                fsfilt_clear_fs_flags(obd, dparent->d_inode, 
+                                      SM_DO_REC | SM_DO_COW);
                 
                 dchild = filter_fid2dentry(obd, dparent, group, next_id);
                 if (IS_ERR(dchild))
@@ -2180,7 +2183,7 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa,
                                 CERROR("unable to write lastobjid "
                                        "but file created\n");
                 }
-                fsfilt_set_kml_flags(obd, dparent->d_inode);
+                fsfilt_set_fs_flags(obd, dparent->d_inode, SM_DO_REC | SM_DO_COW);
         
         cleanup:
                 switch(cleanup_phase) {
@@ -2685,7 +2688,7 @@ static int filter_set_info(struct obd_export *exp, __u32 keylen,
                 CERROR("can't read group %u\n", group);
                 RETURN(rc);
         }
-        rc = filter_group_set_kml_flags(obd, group);
+        rc = filter_group_set_fs_flags(obd, group);
          if (rc != 0) {
                 CERROR("can't set kml flags %u\n", group);
                 RETURN(rc);
diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c
index f01f1d0f11925694f689d82967c1987f31db08a1..73b9a88f4a8fb92b6da945d4d8c46f85fb530d03 100644
--- a/lustre/smfs/inode.c
+++ b/lustre/smfs/inode.c
@@ -79,9 +79,8 @@ static void smfs_read_inode2(struct inode *inode, void *opaque)
         post_smfs_inode(inode, cache_inode);
         sm_set_inode_ops(cache_inode, inode);
 #if CONFIG_SNAPFS
-        if (SMFS_DO_COW(S2SMI(inode->i_sb))) {
+        if (opaque)
                 smfs_init_snap_inode_info(inode, *((int *)opaque));
-        }
 #endif
         CDEBUG(D_INODE, "read_inode ino %lu icount %d \n",
                inode->i_ino, atomic_read(&inode->i_count));
diff --git a/lustre/smfs/smfs_cow.c b/lustre/smfs/smfs_cow.c
index 2b5c75c37c5866e19d4d44e3d05666a02e316221..b592087460da08f4ab1724c9819f8d7d81fc4c05 100644
--- a/lustre/smfs/smfs_cow.c
+++ b/lustre/smfs/smfs_cow.c
@@ -104,7 +104,6 @@ int smfs_cow_init(struct super_block *sb)
         int rc = 0;
 
         SMFS_SET_COW(smfs_info);
-        SMFS_SET_INODE_COW(inode);
       
         OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info));
      
@@ -179,13 +178,15 @@ int smfs_init_snap_inode_info(struct inode *inode, int flags)
         int vallen, rc = 0;
         ENTRY;
 
-        sni_info->sn_flags = flags;
-        vallen = sizeof(sni_info->sn_gen);
+        if (SMFS_DO_COW(S2SMI(inode->i_sb)) &&
+            (flags & SM_DO_COW)) {
+                sni_info->sn_flags = flags;
+                vallen = sizeof(sni_info->sn_gen);
 
-        rc = snapops->fs_get_snap_info(NULL, inode, SNAP_GENERATION,
-                                       strlen(SNAP_GENERATION),
-                                       &sni_info->sn_gen, &vallen);               
-        
+                rc = snapops->fs_get_snap_info(NULL, inode, SNAP_GENERATION,
+                                               strlen(SNAP_GENERATION),
+                                               &sni_info->sn_gen, &vallen);               
+        } 
         RETURN(rc);                                              
          
 }
@@ -253,7 +254,7 @@ int smfs_add_snap_item(struct super_block *sb, char *name)
         struct snap      *snap_item;
         int    table_size, count = 0, index = 0, rc = 0;
 
-        count = snap_table->sntbl_count + 1; 
+        count = snap_table->sntbl_count; 
 	/* XXX Is down this sema necessary*/
 	down_interruptible(&snap_info->sntbl_sema);
         snap_item = &snap_table->sntbl_items[count];
@@ -284,7 +285,6 @@ int smfs_add_snap_item(struct super_block *sb, char *name)
 exit:
 	up(&snap_info->sntbl_sema);
 	RETURN(rc);
-
 }
 EXPORT_SYMBOL(smfs_add_snap_item);
 /*
@@ -351,7 +351,7 @@ int smfs_cow_create(struct inode *dir, struct dentry *dentry)
 
         if (smfs_needs_cow(dir) != -1) {
 		CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
-		if ((smfs_cow(dir, dentry->d_parent, 0))) {
+		if ((snap_do_cow(dir, dentry->d_parent, 0))) {
 			CERROR("Do cow error\n");
 			RETURN(-EINVAL);
 		}