Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / smfs / journal.c
index 040393f..715a61c 100644 (file)
@@ -1,22 +1,5 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2004 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+/*
+ *  smfs/inode.c
  *
  */
 
 #include <linux/string.h>
 #include <asm/segment.h>
 #include <asm/uaccess.h>
-#include <linux/obd_class.h>
-#include <linux/obd_support.h>
-#include <linux/lustre_lib.h>
 #include <linux/lustre_idl.h>
-#include <linux/lustre_fsfilt.h>
-#include <linux/lustre_smfs.h>
-#include <linux/lvfs.h>
-#include "smfs_internal.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, void *desc_private)
+void *smfs_trans_start(struct inode *inode, int op)
 {
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-
-        CDEBUG(D_INFO, "trans start %p\n", fsfilt->fs_start);
 
-        SMFS_TRANS_OP(inode, op);
-
-        /* There are some problem here. fs_start in fsfilt is used by lustre
-         * the journal blocks of write rec are not counted in FIXME later */
-        if (fsfilt->fs_start)
-                return fsfilt->fs_start(inode, op, desc_private, 0);
-        return NULL;
+       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(struct inode *inode, void *handle, int force_sync)
+void smfs_trans_commit(void *handle)
 {
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-
-        CDEBUG(D_INFO, "trans commit %p\n", fsfilt->fs_commit);
-
-        if (fsfilt->fs_commit)
-                fsfilt->fs_commit(inode, handle, force_sync);
+       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);
 }
-
-/*smfs_path is gotten from intermezzo*/
-static char* smfs_path(struct dentry *dentry, struct dentry *root, char *buffer,
-                       int buflen)
+/*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 * name = buffer;
-        char * buf_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;
@@ -99,432 +81,169 @@ static char* smfs_path(struct dentry *dentry, struct dentry *root, char *buffer,
                 retval = end;
                 dentry = parent;
         }
-
-        while (end != buf_end)
-                *name++ = *end++;
-        *name = '\0';
         return retval;
 }
-static int smfs_log_path(struct dentry *root, struct dentry *dentry,
-                         char *buffer, int buffer_len)
+                                                                                                                                                                                                     
+static inline char *logit(char *buf, const void *value, int size)
 {
-        char *p_name = buffer + sizeof(int);
-        char *name = NULL;
-        int namelen = 0;
-
-        name = smfs_path(dentry, root, p_name, buffer_len);
-        namelen = cpu_to_le32(strlen(p_name));
-        memcpy(buffer, &namelen, sizeof(int));
-
-        namelen += sizeof(int);
-        RETURN(namelen);
+        char *ptr = (char *)value;
+                                                                                                                                                                                                     
+        memcpy(buf, ptr, size);
+        buf += size;
+        return buf;
 }
-
-static inline int log_it(char *buffer, void *data, int length)
+static inline char *
+journal_log_prefix_with_groups_and_ids(char *buf, int opcode,
+                                       __u32 ngroups, gid_t *groups,
+                                       __u32 fsuid, __u32 fsgid)
 {
-        memcpy(buffer, &length, sizeof(int));
-        memcpy(buffer + sizeof(int), data, length);
-        return (sizeof(int) + length);
+        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 int smfs_post_rec_create(struct inode *dir, struct dentry *dentry,
-                                void *data1, void *data2)
+                                                                                                                                                                                                     
+static inline char *
+journal_log_prefix(char *buf, int opcode)
 {
-        struct smfs_super_info *sinfo;
-        struct dentry *root;
-        struct update_record *rec = NULL;
-        char *buffer = NULL, *p_name;
-        int rc = 0, buffer_length = 0;
-        ENTRY;
-
-        sinfo = S2SMI(dentry->d_inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(buffer, PAGE_SIZE + sizeof(struct update_record));
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-        rec = (struct update_record*)buffer;
-
-        smfs_rec_pack(rec, dentry->d_inode, dir, REINT_CREATE);
-
-        p_name = buffer + sizeof(struct update_record);
-
-        root = dir->i_sb->s_root;
-
-        rc = smfs_log_path(root, dentry, p_name, PAGE_SIZE);
-        if (rc < 0) {
-                GOTO(exit, rc);
-        } else {
-                buffer_length += rc;
-                rc = 0;
-        }
-        if (data1) {
-                /*for symlink data is the path of the symname*/
-                int data_len = strlen(data1);
-
-                buffer_length += log_it(p_name + buffer_length,
-                                        data1, data_len);
-        }
-        rec->ur_len = sizeof(struct update_record) + buffer_length;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, rec->ur_len);
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE + sizeof(struct update_record));
-
-        RETURN(rc);
+        __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 int smfs_post_rec_link(struct inode *dir, struct dentry *dentry,
-                              void *data1, void *data2)
+                                                                                                                                                                                                     
+static inline char *
+journal_log_prefix_with_groups(char *buf, int opcode, 
+                               __u32 ngroups, gid_t *groups)
 {
-        struct smfs_super_info *sinfo;
-        struct dentry *root;
-        struct dentry *new_dentry = (struct dentry *)data1;
-        struct update_record *rec = NULL;
-        char *buffer = NULL, *p_name = NULL;
-        int rc = 0, buffer_length = 0;
-        ENTRY;
-
-        sinfo = S2SMI(dir->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-        OBD_ALLOC(buffer, PAGE_SIZE + sizeof(struct update_record));
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-
-        rec = (struct update_record*)buffer;
-
-        smfs_rec_pack(rec, dentry->d_inode, NULL, REINT_LINK);
-
-        root = dir->i_sb->s_root;
-        /*record old_dentry path*/
-        p_name = buffer + sizeof(struct update_record);
-        rc = smfs_log_path(root, dentry, p_name, PAGE_SIZE);
-        if (rc < 0)
-                GOTO(exit, rc);
-
-        buffer_length += rc;
-        p_name += buffer_length;
-
-        /*record new_dentry path*/
-        rc = smfs_log_path(root, new_dentry, p_name,
-                           PAGE_SIZE - rc - sizeof(int));
-        if (rc < 0) {
-                GOTO(exit, rc);
-        } else {
-                buffer_length += rc;
-                rc = 0;
-        }
-        rec->ur_len = sizeof(struct update_record) + buffer_length;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, rec->ur_len);
-
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE + sizeof(struct update_record));
-        RETURN(rc);
+        return journal_log_prefix_with_groups_and_ids(buf, opcode,
+                                                      ngroups, groups,
+                                                      (__u32)current->fsuid,
+                                                      (__u32)current->fsgid);
 }
 
