modulefs_DATA = smfs.o
EXTRA_PROGRAMS = smfs
-smfs_SOURCES = super.c options.c inode.c cache.c dir.c
-smfs_SOURCES += sysctl.c file.c symlink.c sm_fs.c
-
+smfs_SOURCES = super.c options.c inode.c cache.c dir.c sysctl.c file.c
+smfs_SOURCES += symlink.c sm_fs.c kml.c reint.c journal.c journal_ext3.c
+smfs_SOURCES += smfs_llog.c
include $(top_srcdir)/Rules
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/lustre_idl.h>
#include <portals/list.h>
+
#include "smfs_internal.h"
struct sm_ops smfs_operations;
extern struct inode_operations smfs_sym_iops;
extern struct file_operations smfs_sym_fops;
extern struct super_operations smfs_super_ops;
+extern struct journal_operations smfs_journal_ops;
+
inline struct super_operations *cache_sops(struct sm_ops *smfs_ops)
{
return &smfs_ops->sm_dentry_ops;
}
+inline struct journal_operations *journal_ops(struct sm_ops *smfs_ops)
+{
+ return &smfs_ops->sm_journal_ops;
+}
+
void init_smfs_cache()
{
memset(&smfs_operations, 0, sizeof(struct sm_ops));
return;
}
+void setup_sm_journal_ops(char *cache_type)
+{
+ struct journal_operations *jops;
+
+ jops = journal_ops(&smfs_operations);
+
+ if (strlen(cache_type) == strlen("ext3") &&
+ memcmp(cache_type, "ext3", strlen("ext3")) == 0 ) {
+#if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
+ memcpy(jops, &smfs_ext3_journal_ops,
+ sizeof(struct journal_operations));
+#else
+ memset(jops, 0, sizeof(journal_operations));
+#endif
+ CDEBUG(D_SUPER, "ops at %p\n", jops);
+ }
+}
+
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/unistd.h>
+#include <linux/lustre_idl.h>
+#include <linux/smp_lock.h>
#include "smfs_internal.h"
+#include "kml_idl.h"
#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
struct inode *inode = NULL;
struct dentry *cache_dentry;
struct dentry parent;
+ void *handle;
int rc = 0;
if (!cache_dir)
RETURN(-ENOENT);
+
+ handle = smfs_trans_start(cache_dir, KML_OPCODE_MKDIR);
+ if (IS_ERR(handle) ) {
+ CERROR("smfs_do_mkdir: no space for transaction\n");
+ RETURN(-ENOSPC);
+ }
prepare_parent_dentry(&parent, cache_dir);
cache_dentry = d_alloc(&parent, &dentry->d_name);
-
+
+ lock_kernel();
if (cache_dir->i_op->mkdir)
rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
GOTO(exit, rc = -ENOENT);
d_instantiate(dentry, inode);
+ /*Do KML post hook*/
+ if (smfs_do_kml(dir)) {
+ rc = post_kml_mkdir(dir, dentry);
+ GOTO(exit, rc);
+ }
duplicate_inode(cache_dir, dir);
exit:
+ unlock_kernel();
+ smfs_trans_commit(handle);
d_unalloc(cache_dentry);
RETURN(rc);
}
#include <linux/stat.h>
#include <linux/unistd.h>
#include <linux/pagemap.h>
+#include <linux/lustre_idl.h>
#include "smfs_internal.h"
/* instantiate a file handle to the cache file */
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/lustre_idl.h>
#include "smfs_internal.h"
void duplicate_inode(struct inode *cache_inode, struct inode *inode)
if (!cache_inode || !cache_sb)
return;
+ duplicate_inode(inode, cache_inode);
if (cache_sb->s_op->write_inode)
cache_sb->s_op->write_inode(cache_inode, wait);
--- /dev/null
+/*
+ * smfs/inode.c
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/segment.h>
+#include <asm/uaccess.h>
+#include <linux/lustre_idl.h>
+#include "kml_idl.h"
+#include "smfs_internal.h"
+extern struct sm_ops smfs_operations;
+
+#define size_round(x) (((x)+3) & ~0x3)
+
+void *smfs_trans_start(struct inode *inode, int op)
+{
+
+ CDEBUG(D_INODE, "trans start %p\n",
+ smfs_operations.sm_journal_ops.tr_start);
+ if (smfs_operations.sm_journal_ops.tr_start) {
+ return smfs_operations.sm_journal_ops.tr_start(inode, op);
+ }
+ return NULL;
+}
+
+void smfs_trans_commit(void *handle)
+{
+ if (smfs_operations.sm_journal_ops.tr_commit) {
+ smfs_operations.sm_journal_ops.tr_commit(handle);
+ }
+ CDEBUG(D_SM, "trans commit %p\n",
+ smfs_operations.sm_journal_ops.tr_commit);
+}
+/*The following function are gotten from intermezzo
+ * smfs_path
+ * logit
+ * journal_log_prefix_with_groups_and_ids
+ * journal_log_prefix
+*/
+static char* smfs_path(struct dentry *dentry, struct dentry *root,
+ char *buffer, int buflen)
+{
+ char * end = buffer+buflen;
+ char * retval;
+
+ *--end = '\0';
+ buflen--;
+ if (dentry->d_parent != dentry && list_empty(&dentry->d_hash)) {
+ buflen -= 10;
+ end -= 10;
+ memcpy(end, " (deleted)", 10);
+ }
+
+ /* Get '/' right */
+ retval = end-1;
+ *retval = '/';
+
+ for (;;) {
+ struct dentry * parent;
+ int namelen;
+
+ if (dentry == root)
+ break;
+ parent = dentry->d_parent;
+ if (dentry == parent)
+ break;
+ namelen = dentry->d_name.len;
+ buflen -= namelen + 1;
+ if (buflen < 0)
+ break;
+ end -= namelen;
+ memcpy(end, dentry->d_name.name, namelen);
+ *--end = '/';
+ retval = end;
+ dentry = parent;
+ }
+ return retval;
+}
+
+static inline char *logit(char *buf, const void *value, int size)
+{
+ char *ptr = (char *)value;
+
+ memcpy(buf, ptr, size);
+ buf += size;
+ return buf;
+}
+static inline char *
+journal_log_prefix_with_groups_and_ids(char *buf, int opcode,
+ __u32 ngroups, gid_t *groups,
+ __u32 fsuid, __u32 fsgid)
+{
+ struct kml_prefix_hdr p;
+ u32 loggroups[NGROUPS_MAX];
+
+ int i;
+
+ p.version = KML_MAJOR_VERSION | KML_MINOR_VERSION;
+ p.pid = cpu_to_le32(current->pid);
+ p.auid = cpu_to_le32(current->uid);
+ p.fsuid = cpu_to_le32(fsuid);
+ p.fsgid = cpu_to_le32(fsgid);
+ p.ngroups = cpu_to_le32(ngroups);
+ p.opcode = cpu_to_le32(opcode);
+ for (i=0 ; i < ngroups ; i++)
+ loggroups[i] = cpu_to_le32((__u32) groups[i]);
+
+ buf = logit(buf, &p, sizeof(struct kml_prefix_hdr));
+ buf = logit(buf, &loggroups, sizeof(__u32) * ngroups);
+ return buf;
+}
+
+static inline char *
+journal_log_prefix(char *buf, int opcode)
+{
+ __u32 groups[NGROUPS_MAX];
+ int i;
+
+ /* convert 16 bit gid's to 32 bit gid's */
+ for (i=0; i<current->ngroups; i++)
+ groups[i] = (__u32) current->groups[i];
+
+ return journal_log_prefix_with_groups_and_ids(buf, opcode,
+ (__u32)current->ngroups,
+ groups,
+ (__u32)current->fsuid,
+ (__u32)current->fsgid);
+}
+
+static inline char *
+journal_log_prefix_with_groups(char *buf, int opcode,
+ __u32 ngroups, gid_t *groups)
+{
+ return journal_log_prefix_with_groups_and_ids(buf, opcode,
+ ngroups, groups,
+ (__u32)current->fsuid,
+ (__u32)current->fsgid);
+}
+
+static inline char *log_dentry_version(char *buf, struct dentry *dentry)
+{
+ struct smfs_version version;
+
+ smfs_getversion(&version, dentry->d_inode);
+
+ version.sm_mtime = HTON__u64(version.sm_mtime);
+ version.sm_ctime = HTON__u64(version.sm_ctime);
+ version.sm_size = HTON__u64(version.sm_size);
+
+ return logit(buf, &version, sizeof(version));
+}
+
+static inline char *log_version(char *buf, struct smfs_version *pv)
+{
+ struct smfs_version version;
+
+ memcpy(&version, pv, sizeof(version));
+
+ version.sm_mtime = HTON__u64(version.sm_mtime);
+ version.sm_ctime = HTON__u64(version.sm_ctime);
+ version.sm_size = HTON__u64(version.sm_size);
+
+ return logit(buf, &version, sizeof(version));
+}
+static inline char *journal_log_suffix(char *buf, char *log,
+ struct dentry *dentry)
+{
+ struct kml_suffix s;
+ struct kml_prefix_hdr *p = (struct kml_prefix_hdr *)log;
+
+ s.prevrec = 0;
+
+ /* record number needs to be filled in after reservation
+ s.recno = cpu_to_le32(rec->recno); */
+ s.time = cpu_to_le32(CURRENT_TIME);
+ s.len = p->len;
+ return logit(buf, &s, sizeof(s));
+}
+
+int smfs_kml_log(struct smfs_super_info *smfs_info,
+ const char *buf, size_t size,
+ const char *string1, int len1,
+ const char *string2, int len2,
+ const char *string3, int len3)
+{
+ int rc = 0;
+ /*should pack the record and dispatch it
+ *create llog handle write to the log*/
+ return rc;
+}
+
+int smfs_journal_mkdir(struct dentry *dentry,
+ struct smfs_version *tgt_dir_ver,
+ struct smfs_version *new_dir_ver,
+ int mode)
+{
+ int opcode = KML_OPCODE_MKDIR;
+ char *buffer, *path, *logrecord, record[292];
+ struct dentry *root;
+ __u32 uid, gid, lmode, pathlen;
+ struct smfs_super_info *smfs_info;
+ struct super_block* sb;
+ int error, size;
+
+ ENTRY;
+
+ sb = dentry->d_inode->i_sb;
+ root = sb->s_root;
+ smfs_info = S2SMI(sb);
+
+ uid = cpu_to_le32(dentry->d_inode->i_uid);
+ gid = cpu_to_le32(dentry->d_inode->i_gid);
+ lmode = cpu_to_le32(mode);
+
+ SM_ALLOC(buffer, PAGE_SIZE);
+ path = smfs_path(dentry, root, buffer, PAGE_SIZE);
+ pathlen = cpu_to_le32(MYPATHLEN(buffer, path));
+ size = sizeof(__u32) * current->ngroups +
+ sizeof(struct kml_prefix_hdr) + 3 * sizeof(*tgt_dir_ver) +
+ sizeof(lmode) + sizeof(uid) + sizeof(gid) + sizeof(pathlen) +
+ sizeof(struct kml_suffix);
+
+ if ( size > sizeof(record) )
+ CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__);
+
+ logrecord = journal_log_prefix(record, opcode);
+
+ logrecord = log_version(logrecord, tgt_dir_ver);
+ logrecord = log_dentry_version(logrecord, dentry->d_parent);
+ logrecord = log_version(logrecord, new_dir_ver);
+ logrecord = logit(logrecord, &lmode, sizeof(lmode));
+ logrecord = logit(logrecord, &uid, sizeof(uid));
+ logrecord = logit(logrecord, &gid, sizeof(gid));
+ logrecord = logit(logrecord, &pathlen, sizeof(pathlen));
+ logrecord = journal_log_suffix(logrecord, record, dentry);
+
+ error = smfs_kml_log(smfs_info, record, size,
+ path, size_round(le32_to_cpu(pathlen)),
+ NULL, 0, NULL, 0);
+ SM_FREE(buffer, PAGE_SIZE);
+ RETURN(error);
+}
--- /dev/null
+/*
+ * smfs/journal_ext3.c
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/lustre_idl.h>
+#if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
+#include <linux/jbd.h>
+#include <linux/ext3_fs.h>
+#include <linux/ext3_jbd.h>
+#endif
+
+#include "smfs_internal.h"
+#include "kml_idl.h"
+
+#if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
+
+#define MAX_PATH_BLOCKS(inode) (PATH_MAX >> EXT3_BLOCK_SIZE_BITS((inode)->i_sb))
+#define MAX_NAME_BLOCKS(inode) (NAME_MAX >> EXT3_BLOCK_SIZE_BITS((inode)->i_sb))
+
+static void *smfs_e3_trans_start(struct inode *inode,
+ int op)
+{
+
+ int trunc_blks, one_path_blks, extra_path_blks;
+ int extra_name_blks, lml_blks, jblocks;
+ __u32 avail_kmlblocks;
+ handle_t *handle;
+
+ avail_kmlblocks = inode->i_sb->u.ext3_sb.s_es->s_free_blocks_count;
+
+ if ( avail_kmlblocks < 3 ) {
+ return ERR_PTR(-ENOSPC);
+ }
+
+ if ((op != KML_OPCODE_UNLINK && op != KML_OPCODE_RMDIR)
+ && avail_kmlblocks < 6 ) {
+ return ERR_PTR(-ENOSPC);
+ }
+ /* Need journal space for:
+ at least three writes to KML (two one block writes, one a path)
+ possibly a second name (unlink, rmdir)
+ possibly a second path (symlink, rename)
+ a one block write to the last rcvd file
+ */
+
+ trunc_blks = EXT3_DATA_TRANS_BLOCKS + 1;
+ one_path_blks = 4*EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode) + 3;
+ lml_blks = 4*EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode) + 2;
+ extra_path_blks = EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode);
+ extra_name_blks = EXT3_DATA_TRANS_BLOCKS + MAX_NAME_BLOCKS(inode);
+
+ /* additional blocks appear for "two pathname" operations
+ and operations involving the LML records
+ */
+
+ switch (op) {
+ case KML_OPCODE_MKDIR:
+ jblocks = one_path_blks + trunc_blks
+ + EXT3_DATA_TRANS_BLOCKS + 4 + 2;
+ break;
+ default:
+ CDEBUG(D_INODE, "invalid operation %d for journal\n", op);
+ return NULL;
+ }
+
+ CDEBUG(D_INODE, "creating journal handle (%d blocks)\n", jblocks);
+
+ lock_kernel();
+ handle = journal_start(EXT3_JOURNAL(inode), jblocks);
+ unlock_kernel();
+
+ return handle;
+}
+
+static void smfs_e3_trans_commit(void *handle)
+{
+ lock_kernel();
+ journal_stop(handle);
+ unlock_kernel();
+}
+
+struct journal_operations smfs_ext3_journal_ops = {
+ .tr_start = smfs_e3_trans_start,
+ .tr_commit = smfs_e3_trans_commit,
+};
+#endif
+
--- /dev/null
+/*
+ * smfs/kml.c
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/lustre_idl.h>
+#include "smfs_internal.h"
+#include "kml_idl.h"
+
+/*FIXME there should be more conditions in this check*/
+int smfs_do_kml(struct inode *dir)
+{
+ struct smfs_super_info *smfs_info = S2SMI(dir->i_sb);
+
+ if (smfs_info->flags & SM_DO_KML) {
+ return 1;
+ }
+ return 0;
+}
+void smfs_getversion(struct smfs_version * smfs_version,
+ struct inode * inode)
+{
+ smfs_version->sm_mtime = (__u64)inode->i_mtime;
+ smfs_version->sm_ctime = (__u64)inode->i_ctime;
+ smfs_version->sm_size = (__u64)inode->i_size;
+}
+
+int smfs_kml_init(struct super_block *sb)
+{
+ struct smfs_super_info *smfs_info = S2SMI(sb);
+ int rc = 0;
+ smfs_info->flags |= SM_DO_KML;
+
+ rc = smfs_llog_setup(&smfs_info->kml_llog);
+
+ RETURN(rc);
+}
+
+int post_kml_mkdir(struct inode *dir, struct dentry *dentry)
+{
+ struct smfs_version tgt_dir_ver, new_dir_ver;
+ int error;
+
+ smfs_getversion(&tgt_dir_ver, dir);
+
+ smfs_getversion(&new_dir_ver, dentry->d_inode);
+
+ error = smfs_journal_mkdir(dentry, &tgt_dir_ver,
+ &new_dir_ver,
+ dentry->d_inode->i_mode);
+ return error;
+}
+
--- /dev/null
+/*
+ * smfs/kml_idl.h
+ */
+
+# define MYPATHLEN(buffer, path) ((buffer) + PAGE_SIZE - (path))
+/*Got these defines from intermezzo*/
+struct kml_log_fd {
+ rwlock_t fd_lock;
+ loff_t fd_offset; /* offset where next record should go */
+ struct file *fd_file;
+ int fd_truncating;
+ unsigned int fd_recno; /* last recno written */
+ struct list_head fd_reservations;
+};
+
+#define KML_MAJOR_VERSION 0x00010000
+#define KML_MINOR_VERSION 0x00000002
+#define KML_OPCODE_NOOP 0
+#define KML_OPCODE_CREATE 1
+#define KML_OPCODE_MKDIR 2
+#define KML_OPCODE_UNLINK 3
+#define KML_OPCODE_RMDIR 4
+#define KML_OPCODE_CLOSE 5
+#define KML_OPCODE_SYMLINK 6
+#define KML_OPCODE_RENAME 7
+#define KML_OPCODE_SETATTR 8
+#define KML_OPCODE_LINK 9
+#define KML_OPCODE_OPEN 10
+#define KML_OPCODE_MKNOD 11
+#define KML_OPCODE_WRITE 12
+#define KML_OPCODE_RELEASE 13
+#define KML_OPCODE_TRUNC 14
+#define KML_OPCODE_SETEXTATTR 15
+#define KML_OPCODE_DELEXTATTR 16
+#define KML_OPCODE_KML_TRUNC 17
+#define KML_OPCODE_GET_FILEID 18
+#define KML_OPCODE_NUM 19
+
+#ifdef __KERNEL__
+# define NTOH__u32(var) le32_to_cpu(var)
+# define NTOH__u64(var) le64_to_cpu(var)
+# define HTON__u32(var) cpu_to_le32(var)
+# define HTON__u64(var) cpu_to_le64(var)
+#else
+# include <glib.h>
+# define NTOH__u32(var) GUINT32_FROM_LE(var)
+# define NTOH__u64(var) GUINT64_FROM_LE(var)
+# define HTON__u32(var) GUINT32_TO_LE(var)
+# define HTON__u64(var) GUINT64_TO_LE(var)
+#endif
+
+
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/lustre_idl.h>
#include "smfs_internal.h"
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);
+ if (option->value)
+ 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;
+ char *name, *value, *left, *tmp;
struct option *tmp_opt;
- int length;
+ int length = 0;
*pos = opt_left;
if (! *opt_left)
return -ENODATA;
-
- left = strchr(opt_left, '=');
-
- if (left == opt_left || !left)
+ left = strchr(opt_left, ',');
+ if (left == opt_left)
return -EINVAL;
+ if (!left){
+ left = opt_left + strlen(opt_left);
+ }
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++;
+ tmp_opt->opt = NULL;
+ tmp_opt->value = NULL;
- opt_left ++; /*after '='*/
+ tmp = opt_left;
+ while(tmp != left && *tmp != '=') {
+ length++;
+ tmp++;
+ }
+ SM_ALLOC(name, length + 1);
+ tmp_opt->opt = name;
+ memset(name, 0, length + 1);
+ while (opt_left != tmp) *name++ = *opt_left++;
- 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 (*tmp == '=') {
+ /*this option has value*/
+ opt_left ++; /*after '='*/
+ if (left == opt_left) {
+ SM_FREE(tmp_opt->opt, length);
+ SM_FREE(tmp_opt, sizeof(struct option));
+ opt_left = *pos;
+ return -EINVAL;
+ }
+ length = left - opt_left + 1;
+ SM_ALLOC(value, length);
+ tmp_opt->value = value;
+ memset(value, 0, length);
+ while (opt_left != left) *value++ = *opt_left++;
}
- 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
+/*
+ * smfs/kml.c
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/lustre_idl.h>
+#include "smfs_internal.h"
+
#include <linux/stat.h>
#include <linux/unistd.h>
#include <linux/miscdevice.h>
-
+#include <linux/lustre_idl.h>
#include "smfs_internal.h"
int sm_stack = 0;
struct smfs_super_info {
struct super_block *smsi_sb;
- struct vfsmount *smsi_mnt; /* mount the cache kere with kern_do_mount (like MDS) */
+ struct vfsmount *smsi_mnt; /* mount the cache kern with kern_do_mount (like MDS) */
+ __u32 flags; /* flags*/
+ struct llog_ctxt *kml_llog; /*smfs kml llog*/
int ops_check;
};
#define SYMLINK_OPS_CHECK 0x20
#define DIR_OPS_CHECK 0x40
+#define SM_DO_KML 0x1
+
#include "smfs_support.h"
+
+struct journal_operations {
+ void *(*tr_start)(struct inode *, int op);
+ void (*tr_commit)(void *handle);
+};
+
struct sm_ops {
/* operations on the file store */
struct super_operations sm_sb_ops;
struct file_operations sm_sym_fops;
struct dentry_operations sm_dentry_ops;
-};
+ struct journal_operations sm_journal_ops;
+};
struct option {
char *opt;
char *value;
void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb);
void init_smfs_cache(void);
void cleanup_smfs_cache(void);
+void setup_sm_journal_ops(char * cache_type);
/*super.c*/
extern int init_smfs(void);
extern int cleanup_smfs(void);
extern ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
extern int smfs_removexattr(struct dentry *dentry, const char *name);
extern void smfs_update_file(struct file *file, struct file *cache_file);
+/*journal.c */
+extern void *smfs_trans_start(struct inode *inode, int op);
+extern void smfs_trans_commit(void *handle);
+extern int smfs_journal_mkdir(struct dentry *dentry,
+ struct smfs_version *tgt_dir_ver,
+ struct smfs_version *new_dir_ver,
+ int mode);
+/*journal_ext3.c*/
+extern struct journal_operations smfs_ext3_journal_ops;
+/*kml.c*/
+extern int smfs_kml_init(struct super_block *sb);
+extern int smfs_do_kml(struct inode *dir);
+extern void smfs_getversion(struct smfs_version * smfs_version, struct inode * inode);
+extern int post_kml_mkdir(struct inode *dir, struct dentry *dentry);
+/*smfs_llog.c*/
+extern int smfs_llog_setup(struct llog_ctxt **ctxt);
#endif /* __LINUX_SMFS_H */
--- /dev/null
+/*
+ * llog.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/lustre_idl.h>
+
+#include "smfs_internal.h"
+
+int smfs_llog_setup(struct llog_ctxt **p_ctxt)
+{
+ int rc = 0;
+
+ RETURN(rc);
+}
+
+
+
+
+
+
#include <linux/slab.h>
#include <linux/loop.h>
#include <linux/errno.h>
+#include <linux/lustre_idl.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)
+static char *smfs_options(char *options, char **devstr, char **namestr, int *kml)
{
struct option *opt_value = NULL;
char *pos;
} else if (!strcmp(opt_value->opt, "type")) {
if (namestr != NULL)
*namestr = opt_value->value;
+ } else if (!strcmp(opt_value->opt, "kml")) {
+ *kml = 1;
} else {
break;
}
char *devstr = NULL, *typestr = NULL;
char *cache_data;
ino_t root_ino;
- int err = 0;
+ int err = 0, kml = 0;
ENTRY;
init_option(data);
/* read and validate options */
- cache_data = smfs_options(data, &devstr, &typestr);
+ cache_data = smfs_options(data, &devstr, &typestr, &kml);
if (*cache_data) {
CERROR("invalid mount option %s\n", (char*)data);
GOTO(out_err, err=-EINVAL);
CERROR("Can not mount %s as %s\n", devstr, typestr);
GOTO(out_err, 0);
}
+
+ if (kml) smfs_kml_init(sb);
+
+ setup_sm_journal_ops(typestr);
+
dget(S2CSB(sb)->s_root);
root_ino = S2CSB(sb)->s_root->d_inode->i_ino;
root_inode = iget(sb, root_ino);
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/lustre_idl.h>
#include "smfs_internal.h"
#include <linux/string.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
-
+#include <linux/lustre_idl.h>
#include "smfs_internal.h"