X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fsmfs%2Fcache_space.c;h=bbbdf0bf364403ef4f7002ebc8e882e253942138;hb=d0a54de6fc931066fd5cf18c78d2eba597e09942;hp=e42156fab5853564cd1422666edd2f419d51191c;hpb=9d4b898b1c1c7c318fda5f0c345ed726c774c06a;p=fs%2Flustre-release.git diff --git a/lustre/smfs/cache_space.c b/lustre/smfs/cache_space.c index e42156f..bbbdf0b 100644 --- a/lustre/smfs/cache_space.c +++ b/lustre/smfs/cache_space.c @@ -44,86 +44,18 @@ 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; - if (!strncmp(dentry->d_name.name, "lost+found", - dentry->d_name.len)) + if (!strncmp((char *)dentry->d_name.name, + "lost+found", dentry->d_name.len)) return 0; LASSERT(active_entry != NULL); get_active_entry(inode, active_entry); @@ -131,8 +63,8 @@ static int cache_leaf_node(struct dentry *dentry, __u64 *active_entry) } else { if (inode->i_nlink != 1) return 0; - if (!strncmp(dentry->d_name.name, KML_LOG_NAME, dentry->d_name.len) || - !strncmp(dentry->d_name.name, CACHE_LRU_LOG, dentry->d_name.len)) + if (!strncmp((char *)dentry->d_name.name, KML_LOG_NAME, dentry->d_name.len) || + !strncmp((char *)dentry->d_name.name, CACHE_LRU_LOG, dentry->d_name.len)) return 0; return 1; } @@ -142,8 +74,8 @@ static int cache_pre_leaf_node(struct dentry *dentry, __u64 *active_entry, int o { if (((op == 0 && dentry->d_inode->i_nlink == 0) || (op == 1 && dentry->d_inode->i_nlink == 2)) && - strncmp(dentry->d_name.name, KML_LOG_NAME, dentry->d_name.len) && - strncmp(dentry->d_name.name, CACHE_LRU_LOG, dentry->d_name.len)) + strncmp((char *)dentry->d_name.name, KML_LOG_NAME, dentry->d_name.len) && + strncmp((char *)dentry->d_name.name, CACHE_LRU_LOG, dentry->d_name.len)) return 1; else if ((op == 2 && dentry->d_inode->i_nlink == 0) || (op == 3 && dentry->d_inode->i_nlink == 3)) { @@ -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) @@ -392,13 +314,13 @@ insert: llr->llr_hdr.lrh_type = CACHE_LRU_REC; /* FIXME-UMKA: should we setup fid components here? */ - llr->llr_cid.li_stc.u.e3s.l3s_ino = inode->i_ino; - llr->llr_cid.li_stc.u.e3s.l3s_gen = inode->i_generation; - llr->llr_cid.li_stc.u.e3s.l3s_type = inode->i_mode & S_IFMT; + id_ino(&llr->llr_cid) = inode->i_ino; + id_gen(&llr->llr_cid) = inode->i_generation; + id_type(&llr->llr_cid) = inode->i_mode & S_IFMT; - llr->llr_pid.li_stc.u.e3s.l3s_ino = parent->i_ino; - llr->llr_pid.li_stc.u.e3s.l3s_gen = parent->i_generation; - llr->llr_pid.li_stc.u.e3s.l3s_type = parent->i_mode & S_IFMT; + id_ino(&llr->llr_pid) = parent->i_ino; + id_gen(&llr->llr_pid) = parent->i_generation; + id_type(&llr->llr_pid) = parent->i_mode & S_IFMT; rc = llog_add(ctxt, &llr->llr_hdr, NULL, logcookie, 1, NULL, NULL, 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,253 @@ 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(hook_op op, struct inode *inode, void * msg, int ret, + void *priv) { int rc = 0; ENTRY; + + /* FIXME have not used op */ + check_cache_space(); + + RETURN(rc); +} - LASSERT(op <= HOOK_MAX + 1); +static int smfs_lru_post_op(hook_op 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_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); - if (cache_space_hook_ops[op]) - rc = cache_space_hook_ops[op](handle, old_dir, old_dentry, - new_dir, new_dentry); + 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)); + RETURN(rc); } + +