+/* Helpers */
+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);
+
+ /* 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;
+
+ /* 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_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);
+}
+
+static int smfs_exit_lru(struct super_block *sb, void * arg)
+{
+ struct smfs_plugin * plg;
+
+ ENTRY;
+
+ plg = smfs_deregister_plugin(sb, SMFS_PLG_LRU);
+ if (plg)
+ OBD_FREE(plg, sizeof(*plg));
+ else
+ CERROR("Cannot find LRU plugin while unregistering\n");
+
+ EXIT;
+ return 0;
+}
+
+int smfs_init_lru(struct super_block *sb)
+{
+ struct smfs_plugin * plg = NULL;
+ int rc = 0;
+
+ ENTRY;
+
+ OBD_ALLOC(plg, sizeof(*plg));
+ if (!plg) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ plg->plg_type = SMFS_PLG_LRU;
+ plg->plg_pre_op = &smfs_lru_pre_op;
+ plg->plg_post_op = &smfs_lru_post_op;
+ plg->plg_helper = &smfs_lru_help_op;
+ plg->plg_exit = &smfs_exit_lru;
+
+ rc = smfs_register_plugin(sb, plg);
+ if (!rc)
+ RETURN(0);
+exit:
+ if (plg)
+ OBD_FREE(plg, sizeof(*plg));
+