Whamcloud - gitweb
add smfs
authorwangdi <wangdi>
Sat, 31 Jan 2004 09:00:38 +0000 (09:00 +0000)
committerwangdi <wangdi>
Sat, 31 Jan 2004 09:00:38 +0000 (09:00 +0000)
lustre/configure.in
lustre/smfs/.cvsignore [new file with mode: 0644]
lustre/smfs/Makefile.am [new file with mode: 0644]
lustre/smfs/options.c [new file with mode: 0644]
lustre/smfs/smfs_internal.h [new file with mode: 0644]
lustre/smfs/smfs_support.h [new file with mode: 0644]
lustre/smfs/super.c [new file with mode: 0644]

index 66a1840..4107a0c 100644 (file)
@@ -49,6 +49,11 @@ AC_SUBST(SYSIO)
 AC_ARG_ENABLE(snapfs, [ --enable-snapfs build snapfs])
 AM_CONDITIONAL(SNAPFS, test x$enable_snapfs = xyes)
 
+# smfs compilation 
+AC_ARG_ENABLE(smfs, [ --enable-smfs build smfs])
+AM_CONDITIONAL(SMFS, test x$enable_smfs = xyes)
+
+
 
 sinclude(portals/build.m4)
 sinclude(portals/archdep.m4)
@@ -72,6 +77,6 @@ AC_OUTPUT([Makefile lvfs/Makefile portals/Makefile portals/Kernelenv \
          lov/Makefile osc/Makefile mdc/Makefile mds/Makefile ost/Makefile \
          cobd/Makefile ptlbd/Makefile conf/Makefile  tests/Makefile \
          utils/Makefile utils/Lustre/Makefile obdfilter/Makefile \
-          obdclass/Makefile snapfs/Makefile snapfs/utils/Makefile \
+          obdclass/Makefile smfs/Makefile snapfs/Makefile snapfs/utils/Makefile \
          include/Makefile include/linux/Makefile llite/Makefile doc/Makefile scripts/Makefile \
          scripts/lustre.spec])
