diff --git a/lustre/smfs/Makefile.am b/lustre/smfs/Makefile.am
index 764dcfd417b4a5e023196ead42a3ffba5f105428..96265dabe7058751cbb5c49108e3d01ab7e84583 100644
--- a/lustre/smfs/Makefile.am
+++ b/lustre/smfs/Makefile.am
@@ -10,7 +10,7 @@ MODULE = smfs
 modulefs_DATA = smfs.o
 EXTRA_PROGRAMS = smfs
 
-smfs_SOURCES = super.c options.c inode.c cache.c dir.c 
-
+smfs_SOURCES = super.c options.c inode.c cache.c dir.c  
+smfs_SOURCES += sysctl.c file.c symlink.c sm_fs.c
 
 include $(top_srcdir)/Rules
diff --git a/lustre/smfs/cache.c b/lustre/smfs/cache.c
index 5008615887a3c3232b33663f36180437f88e73de..0f013d3862f7fefb266ee64761502049aae31656 100644
--- a/lustre/smfs/cache.c
+++ b/lustre/smfs/cache.c
@@ -18,6 +18,7 @@ extern struct file_operations  smfs_file_fops;
 extern struct address_space_operations smfs_file_aops;
 extern struct inode_operations smfs_sym_iops; 
 extern struct file_operations smfs_sym_fops;
+extern struct super_operations smfs_super_ops;
 
 inline struct super_operations *cache_sops(struct sm_ops *smfs_ops)
 {
@@ -70,7 +71,7 @@ void init_smfs_cache()
 }
 void cleanup_smfs_cache()
 {
-
+	return;
 }
 
 static void setup_sm_symlink_ops(struct inode *cache_inode, 
@@ -169,7 +170,7 @@ static void setup_sm_file_ops(struct inode *cache_inode,
 		if (cache_inode->i_op->getxattr)
 			iops->getxattr = cache_iops->getxattr;
 		if (cache_inode->i_op->listxattr)
-			iops->setxattr = cache_iops->setxattr;
+			iops->listxattr = cache_iops->listxattr;
 		if (cache_inode->i_op->removexattr)
 			iops->removexattr = cache_iops->removexattr;
 	}
@@ -181,14 +182,71 @@ static void setup_sm_file_ops(struct inode *cache_inode,
 	}
 	return;
 }
-void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode)
+
+static void setup_sm_sb_ops(struct super_block *cache_sb, 
+			    struct super_block *sb, 
+			    struct super_operations *smfs_sops)	
+{
+	struct smfs_super_info *smb;
+        struct super_operations *sops;
+
+	ENTRY;
+
+	smb = S2SMI(sb); 
+	
+	if (smb->ops_check & SB_OPS_CHECK) 
+		return; 
+	smb->ops_check |= SB_OPS_CHECK;
+	sops = cache_sops(&smfs_operations);
+	memset(sops, 0, sizeof (struct super_operations));	
+
+	if (cache_sb->s_op) {
+		if (cache_sb->s_op->read_inode) 
+			sops->read_inode = smfs_sops->read_inode;
+		if (cache_sb->s_op->read_inode2)
+			sops->read_inode2 = smfs_sops->read_inode2;
+		if (cache_sb->s_op->dirty_inode)
+			sops->dirty_inode = smfs_sops->dirty_inode;
+		if (cache_sb->s_op->write_inode)
+			sops->write_inode = smfs_sops->write_inode;
+		if (cache_sb->s_op->put_inode)
+			sops->put_inode = smfs_sops->put_inode;
+		if (cache_sb->s_op->delete_inode)
+			sops->delete_inode = smfs_sops->delete_inode;
+		if (cache_sb->s_op->put_super)
+			sops->put_super = smfs_sops->put_super;
+		if (cache_sb->s_op->write_super)
+			sops->write_super = smfs_sops->write_super;
+		if (cache_sb->s_op->write_super_lockfs)
+			sops->write_super_lockfs = smfs_sops->write_super_lockfs;
+		if (cache_sb->s_op->unlockfs)
+			sops->unlockfs = smfs_sops->unlockfs;
+		if (cache_sb->s_op->statfs)
+			sops->statfs = smfs_sops->statfs;
+		if (cache_sb->s_op->remount_fs)
+			sops->remount_fs = smfs_sops->remount_fs;
+		if (cache_sb->s_op->clear_inode)
+			sops->clear_inode = smfs_sops->clear_inode;
+		if (cache_sb->s_op->umount_begin)
+			sops->umount_begin = smfs_sops->umount_begin;
+		if (cache_sb->s_op->fh_to_dentry)
+			sops->fh_to_dentry = smfs_sops->fh_to_dentry;
+		if (cache_sb->s_op->dentry_to_fh)
+			sops->dentry_to_fh = smfs_sops->dentry_to_fh;
+		if (cache_sb->s_op->show_options)
+			sops->show_options = smfs_sops->show_options;
+	}
+						
+	return;
+}	
+void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode)
 {
         /* XXX now set the correct snap_{file,dir,sym}_iops */
         if (S_ISDIR(inode->i_mode)) {
                 inode->i_op = cache_diops(&smfs_operations);
                 inode->i_fop = cache_dfops(&smfs_operations);
         } else if (S_ISREG(inode->i_mode)) {
-                if (!cache_fiops(&smfs_operations) ) {
+                if (!cache_fiops(&smfs_operations)) {
 		        setup_sm_file_ops(cache_inode, inode,
                                               &smfs_file_iops,
                                               &smfs_file_fops,
@@ -213,4 +271,20 @@ void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode)
                        inode->i_ino, inode->i_op);
         }
 }
+void sm_set_sb_ops (struct super_block *cache_sb,
+		      struct super_block *sb)
+{
+	struct smfs_super_info *smb;
+
+	smb = S2SMI(sb); 
+	
+	if (smb->ops_check & SB_OPS_CHECK) 
+		return; 
+	smb->ops_check |= SB_OPS_CHECK;
+	if (!cache_sops(&smfs_operations)) {
+		setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops);	
+	}
+	sb->s_op = cache_sops(&smfs_operations);
+	return;	
+}
 
diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c
index b0108b2a97ade4a1d5c2f77bb9a0cffe74a54de2..3583f7be9c6a6e18163513129dab14140c25fab7 100644
--- a/lustre/smfs/dir.c
+++ b/lustre/smfs/dir.c
@@ -85,7 +85,7 @@ static int smfs_create(struct inode *dir,
 	if (!inode) 
 		GOTO(exit, rc);		
 	
-	sm_setup_inode_ops(cache_inode, inode);
+	sm_set_inode_ops(cache_inode, inode);
 exit:
 	d_unalloc(cache_dentry);	
 	RETURN(rc);
diff --git a/lustre/smfs/file.c b/lustre/smfs/file.c
new file mode 100644
index 0000000000000000000000000000000000000000..751f13aeb408e3013ff378b857c093bcebabcb6f
--- /dev/null
+++ b/lustre/smfs/file.c
@@ -0,0 +1,24 @@
+/*
+ * file.c
+ */
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/unistd.h>
+#include <linux/pagemap.h>
+#include "smfs_internal.h" 
+
+struct address_space_operations smfs_file_aops = {
+};
+                                                                                                                                                                                                     
+struct file_operations smfs_file_fops = {
+};
+                                                                                                                                                                                                     
+struct inode_operations smfs_file_iops = {
+};
+
diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c
index 37b86edc85a66305aae56d5d7da1bb5b989a9854..8769913d2f93f23fd779a22f330576957d7788b2 100644
--- a/lustre/smfs/inode.c
+++ b/lustre/smfs/inode.c
@@ -36,7 +36,7 @@ static void smfs_read_inode(struct inode *inode)
 	CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", 
 	       inode->i_ino, atomic_read(&inode->i_count));
 
-	sm_setup_inode_ops(cache_inode, inode);
+	sm_set_inode_ops(cache_inode, inode);
 	
 	CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", 
 	       inode->i_ino, atomic_read(&inode->i_count));
@@ -61,9 +61,11 @@ static void smfs_clear_inode(struct inode *inode)
 	clear_inode(cache_inode);
 	return;	
 }
