1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2005 Cluster File Systems, Inc.
6 * This file is part of the Lustre file system, http://www.lustre.org
7 * Lustre is a trademark of Cluster File Systems, Inc.
9 * You may have signed or agreed to another license before downloading
10 * this software. If so, you are bound by the terms and conditions
11 * of that agreement, and the following does not apply to you. See the
12 * LICENSE file included with this distribution for more information.
14 * If you did not agree to a different license, then this copy of Lustre
15 * is open source software; you can redistribute it and/or modify it
16 * under the terms of version 2 of the GNU General Public License as
17 * published by the Free Software Foundation.
19 * In either case, Lustre is distributed in the hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
21 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * license text for more details.
25 #define DEBUG_SUBSYSTEM S_LOG
32 #include <liblustre.h>
35 #include <obd_class.h>
36 #include <lustre_log.h>
37 #include <libcfs/list.h>
38 #include "llog_internal.h"
40 /* helper functions for calling the llog obd methods */
42 int llog_cleanup(struct llog_ctxt *ctxt)
52 if (CTXTP(ctxt, cleanup))
53 rc = CTXTP(ctxt, cleanup)(ctxt);
55 ctxt->loc_obd->obd_llog_ctxt[ctxt->loc_idx] = NULL;
57 class_export_put(ctxt->loc_exp);
58 OBD_FREE(ctxt, sizeof(*ctxt));
62 EXPORT_SYMBOL(llog_cleanup);
64 int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd,
65 int count, struct llog_logid *logid, struct llog_operations *op)
68 struct llog_ctxt *ctxt;
71 if (index < 0 || index >= LLOG_MAX_CTXTS)
74 if (obd->obd_llog_ctxt[index]) {
75 /* During an mds_lov_add_ost, we try to tear down and resetup llogs.
76 But the mdt teardown does not flow down to the lov/osc's as the
77 setup does, because the lov/osc must clean up only when they are
78 done, not when the mdt is done. So instead, we just assume that
79 if the lov llogs are already set up then we must cleanup first. */
80 CDEBUG(D_CONFIG, "obd %s ctxt %d already set up\n",
81 obd->obd_name, index);
82 llog_cleanup(obd->obd_llog_ctxt[index]);
85 OBD_ALLOC(ctxt, sizeof(*ctxt));
89 obd->obd_llog_ctxt[index] = ctxt;
91 ctxt->loc_exp = class_export_get(disk_obd->obd_self_export);
92 ctxt->loc_idx = index;
93 ctxt->loc_logops = op;
94 sema_init(&ctxt->loc_sem, 1);
97 rc = op->lop_setup(obd, index, disk_obd, count, logid);
101 EXPORT_SYMBOL(llog_setup);
103 int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp)
111 if (CTXTP(ctxt, sync))
112 rc = CTXTP(ctxt, sync)(ctxt, exp);
116 EXPORT_SYMBOL(llog_sync);
118 int llog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
119 struct lov_stripe_md *lsm, struct llog_cookie *logcookies,
130 CTXT_CHECK_OP(ctxt, add, -EOPNOTSUPP);
132 rc = CTXTP(ctxt, add)(ctxt, rec, lsm, logcookies, numcookies);
135 EXPORT_SYMBOL(llog_add);
137 int llog_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
138 int count, struct llog_cookie *cookies, int flags)
148 CTXT_CHECK_OP(ctxt, cancel, -EOPNOTSUPP);
149 rc = CTXTP(ctxt, cancel)(ctxt, lsm, count, cookies, flags);
152 EXPORT_SYMBOL(llog_cancel);
154 /* callback func for llog_process in llog_obd_origin_setup */
155 static int cat_cancel_cb(struct llog_handle *cathandle,
156 struct llog_rec_hdr *rec, void *data)
158 struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
159 struct llog_handle *loghandle;
160 struct llog_log_hdr *llh;
164 if (rec->lrh_type != LLOG_LOGID_MAGIC) {
165 CERROR("invalid record in catalog\n");
168 CWARN("processing log "LPX64":%x at index %u of catalog "LPX64"\n",
169 lir->lid_id.lgl_oid, lir->lid_id.lgl_ogen,
170 rec->lrh_index, cathandle->lgh_id.lgl_oid);
172 rc = llog_cat_id2handle(cathandle, &loghandle, &lir->lid_id);
174 CERROR("Cannot find handle for log "LPX64"\n",
175 lir->lid_id.lgl_oid);
179 llh = loghandle->lgh_hdr;
180 if ((llh->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) &&
181 (llh->llh_count == 1)) {
182 rc = llog_destroy(loghandle);
184 CERROR("failure destroying log in postsetup: %d\n", rc);
186 index = loghandle->u.phd.phd_cookie.lgc_index;
187 llog_free_handle(loghandle);
190 llog_cat_set_first_idx(cathandle, index);
191 rc = llog_cancel_rec(cathandle, index);
193 CWARN("cancel log "LPX64":%x at index %u of catalog "
194 LPX64"\n", lir->lid_id.lgl_oid,
195 lir->lid_id.lgl_ogen, rec->lrh_index,
196 cathandle->lgh_id.lgl_oid);
202 /* lop_setup method for filter/osc */
203 // XXX how to set exports
204 int llog_obd_origin_setup(struct obd_device *obd, int index,
205 struct obd_device *disk_obd, int count,
206 struct llog_logid *logid)
208 struct llog_ctxt *ctxt;
209 struct llog_handle *handle;
210 struct lvfs_run_ctxt saved;
219 ctxt = llog_get_context(obd, index);
224 rc = llog_create(ctxt, &handle, logid, NULL);
226 rc = llog_create(ctxt, &handle, NULL, NULL);
228 *logid = handle->lgh_id;
233 ctxt->loc_handle = handle;
234 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
235 rc = llog_init_handle(handle, LLOG_F_IS_CAT, NULL);
236 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
240 rc = llog_process(handle, (llog_cb_t)cat_cancel_cb, NULL, NULL);
242 CERROR("llog_process with cat_cancel_cb failed: %d\n", rc);
245 obd->obd_llog_ctxt[index] = NULL;
246 OBD_FREE(ctxt, sizeof(*ctxt));
250 EXPORT_SYMBOL(llog_obd_origin_setup);
252 int llog_obd_origin_cleanup(struct llog_ctxt *ctxt)
254 struct llog_handle *cathandle, *n, *loghandle;
255 struct llog_log_hdr *llh;
262 cathandle = ctxt->loc_handle;
264 list_for_each_entry_safe(loghandle, n,
265 &cathandle->u.chd.chd_head,
267 llh = loghandle->lgh_hdr;
268 if ((llh->llh_flags &
269 LLOG_F_ZAP_WHEN_EMPTY) &&
270 (llh->llh_count == 1)) {
271 rc = llog_destroy(loghandle);
273 CERROR("failure destroying log during "
274 "cleanup: %d\n", rc);
276 index = loghandle->u.phd.phd_cookie.lgc_index;
277 llog_free_handle(loghandle);
280 llog_cat_set_first_idx(cathandle, index);
281 rc = llog_cancel_rec(cathandle, index);
283 CDEBUG(D_HA, "cancel plain log at index"
284 " %u of catalog "LPX64"\n",
285 index,cathandle->lgh_id.lgl_oid);
288 llog_cat_put(ctxt->loc_handle);
292 EXPORT_SYMBOL(llog_obd_origin_cleanup);
294 /* add for obdfilter/sz and mds/unlink */
295 int llog_obd_origin_add(struct llog_ctxt *ctxt,
296 struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
297 struct llog_cookie *logcookies, int numcookies)
299 struct llog_handle *cathandle;
303 cathandle = ctxt->loc_handle;
304 LASSERT(cathandle != NULL);
305 rc = llog_cat_add_rec(cathandle, rec, logcookies, NULL);
307 CERROR("write one catalog record failed: %d\n", rc);
310 EXPORT_SYMBOL(llog_obd_origin_add);
312 int llog_cat_initialize(struct obd_device *obd, int count)
314 struct llog_catid *idarray;
315 int size = sizeof(*idarray) * count;
316 char name[32] = CATLIST;
320 OBD_ALLOC(idarray, size);
324 rc = llog_get_cat_list(obd, obd, name, count, idarray);
326 CERROR("rc: %d\n", rc);
330 rc = obd_llog_init(obd, obd, count, idarray);
332 CERROR("rc: %d\n", rc);
336 rc = llog_put_cat_list(obd, obd, name, count, idarray);
338 CERROR("rc: %d\n", rc);
343 OBD_FREE(idarray, size);
346 EXPORT_SYMBOL(llog_cat_initialize);
348 int obd_llog_init(struct obd_device *obd, struct obd_device *disk_obd,
349 int count, struct llog_catid *logid)
353 OBD_CHECK_DT_OP(obd, llog_init, 0);
354 OBD_COUNTER_INCREMENT(obd, llog_init);
356 rc = OBP(obd, llog_init)(obd, disk_obd, count, logid);
359 EXPORT_SYMBOL(obd_llog_init);
361 int obd_llog_finish(struct obd_device *obd, int count)
365 OBD_CHECK_DT_OP(obd, llog_finish, 0);
366 OBD_COUNTER_INCREMENT(obd, llog_finish);
368 rc = OBP(obd, llog_finish)(obd, count);
371 EXPORT_SYMBOL(obd_llog_finish);