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
34 #include <liblustre.h>
37 #include <linux/obd_class.h>
38 #include <linux/lustre_log.h>
39 #include <libcfs/list.h>
40 #include "llog_internal.h"
42 /* helper functions for calling the llog obd methods */
44 int llog_cleanup(struct llog_ctxt *ctxt)
54 if (CTXTP(ctxt, cleanup))
55 rc = CTXTP(ctxt, cleanup)(ctxt);
57 ctxt->loc_obd->obd_llog_ctxt[ctxt->loc_idx] = NULL;
59 class_export_put(ctxt->loc_exp);
60 OBD_FREE(ctxt, sizeof(*ctxt));
64 EXPORT_SYMBOL(llog_cleanup);
66 int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd,
67 int count, struct llog_logid *logid, struct llog_operations *op)
70 struct llog_ctxt *ctxt;
73 if (index < 0 || index >= LLOG_MAX_CTXTS)
76 if (obd->obd_llog_ctxt[index]) {
77 /* During an mds_lov_add_ost, we try to tear down and resetup llogs.
78 But the mdt teardown does not flow down to the lov/osc's as the
79 setup does, because the lov/osc must clean up only when they are
80 done, not when the mdt is done. So instead, we just assume that
81 if the lov llogs are already set up then we must cleanup first. */
82 CDEBUG(D_CONFIG, "obd %s ctxt %d already set up\n",
83 obd->obd_name, index);
84 llog_cleanup(obd->obd_llog_ctxt[index]);
87 OBD_ALLOC(ctxt, sizeof(*ctxt));
91 obd->obd_llog_ctxt[index] = ctxt;
93 ctxt->loc_exp = class_export_get(disk_obd->obd_self_export);
94 ctxt->loc_idx = index;
95 ctxt->loc_logops = op;
96 sema_init(&ctxt->loc_sem, 1);
99 rc = op->lop_setup(obd, index, disk_obd, count, logid);
103 EXPORT_SYMBOL(llog_setup);
105 int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp)
113 if (CTXTP(ctxt, sync))
114 rc = CTXTP(ctxt, sync)(ctxt, exp);
118 EXPORT_SYMBOL(llog_sync);
120 int llog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
121 struct lov_stripe_md *lsm, struct llog_cookie *logcookies,
132 CTXT_CHECK_OP(ctxt, add, -EOPNOTSUPP);
134 rc = CTXTP(ctxt, add)(ctxt, rec, lsm, logcookies, numcookies);
137 EXPORT_SYMBOL(llog_add);
139 int llog_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
140 int count, struct llog_cookie *cookies, int flags)
150 CTXT_CHECK_OP(ctxt, cancel, -EOPNOTSUPP);
151 rc = CTXTP(ctxt, cancel)(ctxt, lsm, count, cookies, flags);
154 EXPORT_SYMBOL(llog_cancel);
156 /* callback func for llog_process in llog_obd_origin_setup */
157 static int cat_cancel_cb(struct llog_handle *cathandle,
158 struct llog_rec_hdr *rec, void *data)
160 struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
161 struct llog_handle *loghandle;
162 struct llog_log_hdr *llh;
166 if (rec->lrh_type != LLOG_LOGID_MAGIC) {
167 CERROR("invalid record in catalog\n");
170 CWARN("processing log "LPX64":%x at index %u of catalog "LPX64"\n",
171 lir->lid_id.lgl_oid, lir->lid_id.lgl_ogen,
172 rec->lrh_index, cathandle->lgh_id.lgl_oid);
174 rc = llog_cat_id2handle(cathandle, &loghandle, &lir->lid_id);
176 CERROR("Cannot find handle for log "LPX64"\n",
177 lir->lid_id.lgl_oid);
181 llh = loghandle->lgh_hdr;
182 if ((llh->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) &&
183 (llh->llh_count == 1)) {
184 rc = llog_destroy(loghandle);
186 CERROR("failure destroying log in postsetup: %d\n", rc);
188 index = loghandle->u.phd.phd_cookie.lgc_index;
189 llog_free_handle(loghandle);
192 llog_cat_set_first_idx(cathandle, index);
193 rc = llog_cancel_rec(cathandle, index);
195 CWARN("cancel log "LPX64":%x at index %u of catalog "
196 LPX64"\n", lir->lid_id.lgl_oid,
197 lir->lid_id.lgl_ogen, rec->lrh_index,
198 cathandle->lgh_id.lgl_oid);
204 /* lop_setup method for filter/osc */
205 // XXX how to set exports
206 int llog_obd_origin_setup(struct obd_device *obd, int index,
207 struct obd_device *disk_obd, int count,
208 struct llog_logid *logid)
210 struct llog_ctxt *ctxt;
211 struct llog_handle *handle;
212 struct lvfs_run_ctxt saved;
221 ctxt = llog_get_context(obd, index);
226 rc = llog_create(ctxt, &handle, logid, NULL);
228 rc = llog_create(ctxt, &handle, NULL, NULL);
230 *logid = handle->lgh_id;
235 ctxt->loc_handle = handle;
236 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
237 rc = llog_init_handle(handle, LLOG_F_IS_CAT, NULL);
238 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
242 rc = llog_process(handle, (llog_cb_t)cat_cancel_cb, NULL, NULL);
244 CERROR("llog_process with cat_cancel_cb failed: %d\n", rc);
247 obd->obd_llog_ctxt[index] = NULL;
248 OBD_FREE(ctxt, sizeof(*ctxt));
252 EXPORT_SYMBOL(llog_obd_origin_setup);
254 int llog_obd_origin_cleanup(struct llog_ctxt *ctxt)
256 struct llog_handle *cathandle, *n, *loghandle;
257 struct llog_log_hdr *llh;
264 cathandle = ctxt->loc_handle;
266 list_for_each_entry_safe(loghandle, n,
267 &cathandle->u.chd.chd_head,
269 llh = loghandle->lgh_hdr;
270 if ((llh->llh_flags &
271 LLOG_F_ZAP_WHEN_EMPTY) &&
272 (llh->llh_count == 1)) {
273 rc = llog_destroy(loghandle);
275 CERROR("failure destroying log during "
276 "cleanup: %d\n", rc);
278 index = loghandle->u.phd.phd_cookie.lgc_index;
279 llog_free_handle(loghandle);
282 llog_cat_set_first_idx(cathandle, index);
283 rc = llog_cancel_rec(cathandle, index);
285 CDEBUG(D_HA, "cancel plain log at index"
286 " %u of catalog "LPX64"\n",
287 index,cathandle->lgh_id.lgl_oid);
290 llog_cat_put(ctxt->loc_handle);
294 EXPORT_SYMBOL(llog_obd_origin_cleanup);
296 /* add for obdfilter/sz and mds/unlink */
297 int llog_obd_origin_add(struct llog_ctxt *ctxt,
298 struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
299 struct llog_cookie *logcookies, int numcookies)
301 struct llog_handle *cathandle;
305 cathandle = ctxt->loc_handle;
306 LASSERT(cathandle != NULL);
307 rc = llog_cat_add_rec(cathandle, rec, logcookies, NULL);
309 CERROR("write one catalog record failed: %d\n", rc);
312 EXPORT_SYMBOL(llog_obd_origin_add);
314 int llog_cat_initialize(struct obd_device *obd, int count)
316 struct llog_catid *idarray;
317 int size = sizeof(*idarray) * count;
318 char name[32] = CATLIST;
322 OBD_ALLOC(idarray, size);
326 rc = llog_get_cat_list(obd, obd, name, count, idarray);
328 CERROR("rc: %d\n", rc);
332 rc = obd_llog_init(obd, obd, count, idarray);
334 CERROR("rc: %d\n", rc);
338 rc = llog_put_cat_list(obd, obd, name, count, idarray);
340 CERROR("rc: %d\n", rc);
345 OBD_FREE(idarray, size);
348 EXPORT_SYMBOL(llog_cat_initialize);
350 int obd_llog_init(struct obd_device *obd, struct obd_device *disk_obd,
351 int count, struct llog_catid *logid)
355 OBD_CHECK_OP(obd, llog_init, 0);
356 OBD_COUNTER_INCREMENT(obd, llog_init);
358 rc = OBP(obd, llog_init)(obd, disk_obd, count, logid);
361 EXPORT_SYMBOL(obd_llog_init);
363 int obd_llog_finish(struct obd_device *obd, int count)
367 OBD_CHECK_OP(obd, llog_finish, 0);
368 OBD_COUNTER_INCREMENT(obd, llog_finish);
370 rc = OBP(obd, llog_finish)(obd, count);
373 EXPORT_SYMBOL(obd_llog_finish);