-struct super_operations currentfs_super_ops = {
+
+struct super_operations smfs_super_ops = {
 	read_inode:	smfs_read_inode,
 	clear_inode:	smfs_clear_inode,
+	put_super:	smfs_put_super,
 };
 
 
diff --git a/lustre/smfs/sm_fs.c b/lustre/smfs/sm_fs.c
new file mode 100644
index 0000000000000000000000000000000000000000..d83c6f4a2a2292071c106ad0fa8ed893bb7cd2d3
--- /dev/null
+++ b/lustre/smfs/sm_fs.c
@@ -0,0 +1,54 @@
+/*
+ *  fs/smfs/sm_fs.c
+ *
+ *  A storage management file system.
+ *
+ */
+#define EXPORT_SYMTAB
+#define DEBUG_SUBSYSTEM S_SM
+                                                                                                                                                                                                     
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/unistd.h>
+#include <linux/miscdevice.h>
+                                                                                                                                                                                                     
+#include "smfs_internal.h" 
+
+int sm_stack = 0;
+long sm_kmemory = 0;
+
+                                                                                                                                                                                                     
+MODULE_AUTHOR("Peter J. Braam <braam@cs.cmu.edu>");
+MODULE_DESCRIPTION("Smfs file system filters v0.01");
+                                                                                                                                                                                                     
+extern int init_smfs(void);
+extern int cleanup_smfs(void);
+extern int init_snap_sysctl(void);
+                                                                                                                                                                                                     
+static int __init smfs_init(void)
+{
+        int err;
+                                                                                                                                                                                                     
+        if ( (err = init_smfs()) ) {
+                printk("Error initializing snapfs, %d\n", err);
+                return -EINVAL;
+        }
+                                                                                                                                                                                                     
+        if ( (err = init_smfs_proc_sys()) ) {
+                printk("Error initializing snapfs proc sys, %d\n", err);
+                return -EINVAL;
+        }
+                                                                                                                                                                                                     
+        return 0;
+}
+                                                                                                                                                                                                     
+static void __exit smfs_cleanup(void)
+{
+	cleanup_smfs();
+}
+module_init(smfs_init);
+module_exit(smfs_cleanup);
+
diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h
index fe6b574768ab7745a676f16006a85ed029a8c526..ad58e8eeec65294f3fdddec71b3e4fea5b205993 100644
--- a/lustre/smfs/smfs_internal.h
+++ b/lustre/smfs/smfs_internal.h
@@ -46,16 +46,21 @@ struct option {
 	char *value;
 	struct list_head list;
 };
+
+extern int init_smfs_proc_sys(void);
 /*options.c*/
 extern int get_opt(struct option **option, char **pos);
 extern void cleanup_option(void);
 extern int init_option(char *data);
 /*cache.c*/
-void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode);
+void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode);
 void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb);
 void init_smfs_cache(void);
 void cleanup_smfs_cache(void);
-
+/*super.c*/
+int init_smfs(void);
+int cleanup_smfs(void);
+void smfs_put_super(struct super_block *sb);
 /*sysctl.c*/
 extern int sm_debug_level;
 extern int sm_inodes;
diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c
index 53fe4f1466b75debfb9fc1d46e3d03b9904e9153..2cb0346758c4b808a8a2baea218da8314353ecb0 100644
--- a/lustre/smfs/super.c
+++ b/lustre/smfs/super.c
@@ -8,14 +8,18 @@
  *
  *  Author: Peter J. Braam <braam@mountainviewdata.com>
  */
-#define DEBUG_SUBSYSTEM S_SNAP
+#define DEBUG_SUBSYSTEM S_SM
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/utime.h>
+#include <linux/file.h>
+#include <linux/slab.h>
 #include <linux/loop.h>
 #include <linux/errno.h>
 #include "smfs_internal.h" 
@@ -56,6 +60,19 @@ static int get_fd(struct file *filp)
 	write_unlock(&files->file_lock);
 	RETURN(-1);
 }
+static int close_fd(int fd)
+{
+	struct files_struct *files = current->files;	
+        
+	write_lock(&files->file_lock);
+       
+	files->fd[fd] = NULL;
+        __put_unused_fd(files, fd); 
+	
+	write_unlock(&files->file_lock);
+	return 0;
+}
+
 #define MAX_LOOP_DEVICES	256
 static char *parse_path2dev(struct super_block *sb, char *dev_path)
 {
@@ -66,22 +83,48 @@ static char *parse_path2dev(struct super_block *sb, char *dev_path)
 	filp = filp_open(dev_path, 0, 0);
 	if (!filp) 
 		RETURN(NULL);
-
 	if (S_ISREG(filp->f_dentry->d_inode->i_mode)) {
 		/*here we must walk through all the snap cache to 
 		 *find the loop device */
+		
+		fd = get_unused_fd();
+		if (!fd) RETURN(NULL);
+
+		fd_install(fd, filp);		
+		SM_ALLOC(name, strlen("/dev/loop/") + 2);
+	
 		for (i = 0; i < MAX_LOOP_DEVICES; i++) {
 			fd = get_fd(filp);
-			error = sb->s_bdev->bd_op->ioctl(filp->f_dentry->d_inode, 
-						 filp, LOOP_SET_FD,
-                                                 (unsigned long)&fd);
-			if (!error) {
-				filp_close(filp, current->files); 
-				/*FIXME later, the loop file should 
+			if (fd > 0) {
+				struct block_device_operations *bd_ops;
+				struct dentry *dentry;
+				struct nameidata nd;
+                                /*FIXME later, the loop file should 
 			         *be different for different system*/
-				SM_ALLOC(name, strlen("/dev/loop/") + 2);
-				sprintf(name, "dev/loop/%d", i);
-				RETURN(name);	 				
+                                                                                                                                                             
+				sprintf(name, "/dev/loop/%d", i);
+        		
+				if (path_init(name, LOOKUP_FOLLOW, &nd)) {
+                			error = path_walk(name, &nd);
+                			if (error) {
+						path_release(&nd);
+                        			SM_FREE(name, sizeof(name) + 1); 
+						RETURN(NULL);
+					}
+        			} else {
+                        		SM_FREE(name, sizeof(name) + 1); 
+                			RETURN(NULL);
+                                }                                                                                                                                                                    
+				dentry = nd.dentry;
+				bd_ops = get_blkfops(LOOP_MAJOR); 
+				error = bd_ops->ioctl(dentry->d_inode, 
+						      filp, LOOP_SET_FD,
+                                                      (unsigned long)fd);
+				path_release(&nd);
+				if (!error) {
+					filp_close(filp, current->files); 
+					RETURN(name);	 				
+				}
 			}
 		}
 	}
@@ -129,6 +172,19 @@ err_out:
 		
 	return err;	
 }
