From 23e081e33b1fd4e5912ab87aa00b2909b835c1a0 Mon Sep 17 00:00:00 2001 From: wangdi Date: Sat, 31 Jan 2004 09:00:38 +0000 Subject: [PATCH] add smfs --- lustre/configure.in | 7 +- lustre/smfs/.cvsignore | 9 +++ lustre/smfs/Makefile.am | 16 +++++ lustre/smfs/options.c | 95 ++++++++++++++++++++++++++ lustre/smfs/smfs_internal.h | 31 +++++++++ lustre/smfs/smfs_support.h | 161 ++++++++++++++++++++++++++++++++++++++++++++ lustre/smfs/super.c | 149 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 lustre/smfs/.cvsignore create mode 100644 lustre/smfs/Makefile.am create mode 100644 lustre/smfs/options.c create mode 100644 lustre/smfs/smfs_internal.h create mode 100644 lustre/smfs/smfs_support.h create mode 100644 lustre/smfs/super.c diff --git a/lustre/configure.in b/lustre/configure.in index 66a1840..4107a0c 100644 --- a/lustre/configure.in +++ b/lustre/configure.in @@ -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 index 0000000..49c6100 --- /dev/null +++ b/lustre/smfs/.cvsignore @@ -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 index 0000000..1dcfa95 --- /dev/null +++ b/lustre/smfs/Makefile.am @@ -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 index 0000000..0b5d76c --- /dev/null +++ b/lustre/smfs/options.c @@ -0,0 +1,95 @@ +/* + * snapfs/options.c + */ +#define DEBUG_SUBSYSTEM S_SM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 index 0000000..6150a93 --- /dev/null +++ b/lustre/smfs/smfs_internal.h @@ -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 index 0000000..433d350 --- /dev/null +++ b/lustre/smfs/smfs_support.h @@ -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 /* THREAD_SIZE */ +#else +# ifndef THREAD_SIZE /* x86_64 has THREAD_SIZE in userspace */ +# define THREAD_SIZE 8192 +# endif +#endif +# include +# 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 index 0000000..b146001 --- /dev/null +++ b/lustre/smfs/super.c @@ -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 + */ +#define DEBUG_SUBSYSTEM S_SNAP + +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#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; +} -- 1.8.3.1