diff --git a/lustre/smfs/.cvsignore b/lustre/smfs/.cvsignore
new file mode 100644 (file)
index 0000000..49c6100
--- /dev/null
@@ -0,0 +1,9 @@
+.Xrefs
+config.log
+config.status
+configure
+Makefile
+Makefile.in
+.deps
+TAGS
+.*.cmd
diff --git a/lustre/smfs/Makefile.am b/lustre/smfs/Makefile.am
new file mode 100644 (file)
index 0000000..1dcfa95
--- /dev/null
@@ -0,0 +1,16 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+
+DEFS= 
+
+MODULE = smfs
+modulefs_DATA = smfs.o
+EXTRA_PROGRAMS = smfs
+
+smfs_SOURCES = super.c options.c  
+
+
+include $(top_srcdir)/Rules
diff --git a/lustre/smfs/options.c b/lustre/smfs/options.c
new file mode 100644 (file)
index 0000000..0b5d76c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  snapfs/options.c
+ */
+#define DEBUG_SUBSYSTEM S_SM
+
+#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/jbd.h>
+#include <linux/ext3_fs.h>
+#include <linux/snap.h>
+#include <linux/errno.h>
+#include "smfs_internal.h" 
+
+
+static struct list_head option_list;
+char  *options = NULL;
+char  *opt_left = NULL;
+
+int init_option(char *data)
+{
+       INIT_LIST_HEAD(&option_list);
+       SM_ALLOC(options, strlen(data) + 1);
+       if (!options) {
+               CERROR("Can not allocate memory \n");
+               return -ENOMEM;
+       }
+       memcpy(options, data, strlen(data));
+       opt_left = options;
+       return 0;
+}
+/*cleanup options*/
+void cleanup_option(void)
+{
+       struct option *option;
+       while (!list_empty(&option_list)) {
+               option = list_entry(option_list.next, struct option, list);
+               list_del(&option->list);
+               SM_FREE(option->opt, strlen(option->opt) + 1);
+               SM_FREE(option->value, strlen(option->value) + 1);
+               SM_FREE(option, sizeof(struct option));
+       }
+       SM_FREE(options, strlen(options) + 1);
+}
+int get_opt(struct option **option, char **pos)
+{
+       char  *name, *value, *left;
+       struct option *tmp_opt;
+       int  length;
+
+       *pos = opt_left;
+
+       if (! *opt_left)
+               return -ENODATA;
+
+       left = strchr(opt_left, '=');
+
+       if (left == opt_left || !left) 
+               return -EINVAL;
+
+       SM_ALLOC(tmp_opt, sizeof(struct option));       
+               
+       length = left - opt_left + 1;
+       SM_ALLOC(name, length);
+       tmp_opt->opt = name;
+       memset(name, 0, length);
+       while (opt_left != left) *name++ = *opt_left++;
+
+       opt_left ++; /*after '='*/
+
+       left = strchr(opt_left, ',');
+       if (left == opt_left) {
+               SM_FREE(tmp_opt->opt, length);
+               SM_FREE(tmp_opt, sizeof(struct option));
+               opt_left = *pos;
+               return -EINVAL;
+       }
+       if (!left) 
+               left = opt_left + strlen(opt_left); 
+       length = left - opt_left + 1;
+       SM_ALLOC(value, length);
+       tmp_opt->value = value;
+       memset(value, 0, length);
+       while (opt_left != left) *value++ = *opt_left++;
+
+       list_add(&tmp_opt->list, &option_list);
+       
+       if (*opt_left == ',') opt_left ++; /*after ','*/        
+
+       *option = tmp_opt;
+       return 0;
+}
diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h
new file mode 100644 (file)
index 0000000..6150a93
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __LINUX_SMFS_H
+#define __LINUX_SMFS_H
+
+struct smfs_inode_info {
+       struct inode *smi_inode;
+};
+
+struct smfs_super_info {
+       struct super_block *smsi_sb;
+        struct vfsmnt *smsi_mnt;      /* mount the cache kere with kern_do_mount (like MDS) */
+};
+
+#define I2SMI(inode)  ((struct smfs_inode_info *) (&(inode->u.generic_ip)))
+#define S2SMI(sb)   ((struct smfs_super_info *) (&(sb->u.generic_sbp)))
+
+#include "smfs_support.h"
+struct option {
+       char *opt;
+       char *value;
+       struct list_head list;
+};
+/*options.c*/
+extern int get_opt(struct option **option, char **pos);
+extern void cleanup_option(void);
+extern int init_option(char *data);
+/*sysctl.c*/
+extern int sm_debug_level;
+extern int sm_inodes;
+extern long sm_kmemory;
+extern int sm_stack;
+#endif /* __LINUX_SNAPFS_H */
diff --git a/lustre/smfs/smfs_support.h b/lustre/smfs/smfs_support.h
new file mode 100644 (file)
index 0000000..433d350
--- /dev/null
@@ -0,0 +1,161 @@
+#ifndef __LINUX_SMFS_SUPPORT_H
+#define __LINUX_SMFS_SUPPORT_H
+/*Got these defination from lustre. Put here temporaryly*/
+
+#define D_TRACE     (1 << 0) /* ENTRY/EXIT markers */
+#define D_INODE     (1 << 1)
+#define D_SUPER     (1 << 2)
+#define D_EXT2      (1 << 3) /* anything from ext2_debug */
+#define D_MALLOC    (1 << 4) /* print malloc, free information */
+#define D_CACHE     (1 << 5) /* cache-related items */
+#define D_INFO      (1 << 6) /* general information */
+#define D_IOCTL     (1 << 7) /* ioctl related information */
+#define D_BLOCKS    (1 << 8) /* ext2 block allocation */
+#define D_NET       (1 << 9) /* network communications */
+#define D_WARNING   (1 << 10) /* CWARN(...) == CDEBUG (D_WARNING, ...) */
+#define D_BUFFS     (1 << 11)
+#define D_OTHER     (1 << 12)
+#define D_DENTRY    (1 << 13)
+#define D_PAGE      (1 << 15) /* bulk page handling */
+#define D_DLMTRACE  (1 << 16)
+#define D_ERROR     (1 << 17) /* CERROR(...) == CDEBUG (D_ERROR, ...) */
+#define D_EMERG     (1 << 18) /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
+#define D_HA        (1 << 19) /* recovery and failover */
+#define D_RPCTRACE  (1 << 20) /* for distributed debugging */
+#define D_VFSTRACE  (1 << 21)
+#define D_SM      (1 << 22)
+
+
+#ifdef __KERNEL__
+# include <linux/sched.h> /* THREAD_SIZE */
+#else 
+# ifndef THREAD_SIZE /* x86_64 has THREAD_SIZE in userspace */
+#  define THREAD_SIZE 8192
+# endif
+#endif
+# include <linux/vmalloc.h> 
+# define sm_debug_msg(mask, file, fn, line, stack, format, a...)    \
+    printk("%02x (@%lu %s:%s,l. %d %d %lu): " format,                    \
+           (mask), (long)time(0), file, fn, line,                   \
+           getpid() , stack, ## a);
+
+#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
+
+#ifdef __KERNEL__
+# ifdef  __ia64__
+#  define CDEBUG_STACK (THREAD_SIZE -                                      \
+                        ((unsigned long)__builtin_dwarf_cfa() &            \
+                         (THREAD_SIZE - 1)))
+# else
+#  define CDEBUG_STACK (THREAD_SIZE -                                      \
+                        ((unsigned long)__builtin_frame_address(0) &       \
+                         (THREAD_SIZE - 1)))
+# endif
+
+#define CHECK_STACK(stack)                                                    \
+        do {                                                                  \
+                if ((stack) > 3*THREAD_SIZE/4 && (stack) > sm_stack) {      \
+                        printk( "maximum lustre stack %u\n",                 \
+                                          sm_stack = (stack));              \
+                }                                                             \
+        } while (0)
+#else /* __KERNEL__ */
+#define CHECK_STACK(stack) do { } while(0)
+#define CDEBUG_STACK (0L)
+#endif /* __KERNEL__ */
+
+#if 1
+#define CDEBUG(mask, format, a...)                                            \
+do {                                                                          \
+        CHECK_STACK(CDEBUG_STACK);                                           \
+        if (!(mask) || ((mask) & (D_ERROR | D_EMERG | D_WARNING)) ||          \
+            (sm_debug_level & (mask))) {                                    \
+               printk("SM_DEBUG: (%s %d):", __FILE__, __LINE__);             \
+               printk(format, ## a);                                         \
+       }                                                                     \
+} while (0)
+
+#define CWARN(format, a...)  CDEBUG(D_WARNING, format, ## a)
+#define CERROR(format, a...) CDEBUG(D_ERROR, format, ## a)
+#define CEMERG(format, a...) CDEBUG(D_EMERG, format, ## a)
+
+#define GOTO(label, rc)                                                 \
+do {                                                                    \
+        long GOTO__ret = (long)(rc);                                    \
+        CDEBUG(D_TRACE,"SM_DEBUG: (%s %d):Process leaving via %s (rc=%lu : %ld : %lx)\n", \
+               __FILE__, __LINE__, #label, (unsigned long)GOTO__ret,    \
+              (signed long)GOTO__ret,                                  \
+               (signed long)GOTO__ret);                                 \
+        goto label;                                                     \
+} while (0)
+
+#define RETURN(rc)                                                      \
+do {                                                                    \
+        typeof(rc) RETURN__ret = (rc);                                  \
+        CDEBUG(D_TRACE, "Process %d leaving %s (rc=%lu : %ld : %lx)\n", \
+               current->pid, __FUNCTION__, (long)RETURN__ret,          \
+              (long)RETURN__ret, (long)RETURN__ret);                   \
+        return RETURN__ret;                                             \
+} while (0)
+
+#define ENTRY                                                           \
+do {                                                                    \
+       CDEBUG(D_TRACE,  "SM_DEBUG: (%s %d): Process %d enter %s\n",  \
+              __FILE__, __LINE__, current->pid, __FUNCTION__);         \
+} while (0)
+
+#define EXIT                                                            \
+do {                                                                    \
+        CDEBUG(D_TRACE, "SM_DEBUG: (%s %d): Process %d leaving %s \n",                 \
+              __FILE__, __LINE__, current->pid, __FUNCTION__);                         \
+} while(0)
+#else
+#define CDEBUG(mask, format, a...)      do { } while (0)
+#define CWARN(format, a...)             do { } while (0)
+#define CERROR(format, a...)            printk("<3>" format, ## a)
+#define CEMERG(format, a...)            printk("<0>" format, ## a)
+#define GOTO(label, rc)                 do { (void)(rc); goto label; } while (0)
+#define RETURN(rc)                      return (rc)
+#define ENTRY                           do { } while (0)
+#define EXIT                            do { } while (0)
+#endif
+
+#define SM_ALLOC(ptr, size)                                            \
+do {                                                                   \
+       if (size <= 4096) {                                             \
+               ptr = kmalloc((unsigned long) size, GFP_KERNEL);        \
+                CDEBUG(D_MALLOC, "Proc %d %s:%d kmalloced: %d at %x.\n",\
+                      current->pid, __FUNCTION__, __LINE__,            \
+                      (int) size, (int) ptr);                          \
+       } else {                                                        \
+               ptr = vmalloc((unsigned long) size);                    \
+               CDEBUG(D_MALLOC, "Proc %d %s:%d vmalloced: %d at %x.\n",\
+                      current->pid, __FUNCTION__, __LINE__,            \
+                      (int) size, (int) ptr);                          \
+       }                                                               \
+       if (ptr == 0) {                                                 \
+               printk("kernel malloc returns 0 at %s:%d\n",            \
+                      __FILE__, __LINE__);                             \
+       } else {                                                        \
+               memset(ptr, 0, size);                                   \
+               sm_kmemory += size;                                     \
+       }                                                               \
+} while (0)
+
+#define SM_FREE(ptr,size)                                              \
+do {                                                                   \
+       sm_kmemory -= size;                                             \
+       if (size <= 4096) {                                             \
+               CDEBUG(D_MALLOC, "Proc %d %s:%d kfreed: %d at %x.\n",   \
+                      current->pid, __FUNCTION__, __LINE__,            \
+                      (int) size, (int) ptr);                          \
+               kfree((ptr));                                           \
+       } else {                                                        \
+               CDEBUG(D_MALLOC, "Proc %d %s:%d vfreed: %d at %x.\n",   \
+                      current->pid, __FUNCTION__, __LINE__,            \
+                      (int) size, (int) ptr);                          \
+               vfree((ptr));                                           \
+       }                                                               \
+} while (0)
+
+#endif /*__LINUX_SMFS_SUPPORT_H */
diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c
new file mode 100644 (file)
index 0000000..b146001
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *  snap_current
+ *
+ *  Copyright (C) 1998 Peter J. Braam
+ *  Copyright (C) 2000 Stelias Computing, Inc.
+ *  Copyright (C) 2000 Red Hat, Inc.
+ *  Copyright (C) 2000 Mountain View Data, Inc.
+ *
+ *  Author: Peter J. Braam <braam@mountainviewdata.com>
+ */
+#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/loop.h>
+//#include <linux/jbd.h>
+//#include <linux/ext3_fs.h>
+#include <linux/errno.h>
+#include "smfs_internal.h" 
+
+/* Find the options for the clone. These consist of a cache device
+   and an index in the snaptable associated with that device. 
+*/
+static char *smfs_options(char *options, char **devstr, char **namestr)
+{
+       struct option *opt_value = NULL;
+       char *pos;
+       
+       while (!(get_opt(&opt_value, &pos))) {                  
+               if (!strcmp(opt_value->opt, "dev")) {
+                       if (devstr != NULL)
+                               *devstr = opt_value->value;
+               } else if (!strcmp(opt_value->opt, "type")) {
+                       if (namestr != NULL)
+                               *namestr = opt_value->value;
+               } else {
+                       break;
+               }
+       }
+       return pos;
+}
+extern struct super_operations smfs_super_ops;
+
+static struct super_block *sm_mount_cache(struct super_block *sb, 
+                                         char *devstr,
+                                         char *typestr)
+{
+       return NULL;    
+}
+
+struct super_block *
+smfs_read_super(
+        struct super_block *sb,
+        void *data,
+        int silent)
+{
+       struct smfs_inode_info *smi;
+       struct smfs_super_info *smb;
+       struct dentry *bottom_root;
+       struct inode *root_inode = NULL;
+       struct super_block *cache_sb;
+       char *devstr = NULL, *typestr = NULL;
+       char *cache_data;
+       ino_t root_ino;
+       int err = 0;
+
+       ENTRY;
+
+       CDEBUG(D_SUPER, "mount opts: %s\n", data ? (char *)data : "(none)");
+       
+       init_option(data);
+       /* read and validate options */
+       cache_data = smfs_options(data, &devstr, &typestr);
+       if (*cache_data) {
+               CERROR("invalid mount option %s\n", (char*)data);
+               GOTO(out_err, err=-EINVAL);
+       }
+       if (!typestr || !devstr) {
+               CERROR("mount options name and dev mandatory\n");
+               GOTO(out_err, err=-EINVAL);
+       }
+       
+       cache_sb = sm_mount_cache(sb, devstr, typestr);
+       if (!cache_sb) {
+               CERROR("Can not mount %s as %s\n", devstr, typestr);
+               GOTO(out_err, err=-EINVAL);
+       }
+       /* set up the super block */
+       smb = S2SMI(sb); 
+       smb->smsi_sb = cache_sb;
+       sb->s_op = &smfs_super_ops;
+
+       bottom_root = dget(cache_sb->s_root);
+       if (!bottom_root) {
+               CERROR("bottom not mounted\n");
+               GOTO(out_err, err=-ENOENT);
+        }
+
+       root_ino = bottom_root->d_inode->i_ino;
+       smi = I2SMI(root_inode);
+       /*FIXME Intialize smi here*/
+       
+       CDEBUG(D_SUPER, "readinode %p, root ino %ld, root inode at %p\n",
+              sb->s_op->read_inode, root_ino, root_inode);
+       
+       sb->s_root = d_alloc_root(bottom_root->d_inode);
+       
+       if (!sb->s_root) {
+               GOTO(out_err, err=-EINVAL);
+       }
+
+       CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
+                (ulong) sb, (ulong) &sb->u.generic_sbp);
+       
+ out_err:
+       cleanup_option();
+       if (err)
+               return NULL;
+       return sb;
+}
+
+static DECLARE_FSTYPE(smfs_type, "smfs", smfs_read_super, 0);
+
+int init_smfs(void)
+{
+       int err;
+
+       err = register_filesystem(&smfs_type);
+       if (err) {
+               CERROR("smfs: failed in register Storage Management filesystem!\n");
+       }
+       return err;
+}
+
+int cleanup_smfs(void)
+{
+       int err;
+
+       ENTRY;
+       err = unregister_filesystem(&smfs_type);
+       if (err) {
+               CERROR("smfs: failed to unregister Storage Management filesystem!\n");
+       }
+       return 0;
+}