#include "smfs_internal.h"
struct cache_purge_param {
- int nfract; /* Percentage of cache dirty to activate cpurge */
- int ndirty; /* Maximum number of objects to write out per
- wake-cycle */
- int interval; /* jiffies delay between cache purge */
- int nfract_sync;/* Percentage of cache dirty to activate
- cpurge synchronously */
- int nfract_stop_cpurge; /* Percentage of cache dirty to stop cpurge */
+ int nfract; /* percentage of cache dirty to activate
+ * cpurge */
+ int ndirty; /* maximum number of objects to write out per
+ wake-cycle */
+ int interval; /* jiffies delay between cache purge */
+ int nfract_sync; /* percentage of cache dirty to activate cpurge
+ synchronously */
+ int nfract_stop_cpurge; /* percentage of cache dirty to stop cpurge */
} cf_prm = {30, 512, 600 * HZ, 60, 20};
static struct cache_purge_queue smfs_cpq;
static struct cache_purge_queue *cpq = &smfs_cpq;
-int cache_space_hook_init(struct super_block *sb)
-{
- struct smfs_super_info *smfs_info = S2SMI(sb);
-
- SMFS_SET_CACHE_HOOK(smfs_info);
- return 0;
-}
-int cache_space_hook_exit(struct super_block *sb)
-{
- struct smfs_super_info *smfs_info = S2SMI(sb);
-
- 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 (!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);
} 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;
}
}
+
static int cache_pre_leaf_node(struct dentry *dentry, __u64 *active_entry, int op)
{
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)) {
{
struct fsfilt_operations *fsops = I2CSB(inode)->sm_fsfilt;
int rc;
+ ENTRY;
+
rc = fsops->fs_set_xattr(inode, handle, XATTR_SMFS_CACHE_LOGCOOKIE,
logcookie, sizeof(*logcookie));
RETURN(rc);
}
+
static int get_lru_logcookie(struct inode *inode, struct llog_cookie *logcookie)
{
struct fsfilt_operations *fsops = I2CSB(inode)->sm_fsfilt;
int rc;
+
+ ENTRY;
rc = fsops->fs_get_xattr(inode, XATTR_SMFS_CACHE_LOGCOOKIE,
logcookie, sizeof(*logcookie));
RETURN(rc);
}
-static int try2purge_from_cache(struct ll_fid cfid, struct ll_fid pfid)
+static int try2purge_from_cache(struct lustre_id cid,
+ struct lustre_id pid)
{
struct inode *inode, *parent;
struct super_block *sb = cpq->cpq_sb;
- //struct llog_cookie logcookie;
__u32 hoard_priority = 0;
int rc = 0;
ENTRY;
- inode = iget(sb, cfid.id);
+ inode = iget(sb, cid.li_stc.u.e3s.l3s_ino);
if (IS_ERR(inode)) {
CERROR("not existent inode: "LPX64"/%u\n",
- cfid.id, cfid.generation);
+ cid.li_stc.u.e3s.l3s_ino,
+ cid.li_stc.u.e3s.l3s_gen);
RETURN(-ENOENT);
}
- parent = iget(sb, pfid.id);
+ parent = iget(sb, pid.li_stc.u.e3s.l3s_ino);
if (IS_ERR(parent)) {
CERROR("not existent inode: "LPX64"/%u\n",
- pfid.id, pfid.generation);
+ pid.li_stc.u.e3s.l3s_ino,
+ pid.li_stc.u.e3s.l3s_gen);
iput(inode);
RETURN(-ENOENT);
}
llr = (struct llog_lru_rec *)rec;
- if (try2purge_from_cache(llr->llr_cfid, llr->llr_pfid)==1){
+ if (try2purge_from_cache(llr->llr_cid, llr->llr_pid)==1){
CDEBUG(D_INODE, "purge ino/gen "LPX64"/%u from cache\n",
- llr->llr_cfid.id, llr->llr_cfid.generation);
+ llr->llr_cid.li_stc.u.e3s.l3s_ino,
+ llr->llr_cid.li_stc.u.e3s.l3s_gen);
count --;
if (count == 0)
rc = LLOG_PROC_BREAK;
}
#define CFLUSH_NR 512
+
static void check_cache_space(void)
{
int state = cache_balance_state();
ENTRY;
- if (state < 0)
+ if (state < 0) {
+ EXIT;
return;
+ }
wakeup_cpurge();
int count = CFLUSH_NR;
purge_some_cache(&count);
}
-}
-
-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;
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)
llr->llr_hdr.lrh_len = llr->llr_tail.lrt_len = sizeof(*llr);
llr->llr_hdr.lrh_type = CACHE_LRU_REC;
- llr->llr_cfid.id = inode->i_ino;
- llr->llr_cfid.generation = inode->i_generation;
- llr->llr_cfid.f_type = inode->i_mode & S_IFMT;
- llr->llr_pfid.id = parent->i_ino;
- llr->llr_pfid.generation = parent->i_generation;
- llr->llr_pfid.f_type = parent->i_mode & S_IFMT;
-
- rc = llog_add(ctxt, &llr->llr_hdr, NULL, logcookie, 1, NULL);
+
+ /* FIXME-UMKA: should we setup fid components here? */
+ 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;
+
+ 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);
if (rc != 1) {
CERROR("failed at llog_add: %d\n", rc);
GOTO(out, rc);
}
cpq->cpq_flags = SVC_STOPPED;
complete(&cpq->cpq_comp);
- 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);
}
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);
}
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;
+ ENTRY;
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;
+ ENTRY;
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);
}
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);
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);
- } else if (cache_pre_leaf_node(new_dentry->d_parent, &active_entry, 3))
- rc = cache_space_hook_lru(new_dir, NULL, 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,
CACHE_SPACE_DELETE, 0);
+ }
- if (!rc && cache_leaf_node(old_dentry->d_parent, &active_entry))
+ 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);
+ old_dentry->d_parent->d_parent->d_inode,
+ 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[CACHE_HOOK_MAX + 1] = {
- [CACHE_HOOK_CREATE] cache_space_hook_create,
- [CACHE_HOOK_LOOKUP] cache_space_hook_lookup,
- [CACHE_HOOK_LINK] cache_space_hook_link,
- [CACHE_HOOK_UNLINK] cache_space_hook_unlink,
- [CACHE_HOOK_SYMLINK] cache_space_hook_create,
- [CACHE_HOOK_MKDIR] cache_space_hook_mkdir,
- [CACHE_HOOK_RMDIR] cache_space_hook_rmdir,
- [CACHE_HOOK_MKNOD] cache_space_hook_create,
- [CACHE_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);
+}
+
+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);
+
+ 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);
- LASSERT(op <= CACHE_HOOK_MAX && cache_space_hook_ops[op] != NULL);
+ 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);
+}
- rc = cache_space_hook_ops[op](handle, old_dir, old_dentry,
- new_dir, new_dentry);
+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);
}
+
+