X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fsmfs%2Fcache_space.c;h=674a2647245b4e59b910492d47b0bd2619e27780;hb=00fc7ec0e84c297275f3d746b18ea0310e69cf57;hp=a2f3133317aa95f2d76a5d67e485c349164542aa;hpb=cd9c585e8c7bdd6cfd802be64ef277dfd466be17;p=fs%2Flustre-release.git diff --git a/lustre/smfs/cache_space.c b/lustre/smfs/cache_space.c index a2f3133..674a264 100644 --- a/lustre/smfs/cache_space.c +++ b/lustre/smfs/cache_space.c @@ -2,10 +2,10 @@ * vim:expandtab:shiftwidth=8:tabstop=8: * * lustre/smfs/cache_space.c - * A library of functions to manage cache space based on ARC + * A library of functions to manage cache space based on ARC * (modified LRU) replacement algorithm. - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. + * + * Copyright (c) 2004 Cluster File Systems, Inc. * * This file is part of Lustre, http://www.lustre.org. * @@ -25,6 +25,7 @@ #define DEBUG_SUBSYSTEM S_SM #include +#include #include #include "smfs_internal.h" @@ -34,7 +35,7 @@ struct cache_purge_param { 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 + 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}; @@ -42,35 +43,81 @@ 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_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; + + RETURN(0); } -int cache_space_hook_exit(struct super_block *sb) + +int cache_space_hook_exit(struct smfs_super_info *smfs_info) { - struct smfs_super_info *smfs_info = S2SMI(sb); + 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; } -int smfs_cache_hook(struct inode *inode) -{ - struct smfs_super_info *smfs_info = I2CSB(inode); - - if (SMFS_CACHE_HOOK(smfs_info) && SMFS_INIT_REC(smfs_info) - && SMFS_INODE_CACHE_HOOK(inode)) - return 1; - else - return 0; -} static int cache_leaf_node(struct dentry *dentry, __u64 *active_entry) { struct inode *inode = dentry->d_inode; + if (!dentry->d_inode) + return 0; if (S_ISDIR(inode->i_mode)) { if (inode->i_nlink != 2) return 0; @@ -133,13 +180,13 @@ static int try2purge_from_cache(struct ll_fid cfid, struct ll_fid pfid) inode = iget(sb, cfid.id); if (IS_ERR(inode)) { - CERROR("not existent inode: "LPX64"/%u\n", + CERROR("not existent inode: "LPX64"/%u\n", cfid.id, cfid.generation); RETURN(-ENOENT); } parent = iget(sb, pfid.id); if (IS_ERR(parent)) { - CERROR("not existent inode: "LPX64"/%u\n", + CERROR("not existent inode: "LPX64"/%u\n", pfid.id, pfid.generation); iput(inode); RETURN(-ENOENT); @@ -218,13 +265,13 @@ static int cache_balance_state(void) rc = fsops->fs_statfs(cpq->cpq_sb, &osfs); LASSERT(rc == 0); - free = (osfs.os_blocks - osfs.os_bfree) * 100; + free = (osfs.os_blocks - osfs.os_bfree) * 100; if (free > cf_prm.nfract * osfs.os_blocks) { if (free < cf_prm.nfract_sync) return 1; return 0; } - return -1; + return -1; } void wakeup_cpurge(void) @@ -272,12 +319,12 @@ void cache_space_pre(struct inode *inode, int op) check_cache_space(); } -static int cache_space_hook_lru(struct inode *inode, struct inode *parent, +static int cache_space_hook_lru(struct inode *inode, struct inode *parent, void *handle, 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_lru_rec *llr = NULL; struct llog_cookie *logcookie = NULL; int cookie_size = sizeof(struct llog_cookie); int rc = 0, err; @@ -294,13 +341,13 @@ static int cache_space_hook_lru(struct inode *inode, struct inode *parent, if (op & CACHE_SPACE_DELETE) { rc = get_lru_logcookie(inode, logcookie); - if (rc < 0) + if (rc < 0) GOTO(out, rc); 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); + GOTO(insert, rc = -ENOENT); } if (flags && llog_cat_half_bottom(logcookie, ctxt->loc_handle)) GOTO(out, rc = 0); @@ -322,7 +369,7 @@ insert: LASSERT(parent != NULL); OBD_ALLOC(llr, sizeof(*llr)); if (llr == NULL) - GOTO(out, rc = -ENOMEM); + GOTO(out, rc = -ENOMEM); llr->llr_hdr.lrh_len = llr->llr_tail.lrt_len = sizeof(*llr); llr->llr_hdr.lrh_type = CACHE_LRU_REC; @@ -333,7 +380,8 @@ insert: 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); + 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); @@ -343,7 +391,7 @@ insert: if (op & CACHE_SPACE_COMMIT) { if (handle) { - err = fsops->fs_commit(inode, handle, 0); + err = fsops->fs_commit(inode->i_sb, inode, handle, 0); if (err) { CERROR("error committing transaction: %d\n", err); if (!rc) @@ -351,7 +399,7 @@ insert: } } } -out: +out: if (logcookie) OBD_FREE(logcookie, cookie_size); if (llr) @@ -381,11 +429,11 @@ static int cache_purge_thread(void *args) purge_some_cache(&ndirty); if (ndirty > 0 || cpurge_stop()) - l_wait_event(cpq->cpq_waitq, + l_wait_event(cpq->cpq_waitq, cpq->cpq_flags & SVC_STOPPING, &lwi); if (cpq->cpq_flags & SVC_STOPPING) { - cpq->cpq_flags &= ~SVC_STOPPING; + cpq->cpq_flags &= ~SVC_STOPPING; EXIT; break; } @@ -403,6 +451,7 @@ int cache_space_hook_setup(struct super_block *sb) /* 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, @@ -412,7 +461,7 @@ int cache_space_hook_setup(struct super_block *sb) RETURN(rc); } cpq->cpq_sb = sb; - cpq->cpq_loghandle = ctxt->loc_handle; + cpq->cpq_loghandle = ctxt->loc_handle; /* start cache purge daemon, only one daemon now */ init_waitqueue_head(&cpq->cpq_waitq); @@ -429,11 +478,13 @@ int cache_space_hook_setup(struct super_block *sb) 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; @@ -441,9 +492,11 @@ int cache_space_hook_cleanup(void) cpq->cpq_flags = SVC_STOPPING; wake_up(&cpq->cpq_waitq); wait_for_completion(&cpq->cpq_comp); - - rc = llog_catalog_cleanup(cpq->cpq_loghandle->lgh_ctxt); - if (rc) + + 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); @@ -470,7 +523,7 @@ 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, handle); RETURN(rc); } static int cache_space_hook_lookup(void *handle, struct inode *dir, @@ -480,7 +533,7 @@ static int cache_space_hook_lookup(void *handle, struct inode *dir, __u64 active_entry; int rc = 0; - if (cache_leaf_node(dentry, &active_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); RETURN(rc); @@ -494,7 +547,7 @@ static int cache_space_hook_link(void *handle, struct inode *dir, if (cache_pre_leaf_node(dentry, NULL, 1)) { rc = cache_space_hook_lru(dentry->d_inode, NULL, - handle, CACHE_SPACE_DELETE, 0); + handle, CACHE_SPACE_DELETE, 0); if (rc) RETURN(rc); } @@ -509,7 +562,7 @@ 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, handle); RETURN(rc); } static int cache_space_hook_unlink(void *handle, struct inode *dir, @@ -520,7 +573,7 @@ static int cache_space_hook_unlink(void *handle, struct inode *dir, int rc = 0; if (cache_pre_leaf_node(dentry, NULL, 0)) - rc = cache_space_hook_lru(dentry->d_inode, NULL, + rc = cache_space_hook_lru(dentry->d_inode, NULL, handle, CACHE_SPACE_DELETE, 0); else if (cache_leaf_node(dentry, NULL)) rc = cache_space_hook_lru(dentry->d_inode, dir, @@ -532,13 +585,13 @@ static int cache_space_hook_unlink(void *handle, struct inode *dir, active_entry --; if (!rc) rc = set_active_entry(dir, &active_entry, handle); - if (!rc && cache_leaf_node(dentry->d_parent, &active_entry)) + 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); RETURN(rc); } -static int cache_space_hook_mkdir(void *handle, struct inode *dir, +static int cache_space_hook_mkdir(void *handle, struct inode *dir, struct dentry *dentry, struct inode *new_dir, struct dentry *new_dentry) { @@ -553,7 +606,7 @@ static int cache_space_hook_mkdir(void *handle, struct inode *dir, rc = cache_space_hook_lru(dir,NULL,handle,CACHE_SPACE_DELETE,0); RETURN(rc); } -static int cache_space_hook_rmdir(void *handle, struct inode *dir, +static int cache_space_hook_rmdir(void *handle, struct inode *dir, struct dentry *dentry, struct inode *new_dir, struct dentry *new_dentry) { @@ -570,7 +623,7 @@ static int cache_space_hook_rmdir(void *handle, struct inode *dir, handle, CACHE_SPACE_INSERT, 0); RETURN(rc); } -static int cache_space_hook_rename(void *handle, struct inode *old_dir, +static int cache_space_hook_rename(void *handle, struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { @@ -622,28 +675,33 @@ static int cache_space_hook_rename(void *handle, struct inode *old_dir, 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 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, + [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) { - int rc; + int rc = 0; ENTRY; - LASSERT(op <= CACHE_HOOK_MAX && cache_space_hook_ops[op] != NULL); + LASSERT(op <= HOOK_MAX + 1); - rc = cache_space_hook_ops[op](handle, old_dir, old_dentry, - new_dir, new_dentry); + if (cache_space_hook_ops[op]) + rc = cache_space_hook_ops[op](handle, old_dir, old_dentry, + new_dir, new_dentry); RETURN(rc); }