From: tappro Date: Wed, 13 Apr 2005 07:01:32 +0000 (+0000) Subject: b=5881 X-Git-Tag: v1_7_100~1446 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=4701d16168bd7ebfe0ef3cc49db4dcef34739cb4;p=fs%2Flustre-release.git b=5881 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 --- diff --git a/lustre/smfs/Makefile.in b/lustre/smfs/Makefile.in index 1f8f387..28821e8 100644 --- a/lustre/smfs/Makefile.in +++ b/lustre/smfs/Makefile.in @@ -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@ diff --git a/lustre/smfs/cache_space.c b/lustre/smfs/cache_space.c index ec87b6d..1e27fff 100644 --- a/lustre/smfs/cache_space.c +++ b/lustre/smfs/cache_space.c @@ -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 index ab62e7a..0000000 --- a/lustre/smfs/journal.c +++ /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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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; -} diff --git a/lustre/smfs/kml.c b/lustre/smfs/kml.c index 2692963..338b995 100644 --- a/lustre/smfs/kml.c +++ b/lustre/smfs/kml.c @@ -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); +} + + diff --git a/lustre/smfs/smfs_lib.c b/lustre/smfs/smfs_lib.c index 2855883..cf89a4e 100644 --- a/lustre/smfs/smfs_lib.c +++ b/lustre/smfs/smfs_lib.c @@ -45,8 +45,66 @@ #include #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; +} + diff --git a/lustre/smfs/smfs_llog.c b/lustre/smfs/smfs_llog.c index 5e6ffe0..1356419 100644 --- a/lustre/smfs/smfs_llog.c +++ b/lustre/smfs/smfs_llog.c @@ -30,121 +30,63 @@ #include #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); } +