Whamcloud - gitweb
b=5881
authortappro <tappro>
Wed, 13 Apr 2005 07:01:32 +0000 (07:01 +0000)
committertappro <tappro>
Wed, 13 Apr 2005 07:01:32 +0000 (07:01 +0000)
update kml and lru stuff in accordance with new DLD for SMFS
remove unused file journal.c
add changes to Makefile
using new options retrival method in smfs_lib

lustre/smfs/Makefile.in
lustre/smfs/cache_space.c
lustre/smfs/journal.c [deleted file]
lustre/smfs/kml.c
lustre/smfs/smfs_lib.c
lustre/smfs/smfs_llog.c

index 1f8f387..28821e8 100644 (file)
@@ -1,6 +1,6 @@
 MODULES := smfs
-smfs-objs := super.o options.o inode.o cache.o cache_space.o dir.o ioctl.o
-smfs-objs += sysctl.o file.o symlink.o smfs_lib.o kml.o smfs_llog.o
-smfs-objs += mds_kml.o ost_kml.o 
+smfs-objs := super.o inode.o cache.o dir.o fsfilt.o ioctl.o
+smfs-objs += sysctl.o file.o symlink.o smfs_lib.o smfs_llog.o
+smfs-objs += kml.o mds_kml.o ost_kml.o cache_space.o
 @SNAPFS_TRUE@smfs-objs += smfs_cow.o 
 @INCLUDE_RULES@
