]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/staging/lustre/lustre/obdclass/llog_cat.c
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2012, 2015, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/obdclass/llog_cat.c
34 * OST<->MDS recovery logging infrastructure.
36 * Invariants in implementation:
37 * - we do not share logs among different OST<->MDS connections, so that
38 * if an OST or MDS fails it need only look at log(s) relevant to itself
40 * Author: Andreas Dilger <adilger@clusterfs.com>
41 * Author: Alexey Zhuravlev <alexey.zhuravlev@intel.com>
42 * Author: Mikhail Pershin <mike.pershin@intel.com>
45 #define DEBUG_SUBSYSTEM S_LOG
47 #include "../include/obd_class.h"
49 #include "llog_internal.h"
51 /* Open an existent log handle and add it to the open list.
52 * This log handle will be closed when all of the records in it are removed.
54 * Assumes caller has already pushed us into the kernel context and is locking.
55 * We return a lock on the handle to ensure nobody yanks it from us.
57 * This takes extra reference on llog_handle via llog_handle_get() and require
58 * this reference to be put by caller using llog_handle_put()
60 static int llog_cat_id2handle(const struct lu_env
*env
,
61 struct llog_handle
*cathandle
,
62 struct llog_handle
**res
,
63 struct llog_logid
*logid
)
65 struct llog_handle
*loghandle
;
72 fmt
= cathandle
->lgh_hdr
->llh_flags
& LLOG_F_EXT_MASK
;
73 down_write(&cathandle
->lgh_lock
);
74 list_for_each_entry(loghandle
, &cathandle
->u
.chd
.chd_head
,
76 struct llog_logid
*cgl
= &loghandle
->lgh_id
;
78 if (ostid_id(&cgl
->lgl_oi
) == ostid_id(&logid
->lgl_oi
) &&
79 ostid_seq(&cgl
->lgl_oi
) == ostid_seq(&logid
->lgl_oi
)) {
80 if (cgl
->lgl_ogen
!= logid
->lgl_ogen
) {
81 CERROR("%s: log " DOSTID
" generation %x != %x\n",
82 loghandle
->lgh_ctxt
->loc_obd
->obd_name
,
83 POSTID(&logid
->lgl_oi
), cgl
->lgl_ogen
,
87 loghandle
->u
.phd
.phd_cat_handle
= cathandle
;
88 up_write(&cathandle
->lgh_lock
);
93 up_write(&cathandle
->lgh_lock
);
95 rc
= llog_open(env
, cathandle
->lgh_ctxt
, &loghandle
, logid
, NULL
,
98 CERROR("%s: error opening log id " DOSTID
":%x: rc = %d\n",
99 cathandle
->lgh_ctxt
->loc_obd
->obd_name
,
100 POSTID(&logid
->lgl_oi
), logid
->lgl_ogen
, rc
);
104 rc
= llog_init_handle(env
, loghandle
, fmt
| LLOG_F_IS_PLAIN
, NULL
);
106 llog_close(env
, loghandle
);
111 down_write(&cathandle
->lgh_lock
);
112 list_add_tail(&loghandle
->u
.phd
.phd_entry
, &cathandle
->u
.chd
.chd_head
);
113 up_write(&cathandle
->lgh_lock
);
115 loghandle
->u
.phd
.phd_cat_handle
= cathandle
;
116 loghandle
->u
.phd
.phd_cookie
.lgc_lgl
= cathandle
->lgh_id
;
117 loghandle
->u
.phd
.phd_cookie
.lgc_index
=
118 loghandle
->lgh_hdr
->llh_cat_idx
;
120 llog_handle_get(loghandle
);
125 int llog_cat_close(const struct lu_env
*env
, struct llog_handle
*cathandle
)
127 struct llog_handle
*loghandle
, *n
;
129 list_for_each_entry_safe(loghandle
, n
, &cathandle
->u
.chd
.chd_head
,
131 /* unlink open-not-created llogs */
132 list_del_init(&loghandle
->u
.phd
.phd_entry
);
133 llog_close(env
, loghandle
);
135 /* if handle was stored in ctxt, remove it too */
136 if (cathandle
->lgh_ctxt
->loc_handle
== cathandle
)
137 cathandle
->lgh_ctxt
->loc_handle
= NULL
;
138 return llog_close(env
, cathandle
);
140 EXPORT_SYMBOL(llog_cat_close
);
142 static int llog_cat_process_cb(const struct lu_env
*env
,
143 struct llog_handle
*cat_llh
,
144 struct llog_rec_hdr
*rec
, void *data
)
146 struct llog_process_data
*d
= data
;
147 struct llog_logid_rec
*lir
= (struct llog_logid_rec
*)rec
;
148 struct llog_handle
*llh
;
151 if (rec
->lrh_type
!= LLOG_LOGID_MAGIC
) {
152 CERROR("invalid record in catalog\n");
155 CDEBUG(D_HA
, "processing log " DOSTID
":%x at index %u of catalog "
156 DOSTID
"\n", POSTID(&lir
->lid_id
.lgl_oi
), lir
->lid_id
.lgl_ogen
,
157 rec
->lrh_index
, POSTID(&cat_llh
->lgh_id
.lgl_oi
));
159 rc
= llog_cat_id2handle(env
, cat_llh
, &llh
, &lir
->lid_id
);
161 CERROR("%s: cannot find handle for llog " DOSTID
": %d\n",
162 cat_llh
->lgh_ctxt
->loc_obd
->obd_name
,
163 POSTID(&lir
->lid_id
.lgl_oi
), rc
);
167 if (rec
->lrh_index
< d
->lpd_startcat
)
168 /* Skip processing of the logs until startcat */
170 else if (d
->lpd_startidx
> 0) {
171 struct llog_process_cat_data cd
;
173 cd
.lpcd_first_idx
= d
->lpd_startidx
;
174 cd
.lpcd_last_idx
= 0;
175 rc
= llog_process_or_fork(env
, llh
, d
->lpd_cb
, d
->lpd_data
,
177 /* Continue processing the next log from idx 0 */
180 rc
= llog_process_or_fork(env
, llh
, d
->lpd_cb
, d
->lpd_data
,
184 llog_handle_put(llh
);
189 static int llog_cat_process_or_fork(const struct lu_env
*env
,
190 struct llog_handle
*cat_llh
,
191 llog_cb_t cb
, void *data
, int startcat
,
192 int startidx
, bool fork
)
194 struct llog_process_data d
;
195 struct llog_log_hdr
*llh
= cat_llh
->lgh_hdr
;
198 LASSERT(llh
->llh_flags
& LLOG_F_IS_CAT
);
201 d
.lpd_startcat
= startcat
;
202 d
.lpd_startidx
= startidx
;
204 if (llh
->llh_cat_idx
> cat_llh
->lgh_last_idx
) {
205 struct llog_process_cat_data cd
;
207 CWARN("catlog " DOSTID
" crosses index zero\n",
208 POSTID(&cat_llh
->lgh_id
.lgl_oi
));
210 cd
.lpcd_first_idx
= llh
->llh_cat_idx
;
211 cd
.lpcd_last_idx
= 0;
212 rc
= llog_process_or_fork(env
, cat_llh
, llog_cat_process_cb
,
217 cd
.lpcd_first_idx
= 0;
218 cd
.lpcd_last_idx
= cat_llh
->lgh_last_idx
;
219 rc
= llog_process_or_fork(env
, cat_llh
, llog_cat_process_cb
,
222 rc
= llog_process_or_fork(env
, cat_llh
, llog_cat_process_cb
,
229 int llog_cat_process(const struct lu_env
*env
, struct llog_handle
*cat_llh
,
230 llog_cb_t cb
, void *data
, int startcat
, int startidx
)
232 return llog_cat_process_or_fork(env
, cat_llh
, cb
, data
, startcat
,
235 EXPORT_SYMBOL(llog_cat_process
);