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)
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])
--- /dev/null
+.Xrefs
+config.log
+config.status
+configure
+Makefile
+Makefile.in
+.deps
+TAGS
+.*.cmd
--- /dev/null
+# 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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 */
--- /dev/null
+#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 */
--- /dev/null
+/*
+ * 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;
+}