index ec87b6d..1e27fff 100644 (file)
@@ -44,81 +44,13 @@ struct cache_purge_param {
 static struct cache_purge_queue smfs_cpq;
 static struct cache_purge_queue *cpq = &smfs_cpq;
 
-#define CACHE_HOOK "cache_hook"
-int cache_space_pre_hook(struct inode *inode, void *dentry,
-                         void *data1, void *data2, int op, void *handle)
-{
-        int rc = 0;
-        ENTRY;
-
-        if (smfs_cache_hook(inode)) {                                          
-               if (!handle) {                                                  
-                        handle = smfs_trans_start(inode, KML_CACHE_NOOP, NULL);   
-                        if (IS_ERR(handle)) {                                   
-                                RETURN(PTR_ERR(handle));
-                        }                                                       
-                }                                                               
-                cache_space_pre(inode, op);                                       
-        }                                                                       
-        RETURN(rc); 
-}
-
-int cache_space_post_hook(struct inode *inode, void *de, void *data1, 
-                          void *data2, int op, void *handle)
-{
-        int rc = 0;
-        ENTRY;
-        if (smfs_cache_hook(inode)) {      
-                struct inode *new_inode = (struct inode*)data1;
-                struct dentry *new_dentry = (struct dentry*)data2;        
-                struct dentry *dentry = (struct dentry *)de;
-            
-                LASSERT(handle != NULL);                                
-                rc = cache_space_post(op, handle, inode, dentry, new_inode, 
-                                      new_dentry);
-        }
-        RETURN(rc);                                                               
-}
-
-int cache_space_hook_init(struct super_block *sb)
-{
-        struct smfs_super_info *smfs_info = S2SMI(sb);
-        struct smfs_hook_ops    *cache_hops;
-        int    rc = 0;
-        ENTRY;
-
-        cache_hops = smfs_alloc_hook_ops(CACHE_HOOK, cache_space_pre_hook, 
-                                         cache_space_post_hook);
-        if (!cache_hops) {
-                RETURN(-ENOMEM);
-        }
-        rc = smfs_register_hook_ops(smfs_info, cache_hops); 
-        if (rc) {
-                smfs_free_hook_ops(cache_hops);
-                RETURN(rc);
-        }
-        SMFS_SET_CACHE_HOOK(smfs_info);
-
-        RETURN(0);
-}
-
-int cache_space_hook_exit(struct smfs_super_info *smfs_info)
-{
-        struct smfs_hook_ops *cache_hops; 
-
-        cache_hops = smfs_unregister_hook_ops(smfs_info, CACHE_HOOK);
-        smfs_free_hook_ops(cache_hops);
-
-        SMFS_CLEAN_CACHE_HOOK(smfs_info);
-        return 0;
-}
-
 static int cache_leaf_node(struct dentry *dentry, __u64 *active_entry)
 {
         struct inode *inode = dentry->d_inode;
 
-        if (!dentry->d_inode)
+        if (!inode)
                 return 0;
+        
         if (S_ISDIR(inode->i_mode)) {
                 if (inode->i_nlink != 2)
                         return 0;
@@ -326,23 +258,14 @@ static void check_cache_space(void)
         EXIT;
 }
 
-void cache_space_pre(struct inode *inode, int op)
-{
-        ENTRY;
-
-        /* FIXME have not used op */
-        check_cache_space();
-        
-        EXIT;
-}
-
 static int cache_space_hook_lru(struct inode *inode, struct inode *parent,
-                                void *handle, int op, int flags)
+                                int op, int flags)
 {
         struct fsfilt_operations *fsops = S2SMI(cpq->cpq_sb)->sm_fsfilt;
         struct llog_ctxt *ctxt = cpq->cpq_loghandle->lgh_ctxt;
         struct llog_lru_rec *llr = NULL;
         struct llog_cookie *logcookie = NULL;
+        void * handle = NULL;
         int cookie_size = sizeof(struct llog_cookie);
         int rc = 0, err;
         ENTRY;
@@ -356,33 +279,32 @@ static int cache_space_hook_lru(struct inode *inode, struct inode *parent,
         if (!logcookie)
                 GOTO(out, rc = -ENOMEM);
 
-        if (op & CACHE_SPACE_DELETE) {
+         if (op & CACHE_SPACE_DELETE) {
                 rc = get_lru_logcookie(inode, logcookie);
                 if (rc < 0)
-                        GOTO(out, rc);
+                        goto out;
 
                 if (logcookie->lgc_lgl.lgl_oid == 0) {
                         CWARN("inode %lu/%u is not in lru list\n",
                               inode->i_ino, inode->i_generation);
-                        GOTO(insert, rc = -ENOENT);
+                        rc = -ENOENT;
                 }
-                if (flags && llog_cat_half_bottom(logcookie, ctxt->loc_handle))
-                        GOTO(out, rc = 0);
-
-                rc = llog_cancel(ctxt, 1, logcookie, 0, NULL);
-                if (!rc) {
-                        memset(logcookie, 0, cookie_size);
-                        rc = set_lru_logcookie(inode, handle, logcookie);
+                else {
+                        rc = 0;
+                        if (flags && llog_cat_half_bottom(logcookie, ctxt->loc_handle))
+                               goto out;
+
+                        rc = llog_cancel(ctxt, 1, logcookie, 0, NULL);
+                        if (!rc) {
+                                memset(logcookie, 0, cookie_size);
+                                rc = set_lru_logcookie(inode, handle, logcookie);
+                        }
                         if (rc)
-                                GOTO(out, rc);
-                } else {
-                        CERROR("failed at llog_cancel: %d\n", rc);
-                        GOTO(out, rc);
+                                        goto out;
                 }
         }
 
-insert:
-        if (op & CACHE_SPACE_INSERT) {
+         if (op & CACHE_SPACE_INSERT) {
                 LASSERT(parent != NULL);
                 OBD_ALLOC(llr, sizeof(*llr));
                 if (llr == NULL)
@@ -463,81 +385,19 @@ static int cache_purge_thread(void *args)
         RETURN(0);
 }
 
-int cache_space_hook_setup(struct super_block *sb)
-{
-        struct llog_ctxt *ctxt;
-        int rc;
-        ENTRY;
-
-        /* first to initialize the cache lru catalog on local fs */
-        rc = llog_catalog_setup(&ctxt, CACHE_LRU_LOG,
-                                S2SMI(sb)->smsi_exp,
-                                S2SMI(sb)->smsi_ctxt,
-                                S2SMI(sb)->sm_fsfilt,
-                                S2SMI(sb)->smsi_logs_dir,
-                                S2SMI(sb)->smsi_objects_dir);
-        if (rc) {
-                CERROR("failed to initialize cache lru list catalog %d\n", rc);
-                RETURN(rc);
-        }
-        cpq->cpq_sb = sb;
-        cpq->cpq_loghandle = ctxt->loc_handle;
-
-        /* start cache purge daemon, only one daemon now */
-        init_waitqueue_head(&cpq->cpq_waitq);
-        init_completion(&cpq->cpq_comp);
-        cpq->cpq_flags = 0;
-
-        rc = kernel_thread(cache_purge_thread, NULL, CLONE_VM | CLONE_FILES);
-        if (rc < 0) {
-                CERROR("cannot start thread: %d\n", rc);
-                GOTO(err_out, rc);
-        }
-        wait_for_completion(&cpq->cpq_comp);
-
-        RETURN(0);
-err_out:
-        llog_catalog_cleanup(ctxt);
-        OBD_FREE(ctxt, sizeof(*ctxt));
-        RETURN(rc);
-}
-
-int cache_space_hook_cleanup(void)
-{
-        struct llog_ctxt *ctxt;
-        int rc;
-        ENTRY;
-
-        init_completion(&cpq->cpq_comp);
-        cpq->cpq_flags = SVC_STOPPING;
-        wake_up(&cpq->cpq_waitq);
-        wait_for_completion(&cpq->cpq_comp);
-        
-        ctxt = cpq->cpq_loghandle->lgh_ctxt;
-        rc = llog_catalog_cleanup(ctxt);
-        OBD_FREE(ctxt, sizeof(*ctxt));
-        
-        if (rc)
-                CERROR("failed to clean up cache lru list catalog %d\n", rc);
-
-        RETURN(rc);
-}
-
-static int cache_space_hook_create(void *handle, struct inode *dir,
-                                   struct dentry *dentry, struct inode *new_dir,
-                                   struct dentry *new_dentry)
+/* Hooks */
+static int cache_space_hook_create (struct inode *dir, struct dentry * dentry)
 {
         __u64 active_entry = 0;
         int rc;
         ENTRY;
 
         LASSERT(cache_leaf_node(dentry, NULL));
-        rc = cache_space_hook_lru(dentry->d_inode, dir, handle,
-                                  CACHE_SPACE_INSERT, 0);
+        rc = cache_space_hook_lru(dentry->d_inode, dir, CACHE_SPACE_INSERT, 0);
         if (rc)
                 RETURN(rc);
         if (cache_leaf_node(dentry->d_parent, &active_entry)) {
-                rc = cache_space_hook_lru(dir,NULL,handle,CACHE_SPACE_DELETE,0);
+                rc = cache_space_hook_lru(dir, NULL, CACHE_SPACE_DELETE, 0);
                 if (rc)
                         RETURN(rc);
         }
@@ -545,41 +405,37 @@ static int cache_space_hook_create(void *handle, struct inode *dir,
                 rc = get_active_entry(dir, &active_entry);
         active_entry ++;
         if (!rc)
-                rc = set_active_entry(dir, &active_entry, handle);
+                rc = set_active_entry(dir, &active_entry, NULL);
         RETURN(rc);
 }
 
-static int cache_space_hook_lookup(void *handle, struct inode *dir,
-                                   struct dentry *dentry, struct inode *new_dir,
-                                   struct dentry *new_dentry)
+static int cache_space_hook_lookup(struct inode *dir, struct dentry *dentry)
 {
         __u64 active_entry;
         int rc = 0;
         ENTRY;
 
         if (cache_leaf_node(dentry, &active_entry))
-                rc = cache_space_hook_lru(dentry->d_inode, dir, handle,
-                                CACHE_SPACE_DELETE | CACHE_SPACE_INSERT,1);
+                rc = cache_space_hook_lru(dentry->d_inode, dir, 
+                                          CACHE_SPACE_DELETE | CACHE_SPACE_INSERT, 1);
         RETURN(rc);
 }
 
-static int cache_space_hook_link(void *handle, struct inode *dir,
-                                 struct dentry *dentry, struct inode *new_dir,
-                                 struct dentry *new_dentry)
+static int cache_space_hook_link(struct inode *dir, struct dentry *dentry)
 {
         __u64 active_entry = 0;
         int rc = 0;
         ENTRY;
 
         if (cache_pre_leaf_node(dentry, NULL, 1)) {
-                rc = cache_space_hook_lru(dentry->d_inode, NULL,
-                                          handle, CACHE_SPACE_DELETE, 0);
+                rc = cache_space_hook_lru(dentry->d_inode, NULL, 
+                                          CACHE_SPACE_DELETE, 0);
                 if (rc)
                         RETURN(rc);
         }
 
         if (cache_leaf_node(dentry->d_parent, &active_entry)) {
-                rc = cache_space_hook_lru(dir, NULL, handle, CACHE_SPACE_DELETE, 0);
+                rc = cache_space_hook_lru(dir, NULL, CACHE_SPACE_DELETE, 0);
                 if (rc)
                         RETURN(rc);
         }
@@ -588,13 +444,11 @@ static int cache_space_hook_link(void *handle, struct inode *dir,
                 rc = get_active_entry(dir, &active_entry);
         active_entry ++;
         if (!rc)
-                rc = set_active_entry(dir, &active_entry, handle);
+                rc = set_active_entry(dir, &active_entry, NULL);
         RETURN(rc);
 }
 
-static int cache_space_hook_unlink(void *handle, struct inode *dir,
-                                   struct dentry *dentry, struct inode *new_dir,
-                                   struct dentry *new_dentry)
+static int cache_space_hook_unlink(struct inode *dir, struct dentry *dentry)
 {
         __u64 active_entry;
         int rc = 0;
@@ -602,63 +456,57 @@ static int cache_space_hook_unlink(void *handle, struct inode *dir,
 
         if (cache_pre_leaf_node(dentry, NULL, 0))
                 rc = cache_space_hook_lru(dentry->d_inode, NULL,
-                                          handle, CACHE_SPACE_DELETE, 0);
+                                          CACHE_SPACE_DELETE, 0);
         else if (cache_leaf_node(dentry, NULL))
                         rc = cache_space_hook_lru(dentry->d_inode, dir,
-                                                  handle, CACHE_SPACE_INSERT,0);
+                                                  CACHE_SPACE_INSERT,0);
         if (rc)
                 RETURN(rc);
 
         rc = get_active_entry(dir, &active_entry);
         active_entry --;
         if (!rc)
-                rc = set_active_entry(dir, &active_entry, handle);
+                rc = set_active_entry(dir, &active_entry, NULL);
         if (!rc && cache_leaf_node(dentry->d_parent, &active_entry))
                 rc = cache_space_hook_lru(dir,
                                           dentry->d_parent->d_parent->d_inode,
-                                          handle, CACHE_SPACE_INSERT, 0);
+                                          CACHE_SPACE_INSERT, 0);
         RETURN(rc);
 }
 
-static int cache_space_hook_mkdir(void *handle, struct inode *dir,
-                                  struct dentry *dentry, struct inode *new_dir,
-                                  struct dentry *new_dentry)
+static int cache_space_hook_mkdir(struct inode *dir, struct dentry *dentry)
 {
         __u64 active_entry;
         int rc;
         ENTRY;
 
         LASSERT(cache_leaf_node(dentry, &active_entry));
-        rc = cache_space_hook_lru(dentry->d_inode, dir, handle,
-                                  CACHE_SPACE_INSERT, 0);
+        rc = cache_space_hook_lru(dentry->d_inode, dir, CACHE_SPACE_INSERT, 0);
 
         if (!rc && cache_pre_leaf_node(dentry->d_parent, &active_entry, 3))
-                rc = cache_space_hook_lru(dir, NULL, handle, CACHE_SPACE_DELETE, 0);
+                rc = cache_space_hook_lru(dir, NULL, CACHE_SPACE_DELETE, 0);
         RETURN(rc);
 }
 
-static int cache_space_hook_rmdir(void *handle, struct inode *dir,
-                                  struct dentry *dentry, struct inode *new_dir,
-                                  struct dentry *new_dentry)
+static int cache_space_hook_rmdir(struct inode *dir, struct dentry *dentry)
 {
         __u64 active_entry;
         int rc;
         ENTRY;
 
         LASSERT(cache_pre_leaf_node(dentry, &active_entry, 2));
-        rc = cache_space_hook_lru(dentry->d_inode, NULL, handle,
+        rc = cache_space_hook_lru(dentry->d_inode, NULL, 
                                   CACHE_SPACE_DELETE, 0);
 
         if (!rc && cache_leaf_node(dentry->d_parent, &active_entry))
                 rc = cache_space_hook_lru(dir,
                                           dentry->d_parent->d_parent->d_inode,
-                                          handle, CACHE_SPACE_INSERT, 0);
+                                          CACHE_SPACE_INSERT, 0);
         RETURN(rc);
 }
 
-static int cache_space_hook_rename(void *handle, struct inode *old_dir,
-                                   struct dentry *old_dentry, struct inode *new_dir,
-                                   struct dentry *new_dentry)
+static int cache_space_hook_rename(struct inode *old_dir, struct dentry *old_dentry,
+                                   struct inode *new_dir, struct dentry *new_dentry)
 {
         __u64 active_entry;
         int rc = 0;
@@ -667,10 +515,10 @@ static int cache_space_hook_rename(void *handle, struct inode *old_dir,
         if (new_dentry->d_inode) {
                 if (cache_pre_leaf_node(new_dentry, NULL, 0))
                         rc = cache_space_hook_lru(new_dentry->d_inode, NULL,
-                                                  handle, CACHE_SPACE_DELETE,0);
+                                                  CACHE_SPACE_DELETE,0);
                 else if (cache_leaf_node(new_dentry, NULL))
                         rc = cache_space_hook_lru(new_dentry->d_inode,
-                                                  new_dir, handle,
+                                                  new_dir,
                                                   CACHE_SPACE_INSERT,0);
         }
 
@@ -679,7 +527,7 @@ static int cache_space_hook_rename(void *handle, struct inode *old_dir,
 
         if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
                 if (cache_leaf_node(new_dentry->d_parent, &active_entry)) {
-                        rc = cache_space_hook_lru(new_dir, NULL, handle,
+                        rc = cache_space_hook_lru(new_dir, NULL,
                                                   CACHE_SPACE_DELETE, 0);
                         if (rc)
                                 RETURN(rc);
@@ -688,57 +536,237 @@ static int cache_space_hook_rename(void *handle, struct inode *old_dir,
                         rc = get_active_entry(new_dir, &active_entry);
                 active_entry ++;
                 if (!rc)
-                        rc = set_active_entry(new_dir, &active_entry, handle);
+                        rc = set_active_entry(new_dir, &active_entry, NULL);
                 if (rc)
                         RETURN(rc);
                 rc = get_active_entry(old_dir, &active_entry);
                 active_entry --;
                 if (!rc)
-                        rc = set_active_entry(old_dir, &active_entry, handle);
+                        rc = set_active_entry(old_dir, &active_entry, NULL);
         } else if (cache_pre_leaf_node(new_dentry->d_parent, &active_entry, 3)) {
-                rc = cache_space_hook_lru(new_dir, NULL, handle,
+                rc = cache_space_hook_lru(new_dir, NULL,
                                           CACHE_SPACE_DELETE, 0);
         }
 
         if (!rc && cache_leaf_node(old_dentry->d_parent, &active_entry)) {
                 rc = cache_space_hook_lru(old_dir,
                                           old_dentry->d_parent->d_parent->d_inode,
-                                          handle, CACHE_SPACE_INSERT, 0);
+                                          CACHE_SPACE_INSERT, 0);
         }
         
         RETURN(rc);
 }
 
-typedef int (*cache_hook_op)(void *handle, struct inode *old_dir,
-                             struct dentry *old_dentry, struct inode *new_dir,
-                             struct dentry *new_dentry);
-
-static  cache_hook_op cache_space_hook_ops[HOOK_MAX + 1] = {
-        [HOOK_CREATE]     cache_space_hook_create,
-        [HOOK_LOOKUP]     cache_space_hook_lookup,
-        [HOOK_LINK]       cache_space_hook_link,
-        [HOOK_UNLINK]     cache_space_hook_unlink,
-        [HOOK_SYMLINK]    cache_space_hook_create,
-        [HOOK_MKDIR]      cache_space_hook_mkdir,
-        [HOOK_RMDIR]      cache_space_hook_rmdir,
-        [HOOK_MKNOD]      cache_space_hook_create,
-        [HOOK_RENAME]     cache_space_hook_rename,
+static int lru_create (struct inode * inode, void * arg)
+{
+        struct hook_msg * msg = arg;
+        return cache_space_hook_create(inode, msg->dentry);
+}
+static int lru_lookup (struct inode * inode, void * arg)
+{
+        struct hook_msg * msg = arg;
+        return cache_space_hook_lookup(inode, msg->dentry);
+}
+static int lru_link (struct inode * inode, void * arg)
+{
+        struct hook_link_msg * msg = arg;
+        return cache_space_hook_link(inode, msg->dentry);
+}
+static int lru_unlink (struct inode * inode, void * arg)
+{
+        struct hook_unlink_msg * msg = arg;
+        return cache_space_hook_unlink(inode, msg->dentry);
+}
+static int lru_symlink (struct inode * inode, void * arg)
+{
+        struct hook_symlink_msg * msg = arg;
+        return cache_space_hook_create(inode, msg->dentry);
+}
+static int lru_mkdir (struct inode * inode, void * arg)
+{
+        struct hook_msg * msg = arg;
+        return cache_space_hook_mkdir(inode, msg->dentry);
+}
+static int lru_rmdir (struct inode * inode, void * arg)
+{
+        struct hook_unlink_msg * msg = arg;
+        return cache_space_hook_rmdir(inode, msg->dentry);
+}
+static int lru_rename (struct inode * inode, void * arg)
+{
+        struct hook_rename_msg * msg = arg;
+        return cache_space_hook_rename(inode, msg->dentry,
+                                       msg->new_dir, msg->new_dentry);
+}
+
+
+typedef int (*post_lru_op)(struct inode *inode, void * msg);
+static  post_lru_op smfs_lru_post[HOOK_MAX] = {
+        [HOOK_CREATE]     lru_create,
+        [HOOK_LOOKUP]     lru_lookup,
+        [HOOK_LINK]       lru_link,
+        [HOOK_UNLINK]     lru_unlink,
+        [HOOK_SYMLINK]    lru_symlink,
+        [HOOK_MKDIR]      lru_mkdir,
+        [HOOK_RMDIR]      lru_rmdir,
+        [HOOK_MKNOD]      lru_create,
+        [HOOK_RENAME]     lru_rename,
         [HOOK_SETATTR]    NULL,
         [HOOK_WRITE]      NULL,
         [HOOK_READDIR]    NULL,
 };
 
-int cache_space_post(int op, void *handle, struct inode *old_dir,
-                     struct dentry *old_dentry, struct inode *new_dir,
-                     struct dentry *new_dentry)
+static int smfs_lru_pre_op(int op, struct inode *inode, void * msg, int ret, 
+                           void *priv)
+{
+        int rc = 0;
+        ENTRY;
+        
+        /* FIXME have not used op */
+        check_cache_space();                                       
+                                                                               
+        RETURN(rc); 
+}
+
+static int smfs_lru_post_op(int op, struct inode *inode, void *msg, int ret,
+                            void *priv)
+{
+        int rc = 0;
+        
+        ENTRY;
+        if (ret)
+                RETURN(0);
+        
+        if (smfs_lru_post[op])
+                rc = smfs_lru_post[op](inode, msg);
+        
+        RETURN(rc);                                                             
+}
+
+/* Helpers */
+static int smfs_exit_lru(struct super_block *sb, void * arg, void * priv)
+{
+        ENTRY;
+
+        smfs_deregister_plugin(sb, SMFS_PLG_LRU);
+                
+        EXIT;
+        return 0;
+}
+
+static int smfs_trans_lru (struct super_block *sb, void *arg, void * priv)
+{
+        int size;
+        
+        ENTRY;
+        
+        size = 20;//LDISKFS_INDEX_EXTRA_TRANS_BLOCKS+LDISKFS_DATA_TRANS_BLOCKS;
+        
+        RETURN(size);
+}
+
+static int smfs_start_lru(struct super_block *sb, void *arg, void * priv)
 {
         int rc = 0;
+        struct smfs_super_info * smb = S2SMI(sb);
+        struct llog_ctxt *ctxt;
+        
         ENTRY;
+        
+        if (SMFS_IS(smb->plg_flags, SMFS_PLG_LRU))
+                RETURN(0);
 
-        LASSERT(op <= HOOK_MAX + 1);
+        /* first to initialize the cache lru catalog on local fs */
+        rc = llog_catalog_setup(&ctxt, CACHE_LRU_LOG, smb->smsi_exp,
+                                smb->smsi_ctxt, smb->sm_fsfilt,
+                                smb->smsi_logs_dir,
+                                smb->smsi_objects_dir);
+        if (rc) {
+                CERROR("failed to initialize cache lru list catalog %d\n", rc);
+                RETURN(rc);
+        }
+        cpq->cpq_sb = sb;
+        cpq->cpq_loghandle = ctxt->loc_handle;
 
-        if (cache_space_hook_ops[op]) 
-                rc = cache_space_hook_ops[op](handle, old_dir, old_dentry,
-                                              new_dir, new_dentry);
+        /* start cache purge daemon, only one daemon now */
+        init_waitqueue_head(&cpq->cpq_waitq);
+        init_completion(&cpq->cpq_comp);
+        cpq->cpq_flags = 0;
+
+        rc = kernel_thread(cache_purge_thread, NULL, CLONE_VM | CLONE_FILES);
+        if (rc < 0) {
+                CERROR("cannot start thread: %d\n", rc);
+                goto err_out;
+        }
+        wait_for_completion(&cpq->cpq_comp);
+
+        SMFS_SET(smb->plg_flags, SMFS_PLG_LRU);
+
+        RETURN(0);
+err_out:
+        llog_catalog_cleanup(ctxt);
+        OBD_FREE(ctxt, sizeof(*ctxt));
         RETURN(rc);
 }
+
+static int smfs_stop_lru(struct super_block *sb, void *arg, void * priv)
+{
+        struct smfs_super_info * smb = S2SMI(sb);
+        struct llog_ctxt *ctxt;
+        int rc;
+        ENTRY;
+        
+        if (!SMFS_IS(smb->plg_flags, SMFS_PLG_LRU))
+                RETURN(0);
+
+        SMFS_CLEAR(smb->plg_flags, SMFS_PLG_LRU);
+
+        init_completion(&cpq->cpq_comp);
+        cpq->cpq_flags = SVC_STOPPING;
+        wake_up(&cpq->cpq_waitq);
+        wait_for_completion(&cpq->cpq_comp);
+        
+        ctxt = cpq->cpq_loghandle->lgh_ctxt;
+        rc = llog_catalog_cleanup(ctxt);
+        OBD_FREE(ctxt, sizeof(*ctxt));
+        RETURN(0);        
+}
+
+typedef int (*lru_helper)(struct super_block * sb, void *msg, void *);
+static lru_helper smfs_lru_helpers[PLG_HELPER_MAX] = {
+        [PLG_EXIT]       smfs_exit_lru,
+        [PLG_START]      smfs_start_lru,
+        [PLG_STOP]       smfs_stop_lru,
+        [PLG_TRANS_SIZE] smfs_trans_lru,
+        [PLG_TEST_INODE] NULL,
+        [PLG_SET_INODE]  NULL,
+};
+
+static int smfs_lru_help_op(int code, struct super_block * sb,
+                            void * arg, void * priv)
+{
+        ENTRY;
+        if (smfs_lru_helpers[code])
+                smfs_lru_helpers[code](sb, arg, priv);
+        RETURN(0);
+}
+
+int smfs_init_lru(struct super_block *sb)
+{
+        struct smfs_plugin plg = {
+                .plg_type = SMFS_PLG_LRU,
+                .plg_pre_op = &smfs_lru_pre_op,
+                .plg_post_op = &smfs_lru_post_op,
+                .plg_helper = &smfs_lru_help_op,
+                .plg_private = NULL
+        };
+        int rc = 0;
+        
+        ENTRY;
+
+        rc = smfs_register_plugin(sb, &plg); 
+        
+        RETURN(rc);
+}
+
+
diff --git a/lustre/smfs/journal.c b/lustre/smfs/journal.c
deleted file mode 100644 (file)
index ab62e7a..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  lustre/smfs/journal.c
- *  Lustre filesystem abstraction routines
- *
- *  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.
- */
-#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/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"
-
-#define KML_BUF_REC_INIT(buffer, pbuf, len)     \
-do {                                            \
-        pbuf = buffer + sizeof(int);            \
-        len -= sizeof(int);                     \
-} while (0)
-        
-#define KML_BUF_REC_END(buffer, length, pbuf)   \
-do {                                            \
-        int len = length;                       \
-        memcpy(buffer, &len, sizeof(len));      \
-        length += sizeof(int);                  \
-        pbuf = buffer + length;                 \
-} while (0)
-
-void *smfs_trans_start(struct inode *inode, int op, void *desc_private)
-{
-        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;
-}
-
-void smfs_trans_commit(struct inode *inode, void *handle, int force_sync)
-{
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-
-        if (!handle)
-                return;
-
-        CDEBUG(D_INFO, "trans commit %p\n", fsfilt->fs_commit);
-
-        if (fsfilt->fs_commit)
-                fsfilt->fs_commit(inode->i_sb, inode, handle, force_sync);
-}
-
-/*smfs_path is gotten from intermezzo*/
-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--;
-        /* 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;
-        }
-        
-        while (end != buf_end) 
-                *name++ = *end++;
-        *name = '\0'; 
-        return retval;
-}
-
-static int smfs_log_path(struct super_block *sb, 
-                         struct dentry *dentry, 
-                         char   *buffer,
-                         int    buffer_len)
-{
-        struct dentry *root=sb->s_root;
-        char *p_name = buffer + sizeof(int);
-        char *name = NULL;
-        int namelen = 0;
-        if (dentry) {
-                name = smfs_path(dentry, root, p_name, buffer_len - sizeof(int));
-                namelen = cpu_to_le32(strlen(p_name));
-                memcpy(buffer, &namelen, sizeof(int));        
-        }
-        namelen += sizeof(int);
-        RETURN(namelen);
-}
-
-static inline int log_it(char *buffer, void *data, int length)
-{
-        memcpy(buffer, &length, sizeof(int));
-        memcpy(buffer + sizeof(int), data, length);
-        return (sizeof(int) + length);                 
-}
-
-static int smfs_pack_rec (char *buffer, struct dentry *dentry, 
-                          struct inode *dir, void *data1, 
-                          void *data2, int op)
-{ 
-        smfs_pack_rec_func pack_func;        
-        int rc;
-
-        pack_func = smfs_get_rec_pack_type(dir->i_sb);
-        if (!pack_func) {
-                return (0);
-        }
-        rc = pack_func(buffer, dentry, dir, data1, data2, op);
-        return rc;
-}
-
-int smfs_post_rec_create(struct inode *dir, struct dentry *dentry,
-                         void   *data1, void   *data2)
-{
-        struct smfs_super_info *sinfo;
-        char   *buffer = NULL, *pbuf;
-        int rc = 0, length = 0, buf_len = 0;
-        
-        sinfo = S2SMI(dentry->d_inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-        
-        OBD_ALLOC(buffer, PAGE_SIZE);
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);        
-
-        buf_len = PAGE_SIZE;
-        KML_BUF_REC_INIT(buffer, pbuf, buf_len);
-        rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len);
-        if (rc < 0)
-                GOTO(exit, rc);
-        length = rc;
-        KML_BUF_REC_END(buffer, length, pbuf);   
-       
-        rc = smfs_pack_rec(pbuf, dentry, dir, 
-                           data1, data2, REINT_CREATE);
-        if (rc <= 0)
-                GOTO(exit, rc);
-        else
-                length += rc;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); 
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE);        
-        
-        RETURN(rc);
-}
-
-static int smfs_post_rec_link(struct inode *dir, 
-                              struct dentry *dentry,
-                               void   *data1,
-                              void   *data2)
-{
-        struct smfs_super_info *sinfo;
-        struct dentry *old_dentry = (struct dentry *)data1;
-        char *buffer = NULL, *pbuf = NULL;
-        int rc = 0, length = 0, buf_len = 0;
-        
-        sinfo = S2SMI(dir->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-        OBD_ALLOC(buffer, PAGE_SIZE);
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-        
-        buf_len = PAGE_SIZE;
-        KML_BUF_REC_INIT(buffer, pbuf, buf_len);
-        rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len);
-        if (rc < 0)
-                GOTO(exit, rc);
-        
-        length = rc;
-        KML_BUF_REC_END(buffer, length, pbuf);  
-        
-        rc = smfs_pack_rec(pbuf, dentry, dir, dentry->d_parent, 
-                           old_dentry->d_parent, REINT_LINK);
-        if (rc <= 0)
-                GOTO(exit, rc);
-        else
-                length += rc;
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); 
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE);        
-        
-        RETURN(rc);
-}
-
-static int smfs_post_rec_unlink(struct inode *dir, struct dentry *dentry,
-                                void *data1, void *data2)
-{
-        struct smfs_super_info *sinfo;
-        int mode = *((int*)data1);
-        char   *buffer = NULL, *pbuf = NULL;
-        int  length = 0, rc = 0, buf_len = 0;
-         
-        sinfo = S2SMI(dentry->d_inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-        
-        OBD_ALLOC(buffer, PAGE_SIZE);
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);        
-      
-        buf_len = PAGE_SIZE;
-        KML_BUF_REC_INIT(buffer, pbuf, buf_len);        
-        rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len);
-        if (rc < 0)
-                GOTO(exit, rc);
-
-        length = rc;
-        KML_BUF_REC_END(buffer, length, pbuf);
-        rc = smfs_pack_rec(pbuf, dentry, dir, 
-                           &mode, NULL, REINT_UNLINK);
-        if (rc <= 0)
-                GOTO(exit, rc);
-        else
-                length += rc;         
-        
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); 
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE);        
-        
-        RETURN(rc);
-}
-
-static int smfs_post_rec_rename(struct inode *dir, 
-                                 struct dentry *dentry,
-                                 void   *data1,
-                                void   *data2)
-{
-        struct smfs_super_info *sinfo;
-        struct inode *new_dir = (struct inode *)data1;
-        struct dentry *new_dentry = (struct dentry *)data2;
-        char *buffer = NULL, *pbuf = NULL;
-        int rc = 0, length = 0, buf_len = 0;
-        
-        sinfo = S2SMI(dir->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(buffer, PAGE_SIZE);
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);
-        
-        buf_len = PAGE_SIZE;
-        KML_BUF_REC_INIT(buffer, pbuf, buf_len);        
-        rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len);
-        if (rc < 0)
-                GOTO(exit, rc);
-
-        pbuf += rc; 
-        length += rc;
-        buf_len -= rc;         
-        /*record new_dentry path*/        
-        rc = smfs_log_path(dir->i_sb, new_dentry, pbuf, buf_len);
-        if (rc < 0)
-                GOTO(exit, rc);
-
-        length += rc;
-        KML_BUF_REC_END(buffer, length, pbuf);
-               
-        rc = smfs_pack_rec(pbuf, dentry, dir, 
-                           new_dir, new_dentry, REINT_RENAME);
-        if (rc <= 0) 
-                GOTO(exit, rc);
-        length += rc;
-        
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); 
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE);
-        RETURN(rc);
-}
-
-static int smfs_insert_extents_ea(struct inode *inode, size_t from, loff_t num)
-{
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-        int rc = 0;
-        
-        if (SMFS_INODE_OVER_WRITE(inode))
-                RETURN(rc);
-        
-        rc = fsfilt->fs_insert_extents_ea(inode, OFF2BLKS(from, inode), 
-                                          SIZE2BLKS(num, inode));        
-        RETURN(rc);
-}
-
-static int smfs_remove_extents_ea(struct inode *inode, size_t from, loff_t num)
-{
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-        int rc = 0;
-        
-        rc = fsfilt->fs_remove_extents_ea(inode, OFF2BLKS(from, inode), 
-                                          SIZE2BLKS(num, inode));        
-        
-        RETURN(rc);
-}
-
-static int smfs_remove_all_extents_ea(struct inode *inode)
-{
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-        int rc = 0;
-        
-        rc = fsfilt->fs_remove_extents_ea(inode, 0, 0xffffffff);        
-        RETURN(rc);
-}
-static int  smfs_init_extents_ea(struct inode *inode)
-{
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-        int rc = 0;
-        
-        rc = fsfilt->fs_init_extents_ea(inode);        
-        
-        RETURN(rc);
-}
-static int smfs_set_dirty_flags(struct inode *inode, int flags)
-{
-        struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
-        void   *handle;
-        int    rc = 0;
-
-        if (SMFS_INODE_OVER_WRITE(inode))
-                RETURN(rc);
-        /*FIXME later, the blocks needed in journal here will be recalculated*/
-         handle = smfs_trans_start(inode, FSFILT_OP_SETATTR, NULL);
-        if (IS_ERR(handle)) {
-                CERROR("smfs_set_dirty_flag:no space for transaction\n");
-                RETURN(-ENOSPC);
-        }
-        if ((!SMFS_INODE_DIRTY_WRITE(inode) && (!SMFS_INODE_OVER_WRITE(inode))) || 
-             ((flags == SMFS_OVER_WRITE) && (SMFS_INODE_DIRTY_WRITE(inode)))) {        
-                rc = fsfilt->fs_set_xattr(inode, handle, REINT_EXTENTS_FLAGS,
-                                            &flags, sizeof(int));
-                if (rc)
-                        GOTO(out, rc);
-        }
-        if (flags == SMFS_OVER_WRITE)
-                SMFS_SET_INODE_OVER_WRITE(inode);
-        else
-                SMFS_SET_INODE_DIRTY_WRITE(inode);
-out:
-        smfs_trans_commit(inode, handle, 0);
-        RETURN(rc);
-}
-
-int smfs_post_rec_setattr(struct inode *inode, struct dentry *dentry,
-                          void  *data1, void  *data2)
-{        
-        struct smfs_super_info *sinfo;
-        struct iattr *attr = (struct iattr *)data1;
-        char   *buffer = NULL, *pbuf;
-        int rc = 0, length = 0, buf_len = 0;
-
-        sinfo = S2SMI(inode->i_sb);
-        if (!sinfo)
-                RETURN(-EINVAL);
-        
-        OBD_ALLOC(buffer, PAGE_SIZE);
-        if (!buffer)
-                GOTO(exit, rc = -ENOMEM);        
-
-        buf_len = PAGE_SIZE;
-        KML_BUF_REC_INIT(buffer, pbuf, buf_len);        
-        rc = smfs_log_path(inode->i_sb, dentry, pbuf, buf_len);
-        if (rc < 0)
-                GOTO(exit, rc);
-        
-        length = rc;
-        KML_BUF_REC_END(buffer, length, pbuf);
-        
-        rc = smfs_pack_rec(pbuf, dentry, inode, 
-                           data1, data2, REINT_SETATTR);
-        if (rc <= 0) 
-                GOTO(exit, rc);
-        else
-                length += rc;
-
-        rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); 
-        if (!rc) {
-                if (attr && attr->ia_valid & ATTR_SIZE) {
-                        smfs_remove_extents_ea(inode, attr->ia_size,
-                                               0xffffffff);                                
-                        if (attr->ia_size == 0)
-                                smfs_set_dirty_flags(inode, SMFS_OVER_WRITE);
-                        else
-                                smfs_set_dirty_flags(inode, SMFS_DIRTY_WRITE);
-                }
-        }
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE);        
-        RETURN(rc);
-}
-static int all_blocks_present_ea(struct inode *inode)
-{
-        int rc = 0;
-        
-        RETURN(rc);        
-}
-int smfs_post_rec_write(struct inode *dir, struct dentry *dentry,
-                        void   *data1, void *data2)
-{
-        struct smfs_super_info *sinfo;
-        char   *buffer = NULL, *pbuf;
-        int rc = 0, length = 0, buf_len = 0;
-        
-        if (!SMFS_INODE_OVER_WRITE(dentry->d_inode) && 
-            !SMFS_INODE_DIRTY_WRITE(dentry->d_inode)) {
-                sinfo = S2SMI(dentry->d_inode->i_sb);
-                if (!sinfo)
-                        RETURN(-EINVAL);
-                
-                OBD_ALLOC(buffer, PAGE_SIZE);
-                if (!buffer)
-                        GOTO(exit, rc = -ENOMEM);        
-                
-                buf_len = PAGE_SIZE;
-                KML_BUF_REC_INIT(buffer, pbuf, buf_len);        
-                rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len);
-                
-                if (rc < 0)
-                        GOTO(exit, rc);
-                pbuf += rc;
-                memcpy(buffer, &rc, sizeof(int));        
-                length = rc + sizeof(int);
-                        
-                rc = smfs_pack_rec(pbuf, dentry, dir, 
-                                   data1, data2, REINT_WRITE);
-                if (rc <= 0) 
-                        GOTO(exit, rc);
-                else
-                        length += rc;
-                rc = smfs_llog_add_rec(sinfo, (void*)buffer, length);
-                if (rc)
-                        GOTO(exit, rc);
-                rc = smfs_init_extents_ea(dentry->d_inode);
-                if (rc)
-                        GOTO(exit, rc);
-        } 
-        if (dentry->d_inode->i_size == 0) {
-                smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE);        
-        } else {
-                /*insert extent EA*/
-                loff_t off = *((loff_t*)data1);        
-                size_t count = *((size_t*)data2);
-                
-                rc = smfs_insert_extents_ea(dentry->d_inode, off, count);        
-                if (rc < 0)  
-                        GOTO(exit, rc);        
-                if (all_blocks_present_ea(dentry->d_inode)){
-                        smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE);        
-                        smfs_remove_all_extents_ea(dentry->d_inode);
-                } else {
-                        smfs_set_dirty_flags(dentry->d_inode, SMFS_DIRTY_WRITE);        
-                }
-        }
-exit:
-        if (buffer)
-                OBD_FREE(buffer, PAGE_SIZE);
-        RETURN(rc);
-}
-
-typedef int (*post_kml_rec)(struct inode *dir, struct dentry *dentry,
-                           void *data1, void *data2);
-
-static post_kml_rec smfs_kml_post[HOOK_MAX + 1] = {
-        [HOOK_CREATE]  smfs_post_rec_create,
-        [HOOK_LOOKUP]  NULL,
-        [HOOK_LINK]    smfs_post_rec_link,
-        [HOOK_UNLINK]  smfs_post_rec_unlink,
-        [HOOK_SYMLINK] smfs_post_rec_create,
-        [HOOK_MKDIR]   smfs_post_rec_create,
-        [HOOK_RMDIR]   smfs_post_rec_unlink,
-        [HOOK_MKNOD]   smfs_post_rec_create,
-        [HOOK_RENAME]  smfs_post_rec_rename,
-        [HOOK_SETATTR] smfs_post_rec_setattr,
-        [HOOK_WRITE]   smfs_post_rec_write,
-};
-
-int smfs_post_kml_rec(struct inode *dir, struct dentry *dst_dentry,
-                      void *data1, void *data2, int op)
-{
-        if (smfs_kml_post[op]) {
-                return smfs_kml_post[op](dir, dst_dentry, data1, data2);
-        }
-        return 0;
-}
index 2692963..338b995 100644 (file)
@@ -53,72 +53,66 @@ do {                                            \
         pbuf = buffer + length;                 \
 } while (0)
 
-static smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb)
+
+static int smfs_llog_process_rec_cb(struct llog_handle *handle,
+                                    struct llog_rec_hdr *rec, void *data)
 {
-        int idx = 0;
-        struct smfs_super_info *smsi = S2SMI(sb);
+        char   *rec_buf ;
+        struct smfs_proc_args *args = (struct smfs_proc_args *)data;
+        struct lvfs_run_ctxt saved;
+        int    rc = 0;
 
-        idx = GET_REC_PACK_TYPE_INDEX(smsi->smsi_flags);
-        return smsi->smsi_pack_rec[idx];
-}
+        if (!(le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)) {
+                CERROR("log is not plain\n");
+                RETURN(-EINVAL);
+        }
 
-static int smfs_post_kml_rec(struct inode *dir, void *de, void *data1, 
-                             void *data2, int op);
+        if (le32_to_cpu(rec->lrh_type) == LLOG_GEN_REC) {
+                struct llog_cookie cookie;
 
-static int smfs_rec_post_hook(struct inode *inode, void *dentry,
-                              void *data1, void *data2, int op, void *handle)
-{
-        int rc = 0;
-        ENTRY;
+                cookie.lgc_lgl = handle->lgh_id;
+                cookie.lgc_index = le32_to_cpu(rec->lrh_index);
 
-        if (smfs_do_rec(inode))                                  
-                rc = smfs_post_kml_rec(inode, dentry, data1, data2, op);  
-        
-        RETURN(rc);
-}
+                llog_cancel(handle->lgh_ctxt, 1, &cookie, 0, NULL);
+                RETURN(LLOG_PROC_BREAK);
+        }
 
-#define KML_HOOK "kml_hook"
+        if (le32_to_cpu(rec->lrh_type) != SMFS_UPDATE_REC)
+                RETURN(-EINVAL);
 
-int smfs_rec_init(struct super_block *sb)
-{
-        int rc = 0;
-        struct smfs_super_info *smfs_info = S2SMI(sb);
-        struct smfs_hook_ops   *rec_hops = NULL;
-        ENTRY;
+        rec_buf = (char*) (rec + 1);
 
-        SMFS_SET_REC(smfs_info);
+        if (!S2SMI(args->sr_sb)->smsi_ctxt)
+                GOTO(exit, rc = -ENODEV);
 
-        rc = ost_rec_pack_init(smfs_info);
-        if (rc)
-                return rc;
-        
-        rc = mds_rec_pack_init(smfs_info);
-        if (rc)
-                return rc;
-
-        rec_hops = smfs_alloc_hook_ops(KML_HOOK, NULL, smfs_rec_post_hook);
-        if (!rec_hops) {
-                RETURN(-ENOMEM);
+        push_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
+#if 0
+        /*FIXME later should first unpack the rec,
+         * then call lvfs_reint or lvfs_undo
+         * kml rec format has changed lvfs_reint lvfs_undo should
+         * be rewrite FIXME later*/
+        if (SMFS_DO_REINT_REC(args->sr_flags))
+                rc = lvfs_reint(args->sr_sb, rec_buf);
+        else
+                rc = lvfs_undo(args->sr_sb, rec_buf);
+#endif
+        if (!rc && !SMFS_DO_REC_ALL(args->sr_flags)) {
+                args->sr_count --;
+                if (args->sr_count == 0)
+                        rc = LLOG_PROC_BREAK;
         }
-        rc = smfs_register_hook_ops(smfs_info, rec_hops);
-        if (rc && rec_hops) {
-                smfs_unregister_hook_ops(smfs_info, rec_hops->smh_name);
-                smfs_free_hook_ops(rec_hops);
-        } 
+        pop_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
+exit:
         RETURN(rc);
 }
 
-int smfs_rec_cleanup(struct smfs_super_info *smfs_info)
+static smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb)
 {
-        struct smfs_hook_ops *rec_hops; 
-        int rc = 0;
-        ENTRY;
+        int idx = 0;
+        struct smfs_super_info *smsi = S2SMI(sb);
 
-        rec_hops = smfs_unregister_hook_ops(smfs_info, KML_HOOK);
-        smfs_free_hook_ops(rec_hops);
-        SMFS_CLEAN_REC(smfs_info);
-        
-        RETURN(rc);
+        idx = GET_REC_PACK_TYPE_INDEX(smsi->smsi_flags);
+        return smsi->smsi_pack_rec[idx];
 }
 
 static inline void
@@ -175,93 +169,6 @@ int smfs_rec_unpack(struct smfs_proc_args *args, char *record,
 }
 EXPORT_SYMBOL(smfs_rec_unpack);
 
-int smfs_start_rec(struct super_block *sb, struct vfsmount *mnt)
-{
-        struct dentry *dentry;
-        struct lvfs_run_ctxt saved;
-        int rc = 0;
-        ENTRY;
-
-        if (SMFS_INIT_REC(S2SMI(sb)) ||
-            (!SMFS_DO_REC(S2SMI(sb)) && !SMFS_CACHE_HOOK(S2SMI(sb))))
-                RETURN(rc);
-        
-        rc = smfs_llog_setup(sb, mnt);
-        if (rc)
-                RETURN(rc); 
-        push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
-        dentry = simple_mkdir(current->fs->pwd, "DELETE", 0777, 1);
-        if (IS_ERR(dentry)) {
-                rc = PTR_ERR(dentry);
-                CERROR("cannot create DELETE directory: rc = %d\n", rc);
-                GOTO(err_exit, rc = -EINVAL);
-        }
-        S2SMI(sb)->smsi_delete_dir = dentry;
-
-        if (!rc)
-                SMFS_SET_INIT_REC(S2SMI(sb));
-exit:
-        pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
-        RETURN(rc);
-err_exit:
-        if (S2SMI(sb)->smsi_ctxt)
-                OBD_FREE(S2SMI(sb)->smsi_ctxt, sizeof(struct lvfs_run_ctxt));
-        goto exit;
-}
-EXPORT_SYMBOL(smfs_start_rec);
-
-int smfs_post_setup(struct super_block *sb, struct vfsmount *mnt)
-{
-        struct lvfs_run_ctxt *current_ctxt = NULL;
-        struct smfs_super_info *smb = S2SMI(sb);
-        ENTRY;
-        OBD_ALLOC(current_ctxt, sizeof(*current_ctxt));
-        if (!current_ctxt)
-                RETURN(-ENOMEM);
-        OBD_SET_CTXT_MAGIC(current_ctxt);
-        
-        current_ctxt->pwdmnt = mnt;
-        current_ctxt->pwd = mnt->mnt_root;
-        current_ctxt->fs = get_ds();
-        smb->smsi_ctxt = current_ctxt;
-
-        RETURN(0);
-}
-EXPORT_SYMBOL(smfs_post_setup);
-
-int smfs_post_cleanup(struct super_block *sb)
-{
-        struct smfs_super_info *smb = S2SMI(sb);
-        ENTRY;
-       
-        if (smb->smsi_ctxt)
-                OBD_FREE(S2SMI(sb)->smsi_ctxt, sizeof(struct lvfs_run_ctxt));
-        RETURN(0);
-}
-EXPORT_SYMBOL(smfs_post_cleanup);
-
-int smfs_stop_rec(struct super_block *sb)
-{
-        int rc = 0;
-        ENTRY;
-
-        if (!SMFS_INIT_REC(S2SMI(sb)) ||
-            (!SMFS_DO_REC(S2SMI(sb)) && !SMFS_CACHE_HOOK(S2SMI(sb))))
-                RETURN(rc);
-
-        rc = smfs_llog_cleanup(sb);
-
-        SMFS_CLEAN_INIT_REC(S2SMI(sb));
-
-        if (S2SMI(sb)->smsi_delete_dir) {
-                l_dput(S2SMI(sb)->smsi_delete_dir);
-                S2SMI(sb)->smsi_delete_dir = NULL;
-        }
-        RETURN(rc);
-}
-EXPORT_SYMBOL(smfs_stop_rec);
-
 int smfs_write_extents(struct inode *dir, struct dentry *dentry,
                        unsigned long from, unsigned long num)
 {
@@ -276,35 +183,29 @@ int smfs_rec_setattr(struct inode *dir, struct dentry *dentry,
 }
 EXPORT_SYMBOL(smfs_rec_setattr);
 
-int smfs_rec_md(struct inode *inode, void *lmm, int lmm_size,
-                enum ea_type type)
+int smfs_rec_md(struct inode *inode, void *lmm, int lmm_size)
 {
         char *set_lmm = NULL;
-        int rc = 0;
+        int  rc = 0;
         ENTRY;
 
         if (!SMFS_DO_REC(S2SMI(inode->i_sb)))
                 RETURN(0);
 
         if (lmm) {
-                int size = lmm_size + sizeof(lmm_size) +
-                        sizeof(type);
-
-                OBD_ALLOC(set_lmm, size);
+                OBD_ALLOC(set_lmm, lmm_size + sizeof(lmm_size));
                 if (!set_lmm)
                         RETURN(-ENOMEM);
-
                 memcpy(set_lmm, &lmm_size, sizeof(lmm_size));
-                memcpy(set_lmm + sizeof(lmm_size), &type, sizeof(type));
-                memcpy(set_lmm + sizeof(lmm_size) + sizeof(type), lmm, lmm_size);
-
+                memcpy(set_lmm + sizeof(lmm_size), lmm, lmm_size);
                 rc = smfs_post_rec_setattr(inode, NULL, NULL, set_lmm);
                 if (rc) {
-                        CERROR("Error: Record md for inode %lu rc = %d\n",
+                        CERROR("Error: Record md for inode %lu rc=%d\n",
                                 inode->i_ino, rc);
                 }
-                OBD_FREE(set_lmm, size);
         }
+        if (set_lmm)
+                OBD_FREE(set_lmm, lmm_size + sizeof(lmm_size));
         RETURN(rc);
 }
 EXPORT_SYMBOL(smfs_rec_md);
@@ -334,7 +235,7 @@ int smfs_process_rec(struct super_block *sb,
         args.sr_count = count;
         args.sr_data = dir;
         args.sr_flags = flags ;
-        ctxt = S2SMI(sb)->smsi_rec_log;
+        ctxt = S2SMI(sb)->smsi_kml_log;
         loghandle = ctxt->loc_handle;
 
         if (count == 0) {
@@ -696,12 +597,12 @@ out:
 }
 
 int smfs_post_rec_setattr(struct inode *inode, struct dentry *dentry, 
-                          void *data1, void *data2)
+                          void  *data1, void  *data2)
 {        
+        struct smfs_super_info *sinfo;
         struct iattr *attr = (struct iattr *)data1;
+        char   *buffer = NULL, *pbuf;
         int rc = 0, length = 0, buf_len = 0;
-        struct smfs_super_info *sinfo;
-        char *buffer = NULL, *pbuf;
         ENTRY;
 
         sinfo = S2SMI(inode->i_sb);
@@ -817,29 +718,205 @@ exit:
         RETURN(rc);
 }
 
-typedef int (*post_kml_rec)(struct inode *dir, struct dentry *dentry,
-                           void *data1, void *data2);
+/* new plugin API */
+struct kml_priv {
+        struct dentry * kml_llog_dir;
+};
+
+static int kml_create(struct inode * inode, void *arg) 
+{
+        struct hook_msg * msg = arg;
+        return smfs_post_rec_create(inode, msg->dentry, NULL, NULL);
+}
+
+static int kml_link(struct inode * inode, void *arg) 
+{
+        struct hook_link_msg * msg = arg;
+        return smfs_post_rec_link(inode, msg->dentry, msg->new_dentry, NULL);
+}
+
+static int kml_unlink(struct inode * inode, void *arg) 
+{
+        struct hook_unlink_msg * msg = arg;
+        return smfs_post_rec_unlink(inode, msg->dentry, &msg->mode, NULL);
+}
+
+static int kml_symlink(struct inode * inode, void *arg) 
+{
+        struct hook_symlink_msg * msg = arg;
+        return smfs_post_rec_create(inode, msg->dentry, &msg->tgt_len,
+                                    msg->symname);
+}
+
+static int kml_rename(struct inode * inode, void *arg) 
+{
+        struct hook_rename_msg * msg = arg;
+        return smfs_post_rec_rename(inode, msg->dentry, msg->new_dir,
+                                    msg->new_dentry);
+}
+
+static int kml_setattr(struct inode * inode, void *arg) 
+{
+        struct hook_setattr_msg * msg = arg;
+        return smfs_post_rec_setattr(inode, msg->dentry, msg->attr, NULL);
+}
+
+static int kml_write(struct inode * inode, void *arg) 
+{
+        struct hook_write_msg * msg = arg;
+        return smfs_post_rec_write(inode, msg->dentry, &msg->count, &msg->pos);
+}
 
-static post_kml_rec smfs_kml_post[HOOK_MAX + 1] = {
-        [HOOK_CREATE]  smfs_post_rec_create,
+typedef int (*post_kml_op)(struct inode * inode, void *msg);
+static post_kml_op smfs_kml_post[HOOK_MAX] = {
+        [HOOK_CREATE]  kml_create,
         [HOOK_LOOKUP]  NULL,
-        [HOOK_LINK]    smfs_post_rec_link,
-        [HOOK_UNLINK]  smfs_post_rec_unlink,
-        [HOOK_SYMLINK] smfs_post_rec_create,
-        [HOOK_MKDIR]   smfs_post_rec_create,
-        [HOOK_RMDIR]   smfs_post_rec_unlink,
-        [HOOK_MKNOD]   smfs_post_rec_create,
-        [HOOK_RENAME]  smfs_post_rec_rename,
-        [HOOK_SETATTR] smfs_post_rec_setattr,
-        [HOOK_WRITE]   smfs_post_rec_write,
+        [HOOK_LINK]    kml_link,
+        [HOOK_UNLINK]  kml_unlink,
+        [HOOK_SYMLINK] kml_symlink,
+        [HOOK_MKDIR]   kml_create,
+        [HOOK_RMDIR]   kml_unlink,
+        [HOOK_MKNOD]   kml_create,
+        [HOOK_RENAME]  kml_rename,
+        [HOOK_SETATTR] kml_setattr,
+        [HOOK_WRITE]   kml_write,
         [HOOK_READDIR] NULL,
 };
-static int smfs_post_kml_rec(struct inode *dir, void *de, void *data1, 
-                             void *data2, int op)
+
+static int smfs_kml_post_op(int code, struct inode * inode,
+                            void * msg, int ret, void * priv)
 {
-        if (smfs_kml_post[op]) {
-                struct dentry *dentry = (struct dentry *)de;
-                return smfs_kml_post[op](dir, dentry, data1, data2);
+        int rc = 0;
+        
+        ENTRY;
+        CDEBUG(D_INODE,"KML: inode %lu, code: %u\n", inode->i_ino, code);
+        //KML don't handle failed ops
+        if (ret)
+                RETURN(0);
+        
+        if (smfs_kml_post[code]) {
+                rc = smfs_kml_post[code](inode, msg);
         }
+                
+        RETURN(rc);
+}
+
+/* Helpers */
+static int smfs_exit_kml(struct super_block *sb, void * arg, struct kml_priv * priv)
+{
+        ENTRY;
+
+        smfs_deregister_plugin(sb, SMFS_PLG_KML);
+                
+        EXIT;
         return 0;
 }
+
+static int smfs_trans_kml (struct super_block *sb, void *arg,
+                           struct kml_priv * priv)
+{
+        int size;
+        
+        ENTRY;
+        
+        size = 20;//LDISKFS_INDEX_EXTRA_TRANS_BLOCKS+LDISKFS_DATA_TRANS_BLOCKS;
+        
+        RETURN(size);
+}
+
+static int smfs_start_kml(struct super_block *sb, void *arg,
+                          struct kml_priv * kml_p)
+{
+        int rc = 0;
+        struct smfs_super_info * smb = S2SMI(sb);
+        struct llog_ctxt **ctxt = &smb->smsi_kml_log;
+
+        ENTRY;
+        //is plugin already activated
+        if (SMFS_IS(smb->plg_flags, SMFS_PLG_KML))
+                RETURN(0);
+        
+        //this will do OBD_ALLOC() for ctxt
+        rc = llog_catalog_setup(ctxt, KML_LOG_NAME, smb->smsi_exp,
+                                smb->smsi_ctxt, smb->sm_fsfilt,
+                                smb->smsi_logs_dir,
+                                smb->smsi_objects_dir);
+        
+        if (rc) {
+                CERROR("Failed to initialize kml log list catalog %d\n", rc);
+                RETURN(rc);
+        }
+        
+        (*ctxt)->llog_proc_cb = smfs_llog_process_rec_cb;
+
+        SMFS_SET(smb->plg_flags, SMFS_PLG_KML);
+
+        RETURN(0);
+}
+
+int smfs_stop_kml(struct super_block *sb, void *arg,
+                  struct kml_priv * kml_p)
+{
+        struct smfs_super_info * smb = S2SMI(sb);
+        struct llog_ctxt *ctxt = smb->smsi_kml_log;
+        ENTRY;
+
+        if (!SMFS_IS(smb->plg_flags, SMFS_PLG_KML))
+                RETURN(0);
+
+        SMFS_CLEAR(smb->plg_flags, SMFS_PLG_KML);
+
+        llog_catalog_cleanup(ctxt);
+        OBD_FREE(ctxt, sizeof(*ctxt));
+        
+        RETURN(0);
+}
+
+typedef int (*kml_helper)(struct super_block * sb, void *msg, struct kml_priv *);
+static kml_helper smfs_kml_helpers[PLG_HELPER_MAX] = {
+        [PLG_EXIT]       smfs_exit_kml,
+        [PLG_START]      smfs_start_kml,
+        [PLG_STOP]       smfs_stop_kml,
+        [PLG_TRANS_SIZE] smfs_trans_kml,
+        [PLG_TEST_INODE] NULL,
+        [PLG_SET_INODE]  NULL,
+};
+
+static int smfs_kml_help_op(int code, struct super_block * sb,
+                            void * arg, void * priv)
+{
+        int rc = 0;
+        ENTRY;
+        if (smfs_kml_helpers[code])
+                rc = smfs_kml_helpers[code](sb, arg, (struct kml_priv *) priv);
+        RETURN(rc);
+}
+
+int smfs_init_kml(struct super_block *sb)
+{
+        int rc = 0;
+        struct smfs_super_info *smb = S2SMI(sb);
+        struct smfs_plugin plg = {
+                .plg_type = SMFS_PLG_KML,
+                .plg_pre_op = NULL,
+                .plg_post_op = &smfs_kml_post_op,
+                .plg_helper = &smfs_kml_help_op,
+                .plg_private = NULL,
+        };
+        
+        ENTRY;
+
+        rc = ost_rec_pack_init(smb);
+        if (rc)
+                return rc;
+        
+        rc = mds_rec_pack_init(smb);
+        if (rc)
+                return rc;
+
+        rc = smfs_register_plugin(sb, &plg);
+        
+        RETURN(rc);
+}
+
+
index 2855883..cf89a4e 100644 (file)
 #include <linux/lustre_smfs.h>
 #include "smfs_internal.h"
 
+int smfs_options(char *data, char **devstr, char **namestr, 
+                 char *ret, int *flags)  
+{
+        char * temp;
+        char * pos = NULL, *next = NULL;
+                
+        ENTRY;
+        
+        LASSERT(flags);
+        //allocate temporary buffer
+        OBD_ALLOC(temp, strlen(data) + 1);
+        if (!temp) {
+                CERROR("Can not allocate memory for options\n");
+                RETURN(-ENOMEM);
+        }
+        
+        memcpy(temp, data, strlen(data));
+        pos = temp;
+        
+        while (pos) {
+                next = strchr(pos, ',');
+                if (next) {
+                        *next = '\0';
+                        next++;
+                }
+                
+                //now pos points to one-options string
+                if (!strncmp(pos, "dev=", 4)) {
+                        if (devstr != NULL)
+                                *devstr = pos + 4;
+                } else if (!strncmp(pos, "type=", 5)) {
+                        if (namestr != NULL)
+                                *namestr = pos + 5;
+                } else if (!strcmp(pos, "kml")) {
+                        SMFS_SET(*flags, SMFS_PLG_KML);
+                } else if (!strcmp(pos, "cache")) {
+                        SMFS_SET(*flags, SMFS_PLG_LRU);
+                } else if (!strcmp(pos, "snap")) {
+                        SMFS_SET(*flags, SMFS_PLG_COW);
+                } else {
+                        /* So it is wrong or backfs option,
+                         * let's save it
+                         */
+                        if (strlen(ret))
+                                strcat(ret, ",");
+                        
+                        strcat(ret, pos);
+                }
+                
+                pos = next;
+        }
 
-struct list_head smfs_plg_list;
+        //save dev & type for further use
+        *devstr = strcpy(ret + strlen(ret) + 1, *devstr);//, strlen(*devstr));
+        *namestr = strcpy(*devstr + strlen(*devstr) + 1, *namestr);//, strlen(*namestr));
+        
+        OBD_FREE(temp, strlen(data) + 1);
+        
+        RETURN(0);
+}
 
 static struct smfs_super_info *smfs_init_smb(struct super_block *sb)
 {
@@ -61,6 +119,15 @@ static struct smfs_super_info *smfs_init_smb(struct super_block *sb)
         RETURN(smb);        
 }
 
+static void smfs_cleanup_smb(struct smfs_super_info *smb)
+{
+        ENTRY;
+
+        if (smb) 
+                OBD_FREE(smb, sizeof(*smb));
+        EXIT;
+}
+
 static int smfs_init_fsfilt_ops(struct smfs_super_info *smb)
 {
         ENTRY;
@@ -68,7 +135,7 @@ static int smfs_init_fsfilt_ops(struct smfs_super_info *smb)
                 smb->sm_cache_fsfilt =
                         fsfilt_get_ops(smb->smsi_cache_ftype);
                 if (!smb->sm_cache_fsfilt) {
-                        CERROR("Can not get %s fsfilt ops needed by kml\n",
+                        CERROR("Can not get %s fsfilt ops needed by smfs\n",
                                smb->smsi_cache_ftype);
                         RETURN(-EINVAL);
                 }
@@ -77,7 +144,7 @@ static int smfs_init_fsfilt_ops(struct smfs_super_info *smb)
                 smb->sm_fsfilt =
                         fsfilt_get_ops(smb->smsi_ftype);
                 if (!smb->sm_fsfilt) {
-                        CERROR("Can not get %s fsfilt ops needed by kml\n",
+                        CERROR("Can not get %s fsfilt ops needed by smfs\n",
                                smb->smsi_ftype);
                         RETURN(-EINVAL);
                 }
@@ -93,6 +160,55 @@ void smfs_cleanup_fsfilt_ops(struct smfs_super_info *smb)
                 fsfilt_put_ops(smb->sm_fsfilt);
 }
 
+int smfs_post_setup(struct super_block *sb, struct vfsmount *mnt)
+{
+        struct lvfs_run_ctxt saved, *current_ctxt = NULL;
+        struct smfs_super_info *smb = S2SMI(sb);
+        int rc = 0;
+        
+        ENTRY;
+        OBD_ALLOC(current_ctxt, sizeof(*current_ctxt));
+        if (!current_ctxt)
+                RETURN(-ENOMEM);
+        
+        OBD_SET_CTXT_MAGIC(current_ctxt);
+        
+        current_ctxt->pwdmnt = mnt;
+        current_ctxt->pwd = mnt->mnt_root;
+        current_ctxt->fs = get_ds();
+        smb->smsi_ctxt = current_ctxt;
+        
+        push_ctxt(&saved, smb->smsi_ctxt, NULL);
+
+        rc = smfs_llog_setup(sb, mnt);
+        if (!rc) {
+                rc = SMFS_PLG_HELP(sb, PLG_START, NULL);
+        }
+
+        pop_ctxt(&saved, smb->smsi_ctxt, NULL);
+
+        if (rc)
+                OBD_FREE(current_ctxt, sizeof(*current_ctxt));
+  
+        RETURN(rc);
+}
+
+void smfs_post_cleanup(struct super_block *sb)
+{
+        struct smfs_super_info *smb = S2SMI(sb);
+        
+        ENTRY;
+        
+        smfs_llog_cleanup(sb);
+        SMFS_PLG_HELP(sb, PLG_STOP, NULL);
+        
+        if (smb->smsi_ctxt)
+                OBD_FREE(smb->smsi_ctxt, sizeof(struct lvfs_run_ctxt));
+        
+        EXIT;
+}
+
 static int smfs_mount_cache(struct smfs_super_info *smb, char *devstr, 
                             char *typestr, char *opts)
 {
@@ -102,7 +218,7 @@ static int smfs_mount_cache(struct smfs_super_info *smb, char *devstr,
 
         typelen = strlen(typestr);
 
-        printk("smfs: mounting %s at %s\n", typestr, devstr);
+        CDEBUG(D_INODE, "smfs: mounting %s at %s\n", typestr, devstr);
         mnt = do_kern_mount(typestr, 0, devstr, (void *)opts);
         if (IS_ERR(mnt)) {
                 CERROR("do_kern_mount failed: rc = %ld\n", 
@@ -141,145 +257,110 @@ static int smfs_umount_cache(struct smfs_super_info *smb)
         return 0;
 }
 
-static int smfs_init_hook_ops(struct smfs_super_info *smb)
+/* This function initializes plugins in SMFS 
+ * @flags: are filled while options parsing 
+ * @sb: smfs super block
+ */
+
+static int smfs_init_plugins(struct super_block * sb, int flags)
 {
+        struct smfs_super_info * smb = S2SMI(sb);
+        
         ENTRY;
-        INIT_LIST_HEAD(&smb->smsi_hook_list);
+        
         INIT_LIST_HEAD(&smb->smsi_plg_list);
+
+        if (SMFS_IS(flags, SMFS_PLG_KML)) 
+                smfs_init_kml(sb);
+        if (SMFS_IS(flags, SMFS_PLG_LRU)) 
+                smfs_init_lru(sb);
+#if CONFIG_SNAPFS
+        if (SMFS_IS(flags, SMFS_PLG_COW)) 
+                smfs_init_cow(sb);
+#endif
         RETURN(0); 
 }
 
-static void smfs_cleanup_hook_ops(struct smfs_super_info *smb)
-{
-        struct list_head *hlist = &smb->smsi_hook_list;
-        ENTRY;
-
-        while (!list_empty(hlist)) {
-                struct smfs_hook_ops *smfs_hops;
-                
-                smfs_hops = list_entry(hlist->next, struct smfs_hook_ops, 
-                                       smh_list);
-                CERROR("Unregister %s hook ops\n", smfs_hops->smh_name);         
-                
-                smfs_unregister_hook_ops(smb, smfs_hops->smh_name);
-                smfs_free_hook_ops(smfs_hops); 
-        } 
-        EXIT;
-}
-static void smfs_cleanup_smb(struct super_block *sb)
+static void smfs_remove_plugins(struct super_block *sb)
 {
-        struct smfs_super_info *smb;
         ENTRY;
 
-        smb = S2SMI(sb);
-        if (smb) 
-                OBD_FREE(smb, sizeof(*smb));
-        EXIT;
-}
-
-void smfs_cleanup_hooks(struct smfs_super_info *smb)
-{
+        SMFS_PLG_HELP(sb, PLG_EXIT, (void*)sb);
         
-        if (SMFS_CACHE_HOOK(smb))
-                cache_space_hook_exit(smb);
-        if (SMFS_DO_REC(smb))
-                smfs_rec_cleanup(smb);
-#if CONFIG_SNAPFS
-        if (SMFS_DO_COW(smb))
-                smfs_cow_cleanup(smb);
-#endif  
-        smfs_cleanup_hook_ops(smb);
+        EXIT;
 }
 
 void smfs_put_super(struct super_block *sb)
 {
-        struct smfs_super_info *smfs_info = S2SMI(sb);
-
-        smfs_cleanup_hooks(smfs_info);
-        
-        if (sb)
-                smfs_umount_cache(smfs_info);
-        smfs_cleanup_smb(sb); 
-}
-
-static int smfs_init_hooks(struct super_block *sb)
-{ 
+        struct smfs_super_info *smb = S2SMI(sb);
         ENTRY;
-        if (SMFS_DO_REC(S2SMI(sb))) 
-                smfs_rec_init(sb);
-        if (SMFS_CACHE_HOOK(S2SMI(sb))) 
-                cache_space_hook_init(sb);
-#if CONFIG_SNAPFS
-        if (SMFS_DO_COW(S2SMI(sb))) 
-                smfs_cow_init(sb);
-#endif
-        RETURN(0);
+        smfs_remove_plugins(sb);
+        
+        dput(sb->s_root);
+        
+        if (smb->smsi_mnt)
+                smfs_umount_cache(smb);
+        
+        smfs_cleanup_smb(smb);
+        EXIT;
 }
 
-extern char* smfs_options(char*, char**, char**, char*, int *);
-extern void cleanup_option(void);
-
 int smfs_fill_super(struct super_block *sb, void *data, int silent)
 {
         struct inode *root_inode = NULL;
         struct smfs_super_info *smb = NULL;
         char *devstr = NULL, *typestr = NULL; 
-        char *opts = NULL, *cache_data = NULL;
-        unsigned long page;
-        int err = 0; 
+        char *opts = NULL;
+        int err = 0;
+        int flags = 0;
         ino_t root_ino;
 
         ENTRY;
+        
+        if (!data) {
+                CERROR("no mount options. At least name and dev are needed\n");
+                err = -EINVAL;
+                goto out_err;
+        }
 
-        CDEBUG(D_SUPER, "mount opts: %s\n", data ? 
-               (char *)data : "(none)");
+        CERROR("mount opts: %s\n", (char *)data);
 
         smb = smfs_init_smb(sb);
         if (!smb)
                 RETURN(-ENOMEM);
-        page = __get_free_page(GFP_KERNEL);
-        if (!page)
-                GOTO(out_err, err = -ENOMEM);
-        
-        memset((void *)page, 0, PAGE_SIZE);
-        opts = (char *)page;
-
-        cache_data = smfs_options(data, &devstr, &typestr, opts, 
-                                  &smb->smsi_flags); 
-        if (*cache_data) {
-                CWARN("smfs_fill_super(): options parsing stoped at "
-                      "option %s\n", cache_data);
+        lock_kernel();
+        OBD_ALLOC(opts, strlen(data) + 1);
+        if (!opts) {
+                err = -ENOMEM;
+                goto out_err;
         }
-
+        
+        err = smfs_options(data, &devstr, &typestr, opts, &flags);
+        if (err)
+                goto out_err;
+                
         if (!typestr || !devstr) {
                 CERROR("mount options name and dev are mandatory\n");
-                free_page(page);
-                GOTO(out_err, err = -EINVAL);
+                err = -EINVAL;
+                goto out_err;
         }
         
+        CERROR("backfs mount opts: %s\n", opts);
+
         err = smfs_mount_cache(smb, devstr, typestr, opts);
-        free_page(page);
-        
         if (err) {
                 CERROR("Can not mount %s as %s\n", devstr, typestr);
-                GOTO(out_err, err);
+                goto out_err;
         }
 
+        OBD_FREE(opts, strlen(data) + 1);
+        opts = NULL;
+        
         duplicate_sb(sb, smb->smsi_sb);
         sb->s_bdev = smb->smsi_sb->s_bdev;
         sm_set_sb_ops(smb->smsi_sb, sb);
 
-        err = smfs_init_hook_ops(smb);
-        if (err) {
-                CERROR("Can not init super hook ops err %d\n", err);
-                smfs_umount_cache(smb);
-                GOTO(out_err, err);
-        }
-        
         /* init the root_inode of smfs. */ 
-        //dget(S2CSB(sb)->s_root);
         root_ino = S2CSB(sb)->s_root->d_inode->i_ino;
         root_inode = smfs_get_inode(sb, root_ino, NULL, 0);
 
@@ -287,17 +368,11 @@ int smfs_fill_super(struct super_block *sb, void *data, int silent)
                sb->s_op->read_inode, root_ino, root_inode);
 
         sb->s_root = d_alloc_root(root_inode);
-
         if (!sb->s_root) {
-                smfs_umount_cache(smb);
-                GOTO(out_err, err = -ENOMEM);
+                err = -ENOMEM;
+                goto out_err;
         }
         
-        err = smfs_init_hooks(sb);  
-        if (err) {
-                smfs_umount_cache(smb);
-                GOTO(out_err, err);
-        }       
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
                (ulong)sb, (ulong)&sb->u.generic_sbp);
@@ -306,86 +381,19 @@ int smfs_fill_super(struct super_block *sb, void *data, int silent)
                (ulong)sb, smb->smsi_sb, (ulong)&sb->s_fs_info);
 #endif
         
+        smfs_init_plugins(sb, flags);
+        unlock_kernel();
+        RETURN (0);
 out_err:
-        cleanup_option();
-        if (err)
-                smfs_cleanup_smb(sb);
-        return err;
-}
-
-struct smfs_hook_ops *smfs_alloc_hook_ops(char *name, smfs_hook_func pre_hook, 
-                                          smfs_hook_func post_hook)
-{
-        struct smfs_hook_ops *smfs_hops = NULL;
-        
-        ENTRY;
-        OBD_ALLOC(smfs_hops, sizeof(struct smfs_hook_ops));
-
-        if (!smfs_hops)
-                RETURN(NULL);
-        OBD_ALLOC(smfs_hops->smh_name, strlen(name) + 1);
-        
-        if (!smfs_hops->smh_name) { 
-                OBD_FREE(smfs_hops, sizeof(struct smfs_hook_ops));
-                RETURN(NULL);
-        }
-        
-        memcpy(smfs_hops->smh_name, name, strlen(name));  
-       
-        smfs_hops->smh_post_op = post_hook;  
-        smfs_hops->smh_pre_op = pre_hook;  
-        
-        RETURN(smfs_hops); 
-}
-
-void smfs_free_hook_ops(struct smfs_hook_ops *hops)
-{
-        if (hops) {
-                if (hops->smh_name){
-                        OBD_FREE(hops->smh_name, strlen(hops->smh_name) + 1);
-                }
-                OBD_FREE(hops, sizeof(struct smfs_hook_ops));
-        }
-}
-
-int smfs_register_hook_ops(struct smfs_super_info *smb, 
-                           struct smfs_hook_ops *smh_ops)
-{
-        struct list_head *hlist = &smb->smsi_hook_list;
-        struct list_head *p;
-        ENTRY;
-        list_for_each(p, hlist) {
-                struct smfs_hook_ops *found;               
-                found = list_entry(p, struct smfs_hook_ops, smh_list);
-                if (!strcmp(found->smh_name, smh_ops->smh_name)) {
-                        CWARN("hook ops %s list  reregister\n", smh_ops->smh_name);
-                        RETURN(0);
-                }
-        }
-       list_add(&smh_ops->smh_list, hlist);
-        RETURN(0);
-} 
+        if (smb->smsi_mnt)
+                smfs_umount_cache(smb);
 
-struct smfs_hook_ops *smfs_unregister_hook_ops(struct smfs_super_info *smb, 
-                                               char *name)
-{
-        struct list_head *hlist = &smb->smsi_hook_list;
-        struct list_head *p;
-        ENTRY;      
-        list_for_each(p, hlist) {
-               struct smfs_hook_ops *found;
+        if (opts)
+                OBD_FREE(opts, strlen(data) + 1);
 
-                found = list_entry(p, typeof(*found), smh_list);
-                if (!memcmp(found->smh_name, name, strlen(name))) {
-                        list_del(p);
-                        RETURN(found);
-                }
-        }
-
-        RETURN(NULL);
+        smfs_cleanup_smb(smb);
+        unlock_kernel();
+        RETURN(err);
 }
 
 void *smfs_trans_start(struct inode *inode, int op, void *desc_private)
@@ -415,10 +423,11 @@ void smfs_trans_commit(struct inode *inode, void *handle, int force_sync)
         if (fsfilt->fs_commit)
                 fsfilt->fs_commit(inode->i_sb, inode, handle, force_sync);
 }
-
-
-int smfs_register_plugin(struct super_block * sb, struct smfs_plugin * new_plugin) 
+/* Plugin API */
+int smfs_register_plugin(struct super_block * sb,
+                         struct smfs_plugin * new_plugin) 
 {
+        struct smfs_super_info * smb = S2SMI(sb);
         struct smfs_plugin * plg = NULL;
         struct list_head * plist = &S2SMI(sb)->smsi_plg_list;
         
@@ -431,6 +440,12 @@ int smfs_register_plugin(struct super_block * sb, struct smfs_plugin * new_plugi
                 }
         }
         
+        
+        if (SMFS_IS(smb->smsi_flags, new_plugin->plg_type)) {
+                CWARN("Plugin is already registered\n");
+                RETURN(-EEXIST);  
+        }
+                
         OBD_ALLOC(plg, sizeof(*plg));
         if (!plg) {
                 CWARN("Cannot allocate memory for plugin\n");
@@ -439,17 +454,18 @@ int smfs_register_plugin(struct super_block * sb, struct smfs_plugin * new_plugi
         
         memcpy(plg, new_plugin, sizeof(*plg));
         list_add_tail(&plg->plg_list, plist);
-                
+        
         RETURN(0);
 }
 
-void * smfs_deregister_plugin(struct super_block * sb, int type)
+void * smfs_deregister_plugin(struct super_block *sb, int type)
 {
         struct smfs_plugin * plg = NULL;
         struct list_head * plist = &S2SMI(sb)->smsi_plg_list;
         void * priv = NULL;
         
         ENTRY;
+
         list_for_each_entry(plg, plist, plg_list) {
                 if (plg->plg_type == type) {
                         list_del(&plg->plg_list);
@@ -462,4 +478,73 @@ void * smfs_deregister_plugin(struct super_block * sb, int type)
         RETURN(priv);
 }
 
+void smfs_pre_hook (struct inode * inode, int op, void * msg) 
+{
+        struct smfs_super_info *smb = S2SMI(inode->i_sb);    
+        struct smfs_inode_info *smi = I2SMI(inode);
+        struct list_head *hlist = &smb->smsi_plg_list;
+        struct smfs_plugin *plg;
+                
+        //ENTRY;
+        LASSERT(op < HOOK_MAX);
+        //call hook operations
+        list_for_each_entry(plg, hlist, plg_list) {
+                //check that plugin is active
+                if(!SMFS_IS(smb->plg_flags, plg->plg_type))
+                        continue;
+                //check that inode is not exclusion
+                if (!SMFS_IS(smi->smi_flags, plg->plg_type))
+                        continue;
+                
+                if (plg->plg_pre_op)
+                        plg->plg_pre_op(op, inode, msg, 0, plg->plg_private);
+        }
+
+        //EXIT;
+}
+
+void smfs_post_hook (struct inode * inode, int op, void * msg, int ret)
+{
+        struct smfs_super_info *smb = S2SMI(inode->i_sb);
+        struct smfs_inode_info *smi = I2SMI(inode);
+        struct list_head *hlist = &smb->smsi_plg_list;
+        struct smfs_plugin *plg;
+        
+        //ENTRY;
+        
+        list_for_each_entry(plg, hlist, plg_list) {
+                //check that plugin is active
+                if(!SMFS_IS(smb->plg_flags, plg->plg_type))
+                        continue;
+                //check that inode is not exclusion
+                if (!SMFS_IS(smi->smi_flags, plg->plg_type))
+                        continue;
+                
+                if (plg->plg_post_op)
+                        plg->plg_post_op(op, inode, msg, ret, plg->plg_private);
+        }
+
+        //EXIT;
+}
+
+int smfs_helper (struct super_block * sb, int op, void * msg) 
+{
+        struct smfs_super_info *smb = S2SMI(sb);    
+        struct list_head *hlist = &smb->smsi_plg_list;
+        struct smfs_plugin *plg;
+        int rc = 0;
+        
+        ENTRY;
+        LASSERT(op < PLG_HELPER_MAX);
+        //call hook operations
+        list_for_each_entry(plg, hlist, plg_list) {
+               if (plg->plg_helper)
+                       rc += plg->plg_helper(op, sb, msg, plg->plg_private);
+        }
+
+        EXIT;
+        
+        return rc;
+}
+
 
index 5e6ffe0..1356419 100644 (file)
 #include <linux/lvfs.h>
 
 #include "smfs_internal.h"
-
-static int smfs_llog_process_rec_cb(struct llog_handle *handle,
-                                    struct llog_rec_hdr *rec, void *data)
-{
-        char   *rec_buf ;
-        struct smfs_proc_args *args = (struct smfs_proc_args *)data;
-        struct lvfs_run_ctxt saved;
-        int    rc = 0;
-
-        if (!(le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)) {
-                CERROR("log is not plain\n");
-                RETURN(-EINVAL);
-        }
-
-        if (le32_to_cpu(rec->lrh_type) == LLOG_GEN_REC) {
-                struct llog_cookie cookie;
-
-                cookie.lgc_lgl = handle->lgh_id;
-                cookie.lgc_index = le32_to_cpu(rec->lrh_index);
-
-                llog_cancel(handle->lgh_ctxt, 1, &cookie, 0, NULL);
-                RETURN(LLOG_PROC_BREAK);
-        }
-
-        if (le32_to_cpu(rec->lrh_type) != SMFS_UPDATE_REC)
-                RETURN(-EINVAL);
-
-        rec_buf = (char*) (rec + 1);
-
-        if (!S2SMI(args->sr_sb)->smsi_ctxt)
-                GOTO(exit, rc = -ENODEV);
-
-        push_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
-#if 0
-        /*FIXME later should first unpack the rec,
-         * then call lvfs_reint or lvfs_undo
-         * kml rec format has changed lvfs_reint lvfs_undo should
-         * be rewrite FIXME later*/
-        if (SMFS_DO_REINT_REC(args->sr_flags))
-                rc = lvfs_reint(args->sr_sb, rec_buf);
-        else
-                rc = lvfs_undo(args->sr_sb, rec_buf);
-#endif
-        if (!rc && !SMFS_DO_REC_ALL(args->sr_flags)) {
-                args->sr_count --;
-                if (args->sr_count == 0)
-                        rc = LLOG_PROC_BREAK;
-        }
-        pop_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
-exit:
-        RETURN(rc);
-}
-
 int smfs_llog_setup(struct super_block *sb, struct vfsmount *mnt)
 {
-        struct llog_ctxt **ctxt = &(S2SMI(sb)->smsi_rec_log);
-        struct lvfs_run_ctxt saved;
-        struct dentry *dentry;
-        int rc = 0, rc2;
+        struct dentry *dentry = NULL;
+        int rc = 0;
 
         /* create OBJECTS and LOGS for writing logs */
         ENTRY;
 
         LASSERT(mnt);
 
-        push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
+        //push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
         dentry = simple_mkdir(current->fs->pwd, "LOGS", 0777, 1);
         if (IS_ERR(dentry)) {
                 rc = PTR_ERR(dentry);
                 CERROR("cannot create LOGS directory: rc = %d\n", rc);
-                GOTO(exit, rc = -EINVAL);
+                rc = -EINVAL;
+                goto exit;
         }
 
         S2SMI(sb)->smsi_logs_dir = dentry;
+        SMFS_SET(I2SMI(dentry->d_inode)->smi_flags, SMFS_PLG_ALL);
+        
         dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777, 1);
         if (IS_ERR(dentry)) {
                 rc = PTR_ERR(dentry);
                 CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
-                GOTO(exit, rc = -EINVAL);
+                rc = -EINVAL;
+                goto exit;
         }
 
         S2SMI(sb)->smsi_objects_dir = dentry;
+        SMFS_SET(I2SMI(dentry->d_inode)->smi_flags, SMFS_PLG_ALL);
 
         /* write log will not write to KML, cleanup kml flags */
-        SMFS_CLEAN_INODE_REC(S2SMI(sb)->smsi_objects_dir->d_inode);
-        SMFS_CLEAN_INODE_REC(S2SMI(sb)->smsi_logs_dir->d_inode);
+        //SMFS_CLEAN_INODE_REC(S2SMI(sb)->smsi_objects_dir->d_inode);
+        //SMFS_CLEAN_INODE_REC(S2SMI(sb)->smsi_logs_dir->d_inode);
 
         /* log create does not call cache hooks, cleanup hook flags */
-        SMFS_CLEAN_INODE_CACHE_HOOK(S2SMI(sb)->smsi_objects_dir->d_inode);
-        SMFS_CLEAN_INODE_CACHE_HOOK(S2SMI(sb)->smsi_logs_dir->d_inode);
+        //SMFS_CLEAN_INODE_CACHE_HOOK(S2SMI(sb)->smsi_objects_dir->d_inode);
+        //SMFS_CLEAN_INODE_CACHE_HOOK(S2SMI(sb)->smsi_logs_dir->d_inode);
 
-        if (SMFS_DO_REC(S2SMI(sb))) {
-                rc = llog_catalog_setup(ctxt, KML_LOG_NAME, S2SMI(sb)->smsi_exp,
-                                        S2SMI(sb)->smsi_ctxt, S2SMI(sb)->sm_fsfilt,
-                                        S2SMI(sb)->smsi_logs_dir,
-                                        S2SMI(sb)->smsi_objects_dir);
-                (*ctxt)->llog_proc_cb = smfs_llog_process_rec_cb;
-        }
-
-        if (SMFS_CACHE_HOOK(S2SMI(sb))) {
+        
+        /*if (SMFS_CACHE_HOOK(S2SMI(sb))) {
                 rc2 = cache_space_hook_setup(sb);
                 if (!rc && rc2)
                         rc = rc2;
-        }
+        }*/
 exit:
-        pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
+        //pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
         RETURN(rc);
 }
 
 int smfs_llog_cleanup(struct super_block *sb)
 {
-        struct llog_ctxt *ctxt = S2SMI(sb)->smsi_rec_log;
-        int rc = 0, rc2;
         ENTRY;
 
+        /*
         if (SMFS_CACHE_HOOK(S2SMI(sb)))
                 rc = cache_space_hook_cleanup();
 
@@ -154,7 +96,7 @@ int smfs_llog_cleanup(struct super_block *sb)
                 if (!rc)
                         rc = rc2;
         }
-
+        */
         if (S2SMI(sb)->smsi_logs_dir) {
                 l_dput(S2SMI(sb)->smsi_logs_dir);
                 S2SMI(sb)->smsi_logs_dir = NULL;
@@ -163,7 +105,7 @@ int smfs_llog_cleanup(struct super_block *sb)
                 l_dput(S2SMI(sb)->smsi_objects_dir);
                 S2SMI(sb)->smsi_objects_dir = NULL;
         }
-        RETURN(rc);
+        RETURN(0);
 }
 
 int smfs_llog_add_rec(struct smfs_super_info *sinfo, void *data, int data_size)
@@ -174,10 +116,11 @@ int smfs_llog_add_rec(struct smfs_super_info *sinfo, void *data, int data_size)
         rec.lrh_len = size_round(data_size);
         rec.lrh_type = SMFS_UPDATE_REC;
 
-        rc = llog_add(sinfo->smsi_rec_log, &rec, data, NULL, 0, NULL, NULL, NULL);
+        rc = llog_add(sinfo->smsi_kml_log, &rec, data, NULL, 0, NULL, NULL, NULL);
         if (rc != 1) {
                 CERROR("error adding kml rec: %d\n", rc);
                 RETURN(-EINVAL);
         }
         RETURN(0);
 }
+