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.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2013, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/ptlrpc/llog_server.c
38 * remote api for llog - server side
40 * Author: Andreas Dilger <adilger@clusterfs.com>
43 #define DEBUG_SUBSYSTEM S_LOG
46 #include <liblustre.h>
49 #include <obd_class.h>
50 #include <lustre_log.h>
51 #include <lustre_net.h>
52 #include <lustre_fsfilt.h>
54 #if defined(__KERNEL__) && defined(LUSTRE_LOG_SERVER)
55 static int llog_origin_close(const struct lu_env *env, struct llog_handle *lgh)
57 if (lgh->lgh_hdr != NULL && lgh->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
58 return llog_cat_close(env, lgh);
60 return llog_close(env, lgh);
63 /* Only open is supported, no new llog can be created remotely */
64 int llog_origin_handle_open(struct ptlrpc_request *req)
66 struct obd_export *exp = req->rq_export;
67 struct obd_device *obd = exp->exp_obd;
68 struct obd_device *disk_obd;
69 struct lvfs_run_ctxt saved;
70 struct llog_handle *loghandle;
71 struct llogd_body *body;
72 struct llog_logid *logid = NULL;
73 struct llog_ctxt *ctxt;
79 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
83 if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
84 logid = &body->lgd_logid;
86 if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
87 name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
90 CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
93 ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
95 CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
96 obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
99 disk_obd = ctxt->loc_exp->exp_obd;
100 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
102 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid,
103 name, LLOG_OPEN_EXISTS);
107 rc = req_capsule_server_pack(&req->rq_pill);
109 GOTO(out_close, rc = -ENOMEM);
111 body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
112 body->lgd_logid = loghandle->lgh_id;
116 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
118 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
122 EXPORT_SYMBOL(llog_origin_handle_open);
124 int llog_origin_handle_destroy(struct ptlrpc_request *req)
126 struct obd_device *disk_obd;
127 struct lvfs_run_ctxt saved;
128 struct llogd_body *body;
129 struct llog_logid *logid = NULL;
130 struct llog_ctxt *ctxt;
135 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
139 if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
140 logid = &body->lgd_logid;
142 if (!(body->lgd_llh_flags & LLOG_F_IS_PLAIN))
143 CERROR("%s: wrong llog flags %x\n",
144 req->rq_export->exp_obd->obd_name, body->lgd_llh_flags);
146 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
150 disk_obd = ctxt->loc_exp->exp_obd;
151 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
153 rc = req_capsule_server_pack(&req->rq_pill);
154 /* erase only if no error and logid is valid */
156 rc = llog_erase(req->rq_svc_thread->t_env, ctxt, logid, NULL);
157 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
161 EXPORT_SYMBOL(llog_origin_handle_destroy);
163 int llog_origin_handle_next_block(struct ptlrpc_request *req)
165 struct obd_device *disk_obd;
166 struct llog_handle *loghandle;
167 struct llogd_body *body;
168 struct llogd_body *repbody;
169 struct lvfs_run_ctxt saved;
170 struct llog_ctxt *ctxt;
177 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
181 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
185 disk_obd = ctxt->loc_exp->exp_obd;
186 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
188 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
189 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
193 flags = body->lgd_llh_flags;
194 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
199 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
201 rc = req_capsule_server_pack(&req->rq_pill);
203 GOTO(out_close, rc = -ENOMEM);
205 repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
208 ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
209 rc = llog_next_block(req->rq_svc_thread->t_env, loghandle,
210 &repbody->lgd_saved_index, repbody->lgd_index,
211 &repbody->lgd_cur_offset, ptr, LLOG_CHUNK_SIZE);
216 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
218 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
222 EXPORT_SYMBOL(llog_origin_handle_next_block);
224 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
226 struct llog_handle *loghandle;
227 struct llogd_body *body;
228 struct llogd_body *repbody;
229 struct obd_device *disk_obd;
230 struct lvfs_run_ctxt saved;
231 struct llog_ctxt *ctxt;
238 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
242 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
246 disk_obd = ctxt->loc_exp->exp_obd;
247 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
249 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
250 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
254 flags = body->lgd_llh_flags;
255 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
260 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
262 rc = req_capsule_server_pack(&req->rq_pill);
264 GOTO(out_close, rc = -ENOMEM);
266 repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
269 ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
270 rc = llog_prev_block(req->rq_svc_thread->t_env, loghandle,
271 body->lgd_index, ptr, LLOG_CHUNK_SIZE);
277 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
279 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
283 EXPORT_SYMBOL(llog_origin_handle_prev_block);
285 int llog_origin_handle_read_header(struct ptlrpc_request *req)
287 struct obd_device *disk_obd;
288 struct llog_handle *loghandle;
289 struct llogd_body *body;
290 struct llog_log_hdr *hdr;
291 struct lvfs_run_ctxt saved;
292 struct llog_ctxt *ctxt;
298 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
302 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
306 disk_obd = ctxt->loc_exp->exp_obd;
307 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
309 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
310 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
315 * llog_init_handle() reads the llog header
317 flags = body->lgd_llh_flags;
318 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
322 flags = loghandle->lgh_hdr->llh_flags;
324 rc = req_capsule_server_pack(&req->rq_pill);
326 GOTO(out_close, rc = -ENOMEM);
328 hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
329 *hdr = *loghandle->lgh_hdr;
332 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
334 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
338 EXPORT_SYMBOL(llog_origin_handle_read_header);
340 int llog_origin_handle_close(struct ptlrpc_request *req)
346 EXPORT_SYMBOL(llog_origin_handle_close);
348 int llog_origin_handle_cancel(struct ptlrpc_request *req)
350 int num_cookies, rc = 0, err, i, failed = 0;
351 struct obd_device *disk_obd;
352 struct llog_cookie *logcookies;
353 struct llog_ctxt *ctxt = NULL;
354 struct lvfs_run_ctxt saved;
355 struct llog_handle *cathandle;
360 logcookies = req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES);
361 num_cookies = req_capsule_get_size(&req->rq_pill, &RMF_LOGCOOKIES,
362 RCL_CLIENT) / sizeof(*logcookies);
363 if (logcookies == NULL || num_cookies == 0) {
364 DEBUG_REQ(D_HA, req, "No llog cookies sent");
368 ctxt = llog_get_context(req->rq_export->exp_obd,
369 logcookies->lgc_subsys);
373 disk_obd = ctxt->loc_exp->exp_obd;
374 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
375 for (i = 0; i < num_cookies; i++, logcookies++) {
376 cathandle = ctxt->loc_handle;
377 LASSERT(cathandle != NULL);
378 inode = cathandle->lgh_file->f_dentry->d_inode;
380 handle = fsfilt_start_log(disk_obd, inode,
381 FSFILT_OP_CANCEL_UNLINK, NULL, 1);
382 if (IS_ERR(handle)) {
383 CERROR("fsfilt_start_log() failed: %ld\n",
385 GOTO(pop_ctxt, rc = PTR_ERR(handle));
388 rc = llog_cat_cancel_records(req->rq_svc_thread->t_env,
389 cathandle, 1, logcookies);
392 * Do not raise -ENOENT errors for resent rpcs. This rec already
396 (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT)) {
398 * Do not change this message, reply-single.sh test_59b
399 * expects to find this in log.
401 CDEBUG(D_RPCTRACE, "RESENT cancel req %p - ignored\n",
404 } else if (rc == 0) {
405 CDEBUG(D_RPCTRACE, "Canceled %d llog-records\n",
409 err = fsfilt_commit(disk_obd, inode, handle, 0);
411 CERROR("Error committing transaction: %d\n", err);
421 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
423 CERROR("Cancel %d of %d llog-records failed: %d\n",
424 failed, num_cookies, rc);
429 EXPORT_SYMBOL(llog_origin_handle_cancel);
431 #else /* !__KERNEL__ */
432 int llog_origin_handle_open(struct ptlrpc_request *req)
438 int llog_origin_handle_destroy(struct ptlrpc_request *req)
444 int llog_origin_handle_next_block(struct ptlrpc_request *req)
449 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
454 int llog_origin_handle_read_header(struct ptlrpc_request *req)
459 int llog_origin_handle_close(struct ptlrpc_request *req)
464 int llog_origin_handle_cancel(struct ptlrpc_request *req)