-static int smfs_post_rec_unlink(struct inode *dir, struct dentry *dentry,
-                                void *data1, void *data2)
+static inline char *log_dentry_version(char *buf, struct dentry *dentry)
 {
-        struct smfs_super_info *sinfo;
-        struct dentry *root;
-        int flag = *((int*)data1);
-        struct update_record *rec = NULL;
-        char *buffer = NULL, *p_name;
-        int rc = 0, buffer_length = 0;
-        char fidname[LL_FID_NAMELEN];
-        struct dentry *new_child = NULL;
-        int namelen;
-        ENTRY;
-
-        sinfo = S2SMI(dentry->d_inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(buffer, PAGE_SIZE + sizeof(struct update_record));
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-        rec = (struct update_record*)buffer;
-
-        smfs_rec_pack(rec, dentry->d_inode, dir, REINT_UNLINK);
-
-        p_name = buffer + sizeof(struct update_record);
-
-        root = dir->i_sb->s_root;
-        rc = smfs_log_path(root, dentry, p_name, PAGE_SIZE);
-        if (rc < 0)
-                GOTO(exit, rc);
-
-        buffer_length += rc;
-        p_name += rc;
-
-        if (!flag) {
-                /*unlink the inode*/
-                namelen = ll_fid2str(fidname, dentry->d_inode->i_ino,
-                                     dentry->d_inode->i_generation);
-
-                down(&sinfo->smsi_delete_dir->d_inode->i_sem);
-                new_child = lookup_one_len(fidname, sinfo->smsi_delete_dir, namelen);
-                if (new_child->d_inode != NULL) {
-                        CERROR("has been deleted obj dentry %lu:%u!\n",
-                               dentry->d_inode->i_ino,
-                               dentry->d_inode->i_generation);
-                        LBUG();
-                }
-
-                /* FIXME-WANGDI: this is ugly, but I do not know how to resolve
-                 * it. */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-                up(&dir->i_zombie);
-#endif
-                lock_kernel();
-                SMFS_CLEAN_INODE_REC(dir);
-                rc = vfs_rename(dir, dentry, sinfo->smsi_delete_dir->d_inode,
-                                new_child);
-                SMFS_SET_INODE_REC(dir);
-                unlock_kernel();
-                
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-                down(&dir->i_zombie);
-#endif
-                up(&sinfo->smsi_delete_dir->d_inode->i_sem);
-                if (rc)
-                        GOTO(exit, rc);
-                /* in vfs_unlink the inode on the dentry will be deleted, so we
-                 * should delete it from dentry hash. */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-                list_del_init(&dentry->d_hash);
-#else
-                hlist_del_init(&dentry->d_hash);
-#endif
-                
-                /* put the new_file_name to the log. */
-                rc = smfs_log_path(root, dentry, p_name,
-                                   PAGE_SIZE - buffer_length);
-                if (rc < 0)
-                        GOTO(exit, rc);
-                buffer_length += rc;
-                rc = 0;
-        } else {
-                /*only decrease the link count*/
-                namelen = sizeof(ino_t);
-
-                buffer_length += log_it(p_name + buffer_length,
-                                        &(dentry->d_inode->i_ino), namelen);
-                SET_REC_DEC_LINK_FLAGS(rec->ur_flags, SMFS_DEC_LINK);
-        }
-        rec->ur_len = sizeof(struct update_record) + buffer_length;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, rec->ur_len);
-exit:
-        if (new_child);
-                dput(new_child);
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE + sizeof(struct update_record));
-
-        RETURN(rc);
-}
-
-static int smfs_post_rec_rename(struct inode *dir, struct dentry *dentry,
-                                void *data1, void *data2)
-{
-        struct smfs_super_info *sinfo;
-        struct dentry *root;
-        struct inode *new_dir = (struct inode *)data1;
-        struct dentry *new_dentry = (struct dentry *)data2;
-        struct update_record *rec = NULL;
-        char *buffer = NULL, *p_name = NULL;
-        int rc = 0, buffer_length = 0;
-        ENTRY;
-
-        sinfo = S2SMI(dir->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(buffer, PAGE_SIZE + sizeof(struct update_record));
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-
-        rec = (struct update_record*)buffer;
-
-        smfs_rec_pack(rec, dentry->d_inode, dir, REINT_RENAME);
-
-        root = dir->i_sb->s_root;
-        /*record old_dentry path*/
-        p_name = buffer + sizeof(struct update_record);
-        rc = smfs_log_path(root, dentry, p_name, PAGE_SIZE);
-        if (rc < 0)
-                GOTO(exit, rc);
-
-        buffer_length += rc;
-        p_name += rc;
-
-        root = new_dir->i_sb->s_root;
-        /*record new_dentry path*/
-        rc = smfs_log_path(root, new_dentry, p_name,
-                           PAGE_SIZE - rc - sizeof(int));
-        if (rc < 0) {
-                GOTO(exit, rc);
-        } else {
-                buffer_length += rc;
-                rc = 0;
-        }
-        rec->ur_len = sizeof(struct update_record) + buffer_length;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, rec->ur_len);
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE + sizeof(struct update_record));
-        RETURN(rc);
+        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 int smfs_post_rec_setattr(struct inode *dir, struct dentry *dentry,
-                                 void *data1, void *data2)
+                                                                                                                                                                                                     
+static inline char *log_version(char *buf, struct smfs_version *pv)
 {
-        struct smfs_super_info *sinfo;
-        struct dentry *root;
-        struct iattr *attr = (struct iattr *)data1;
-        struct update_record *rec = NULL;
-        char *buffer = NULL, *p_name;
-        int rc = 0, buffer_length = 0;
-        ENTRY;
-
-        sinfo = S2SMI(dentry->d_inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(buffer, PAGE_SIZE + sizeof(struct update_record));
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-        rec = (struct update_record*)buffer;
-
-        smfs_rec_pack(rec, dentry->d_inode, attr, REINT_SETATTR);
-
-        root = dentry->d_inode->i_sb->s_root;
-        /*record old_dentry path*/
-        p_name = buffer + sizeof(struct update_record);
-        rc = smfs_log_path(root, dentry, p_name, PAGE_SIZE);
-
-        if (rc < 0) {
-                GOTO(exit, rc);
-        } else {
-                buffer_length += rc;
-                rc = 0;
-        }
-        rec->ur_len = sizeof(struct update_record) + buffer_length;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, rec->ur_len);
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE + sizeof(struct update_record));
-        RETURN(rc);
+        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 int smfs_post_rec_open_close(struct inode *dir, struct dentry *dentry,
-                                    void *data1, void *data2)
+static inline char *journal_log_suffix(char *buf, char *log,
+                                       struct dentry *dentry)
 {
-        struct smfs_super_info *sinfo;
-        struct dentry *root;
-        int open = *(int*)data1;
-        struct update_record *rec = NULL;
-        char *buffer = NULL, *p_name;
-        int rc = 0, buffer_length = 0;
-        ENTRY;
-
-        sinfo = S2SMI(dentry->d_inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(buffer, PAGE_SIZE + sizeof(struct update_record));
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-        rec = (struct update_record*)buffer;
-        if (open)
-                smfs_rec_pack(rec, dentry->d_inode, NULL, REINT_OPEN);
-        else
-                smfs_rec_pack(rec, dentry->d_inode, NULL, REINT_CLOSE);
-        root = dentry->d_inode->i_sb->s_root;
-        /*record old_dentry path*/
-        p_name = buffer + sizeof(struct update_record);
-        rc = smfs_log_path(root, dentry, p_name, PAGE_SIZE);
-
-        if (rc < 0) {
-                GOTO(exit, rc);
-        } else {
-                buffer_length += rc;
-                rc = 0;
-        }
-        rec->ur_len = sizeof(struct update_record) + buffer_length;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, rec->ur_len);
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE + sizeof(struct update_record));
-        RETURN(rc);
+        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));
 }
 
