1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/smfs/smfs_llog.c
5 * Lustre filesystem abstraction routines
7 * Copyright (C) 2004 Cluster File Systems, Inc.
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #define DEBUG_SUBSYSTEM S_SM
27 #include <linux/lustre_log.h>
28 #include <linux/lustre_fsfilt.h>
29 #include <linux/lustre_smfs.h>
30 #include <linux/lvfs.h>
32 #include "smfs_internal.h"
34 static int smfs_llog_process_rec_cb(struct llog_handle *handle,
35 struct llog_rec_hdr *rec, void *data)
38 struct smfs_proc_args *args = (struct smfs_proc_args *)data;
39 struct lvfs_run_ctxt saved;
42 if (!(le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)) {
43 CERROR("log is not plain\n");
47 if (le32_to_cpu(rec->lrh_type) == LLOG_GEN_REC) {
48 struct llog_cookie cookie;
50 cookie.lgc_lgl = handle->lgh_id;
51 cookie.lgc_index = le32_to_cpu(rec->lrh_index);
53 llog_cancel(handle->lgh_ctxt, 1, &cookie, 0, NULL);
54 RETURN(LLOG_PROC_BREAK);
57 if (le32_to_cpu(rec->lrh_type) != SMFS_UPDATE_REC)
60 rec_buf = (char*) (rec + 1);
62 if (!S2SMI(args->sr_sb)->smsi_ctxt)
63 GOTO(exit, rc = -ENODEV);
65 push_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
67 /*FIXME later should first unpack the rec,
68 * then call lvfs_reint or lvfs_undo
69 * kml rec format has changed lvfs_reint lvfs_undo should
70 * be rewrite FIXME later*/
71 if (SMFS_DO_REINT_REC(args->sr_flags))
72 rc = lvfs_reint(args->sr_sb, rec_buf);
74 rc = lvfs_undo(args->sr_sb, rec_buf);
76 if (!rc && !SMFS_DO_REC_ALL(args->sr_flags)) {
78 if (args->sr_count == 0)
81 pop_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
86 int smfs_llog_setup(struct super_block *sb, struct vfsmount *mnt)
88 struct llog_ctxt **ctxt = &(S2SMI(sb)->smsi_rec_log);
89 struct lvfs_run_ctxt saved;
90 struct lvfs_run_ctxt *current_ctxt = NULL;
91 struct vfsmount *get_mnt = mnt;
92 struct dentry *dentry;
95 /* create OBJECTS and LOGS for writing logs */
97 OBD_ALLOC(current_ctxt, sizeof(*current_ctxt));
101 get_mnt = get_vfsmount(sb);
103 OBD_FREE(current_ctxt, sizeof(*current_ctxt));
107 OBD_SET_CTXT_MAGIC(current_ctxt);
109 current_ctxt->pwdmnt = get_mnt;
110 current_ctxt->pwd = get_mnt->mnt_root;
111 current_ctxt->fs = get_ds();
112 S2SMI(sb)->smsi_ctxt = current_ctxt;
114 push_ctxt(&saved, current_ctxt, NULL);
115 dentry = simple_mkdir(current->fs->pwd, "LOGS", 0777, 1);
116 if (IS_ERR(dentry)) {
117 rc = PTR_ERR(dentry);
118 CERROR("cannot create LOGS directory: rc = %d\n", rc);
119 GOTO(exit, rc = -EINVAL);
122 S2SMI(sb)->smsi_logs_dir = dentry;
123 dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777, 1);
124 if (IS_ERR(dentry)) {
125 rc = PTR_ERR(dentry);
126 CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
127 GOTO(exit, rc = -EINVAL);
130 S2SMI(sb)->smsi_objects_dir = dentry;
132 /* write log will not write to KML, cleanup kml flags */
133 SMFS_CLEAN_INODE_REC(S2SMI(sb)->smsi_objects_dir->d_inode);
134 SMFS_CLEAN_INODE_REC(S2SMI(sb)->smsi_logs_dir->d_inode);
136 /* log create does not call cache hooks, cleanup hook flags */
137 SMFS_CLEAN_INODE_CACHE_HOOK(S2SMI(sb)->smsi_objects_dir->d_inode);
138 SMFS_CLEAN_INODE_CACHE_HOOK(S2SMI(sb)->smsi_logs_dir->d_inode);
140 if (SMFS_DO_REC(S2SMI(sb))) {
142 rc = llog_catalog_setup(ctxt, KML_LOG_NAME, S2SMI(sb)->smsi_exp,
143 current_ctxt, S2SMI(sb)->sm_fsfilt,
144 S2SMI(sb)->smsi_logs_dir,
145 S2SMI(sb)->smsi_objects_dir);
146 (*ctxt)->llog_proc_cb = smfs_llog_process_rec_cb;
149 if (SMFS_CACHE_HOOK(S2SMI(sb))) {
150 rc2 = cache_space_hook_setup(sb);
155 pop_ctxt(&saved, current_ctxt, NULL);
156 if (current_ctxt && rc)
157 OBD_FREE(current_ctxt, sizeof(*current_ctxt));
161 int smfs_llog_cleanup(struct super_block *sb)
163 struct llog_ctxt *ctxt = S2SMI(sb)->smsi_rec_log;
167 if (SMFS_CACHE_HOOK(S2SMI(sb)))
168 rc = cache_space_hook_cleanup();
170 if (SMFS_DO_REC(S2SMI(sb))) {
171 rc2 = llog_catalog_cleanup(ctxt);
172 OBD_FREE(ctxt, sizeof(*ctxt));
177 if (S2SMI(sb)->smsi_logs_dir) {
178 l_dput(S2SMI(sb)->smsi_logs_dir);
179 S2SMI(sb)->smsi_logs_dir = NULL;
181 if (S2SMI(sb)->smsi_objects_dir) {
182 l_dput(S2SMI(sb)->smsi_objects_dir);
183 S2SMI(sb)->smsi_objects_dir = NULL;
186 OBD_FREE(S2SMI(sb)->smsi_ctxt, sizeof(struct lvfs_run_ctxt));
190 int smfs_llog_add_rec(struct smfs_super_info * sinfo, void *data, int data_size)
192 struct llog_rec_hdr rec;
195 rec.lrh_len = size_round(data_size);
196 rec.lrh_type = SMFS_UPDATE_REC;
198 rc = llog_add(sinfo->smsi_rec_log, &rec, data, NULL, 0, NULL);
200 CERROR("error adding kml rec: %d\n", rc);