+static int sm_umount_cache(struct super_block *sb)
+{
+	struct smfs_super_info *smb = S2SMI(sb);
+	
+	mntput(smb->smsi_mnt);
+	return 0;
+}
+void smfs_put_super(struct super_block *sb)
+{
+	if (sb)
+		sm_umount_cache(sb);
+	return; 
+}
 
 struct super_block *
 smfs_read_super(
diff --git a/lustre/smfs/symlink.c b/lustre/smfs/symlink.c
new file mode 100644
index 0000000000000000000000000000000000000000..4174846185375b8503870e33883ad2ef91a804d3
--- /dev/null
+++ b/lustre/smfs/symlink.c
@@ -0,0 +1,21 @@
+/*
+ *  fs/snap/snap.c
+ *
+ *  A snap shot file system.
+ *
+ */
+#define DEBUG_SUBSYSTEM S_SNAP
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "smfs_internal.h" 
+
+struct inode_operations smfs_sym_iops = {
+};
+
+struct file_operations smfs_sym_fops = {
+};
diff --git a/lustre/smfs/sysctl.c b/lustre/smfs/sysctl.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ec1f9b2607e059b7645a9d3173c4e93b9e45380
--- /dev/null
+++ b/lustre/smfs/sysctl.c
@@ -0,0 +1,87 @@
+/*
+ *  Sysctrl entries for Snapfs
+ */
+
+/* /proc entries */
+
+#define DEBUG_SUBSYSTEM S_SNAP
+
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+
+#include "smfs_internal.h" 
+
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *proc_smfs_root;
+#endif
+
+
+/* SYSCTL below */
+
+static struct ctl_table_header *smfs_table_header = NULL;
+/* 0x100 to avoid any chance of collisions at any point in the tree with
+ * non-directories
+ */
+#define PSDEV_SMFS  (0x130)
+
+#define PSDEV_DEBUG	   1      /* control debugging */
+#define PSDEV_TRACE	   2      /* control enter/leave pattern */
+
+/* These are global control options */
+#define ENTRY_CNT 3
+
+int sm_print_entry = 1;
+int sm_debug_level = 0;
+
+/* XXX - doesn't seem to be working in 2.2.15 */
+static struct ctl_table smfs_ctltable[] =
+{
+	{PSDEV_DEBUG, "debug", &sm_debug_level, sizeof(int), 0644, NULL, &proc_dointvec},
+	{PSDEV_TRACE, "trace", &sm_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
+	{0}
+};
+
+static ctl_table smfs_table[2] = {
+	{PSDEV_SMFS, "smfs",    NULL, 0, 0555, smfs_ctltable},
+	{0}
+};
+
+
+int  __init  init_smfs_proc_sys(void)
+{
+#ifdef CONFIG_PROC_FS
+	proc_smfs_root = proc_mkdir("smfs", proc_root_fs);
+	if (!proc_smfs_root) {
+		printk(KERN_ERR "SMFS: error registering /proc/fs/smfs\n");
+		RETURN(-ENOMEM);
+	}
+	proc_smfs_root->owner = THIS_MODULE;
+#endif
+
+#ifdef CONFIG_SYSCTL
+	if ( !smfs_table_header )
+		smfs_table_header =
+			register_sysctl_table(smfs_table, 0);
+#endif
+	return 0;
+}
+
+void cleanup_smfs_proc_sys(void) 
+{
+#ifdef CONFIG_SYSCTL
+	if ( smfs_table_header )
+		unregister_sysctl_table(smfs_table_header);
+	smfs_table_header = NULL;
+#endif
+#if CONFIG_PROC_FS
+	remove_proc_entry("smfs", proc_root_fs);
+#endif
+}
+