-static int smfs_post_rec_write(struct inode *dir, struct dentry *dentry,
-                               void *data1, void *data2)
+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)
 {
-        struct smfs_record_extents extents;
-        struct smfs_super_info *sinfo;
-        struct dentry *root;
-        struct update_record *rec = NULL;
-        char *buffer = NULL, *p_name;
-        int extents_length = 0;
-        int rc = 0, buffer_length = 0;
-        ENTRY;
-
-        sinfo = S2SMI(dentry->d_inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(buffer, PAGE_SIZE + sizeof(struct update_record));
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-        rec = (struct update_record*)buffer;
-
-        smfs_rec_pack(rec, dentry->d_inode, NULL, REINT_OPEN);
-
-        root = dentry->d_inode->i_sb->s_root;
-        /*record old_dentry path*/
-        p_name = buffer + sizeof(struct update_record);
-        rc = smfs_log_path(root, dentry, p_name, PAGE_SIZE);
-
-        if (rc < 0) {
-                GOTO(exit, rc);
-        } else {
-                buffer_length += rc;
-                rc = 0;
-        }
-        /*record the extents of this write*/
-        extents.sre_count = *((size_t*)data1);
-        extents.sre_off = *((loff_t*)data2);
-        extents_length = sizeof(struct smfs_record_extents);
-
-        buffer_length += log_it(p_name + buffer_length,
-                                &extents, extents_length);
-        rec->ur_len = sizeof(struct update_record) + buffer_length;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, rec->ur_len);
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE + sizeof(struct update_record));
-        RETURN(rc);
+       int rc = 0;     
+       /*should pack the record and dispatch it
+        *create llog handle write to the log*/
+       return rc;
 }
 
-typedef int (*post_kml_rec)(struct inode *dir, struct dentry *dentry,
-                            void *data1, void *data2);
-
-static post_kml_rec smfs_kml_post[REINT_MAX + 1] = {
-        [REINT_SETATTR] smfs_post_rec_setattr,
-        [REINT_CREATE]  smfs_post_rec_create,
-        [REINT_LINK]    smfs_post_rec_link,
-        [REINT_UNLINK]  smfs_post_rec_unlink,
-        [REINT_RENAME]  smfs_post_rec_rename,
-        [REINT_OPEN]    smfs_post_rec_open_close,
-        [REINT_CLOSE]   smfs_post_rec_open_close,
-        [REINT_WRITE]   smfs_post_rec_write,
-};
-
-int smfs_post_kml_rec(struct inode *dir, struct dentry *dst_dentry,
-                      void *data1, void *data2, int op)
+int smfs_journal_mkdir(struct dentry *dentry,
+                       struct smfs_version *tgt_dir_ver,
+                       struct smfs_version *new_dir_ver, 
+                      int mode)
 {
-        return smfs_kml_post[op](dir, dst_dentry, data1, data2);
+       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);
 }