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, 2012, 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 <obd_class.h>
47 #include <lustre_log.h>
48 #include <lustre_net.h>
49 #include <lustre_fsfilt.h>
51 #if defined(LUSTRE_LOG_SERVER)
52 static int llog_origin_close(const struct lu_env *env, struct llog_handle *lgh)
54 if (lgh->lgh_hdr != NULL && lgh->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
55 return llog_cat_close(env, lgh);
57 return llog_close(env, lgh);
60 /* Only open is supported, no new llog can be created remotely */
61 int llog_origin_handle_open(struct ptlrpc_request *req)
63 struct obd_export *exp = req->rq_export;
64 struct obd_device *obd = exp->exp_obd;
65 struct obd_device *disk_obd;
66 struct lvfs_run_ctxt saved;
67 struct llog_handle *loghandle;
68 struct llogd_body *body;
69 struct llog_logid *logid = NULL;
70 struct llog_ctxt *ctxt;
74 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
78 if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
79 logid = &body->lgd_logid;
81 if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
82 name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
85 CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
88 ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
90 CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
91 obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
94 disk_obd = ctxt->loc_exp->exp_obd;
95 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
97 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid,
98 name, LLOG_OPEN_EXISTS);
102 rc = req_capsule_server_pack(&req->rq_pill);
104 GOTO(out_close, rc = -ENOMEM);
106 body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
107 body->lgd_logid = loghandle->lgh_id;
110 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
112 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
116 EXPORT_SYMBOL(llog_origin_handle_open);
118 int llog_origin_handle_destroy(struct ptlrpc_request *req)
120 struct obd_device *disk_obd;
121 struct lvfs_run_ctxt saved;
122 struct llogd_body *body;
123 struct llog_logid *logid = NULL;
124 struct llog_ctxt *ctxt;
127 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
131 if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
132 logid = &body->lgd_logid;
134 if (!(body->lgd_llh_flags & LLOG_F_IS_PLAIN))
135 CERROR("%s: wrong llog flags %x\n",
136 req->rq_export->exp_obd->obd_name, body->lgd_llh_flags);
138 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
142 disk_obd = ctxt->loc_exp->exp_obd;
143 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
145 rc = req_capsule_server_pack(&req->rq_pill);
146 /* erase only if no error and logid is valid */
148 rc = llog_erase(req->rq_svc_thread->t_env, ctxt, logid, NULL);
149 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
153 EXPORT_SYMBOL(llog_origin_handle_destroy);
155 int llog_origin_handle_next_block(struct ptlrpc_request *req)
157 struct obd_device *disk_obd;
158 struct llog_handle *loghandle;
159 struct llogd_body *body;
160 struct llogd_body *repbody;
161 struct lvfs_run_ctxt saved;
162 struct llog_ctxt *ctxt;
167 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
171 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
175 disk_obd = ctxt->loc_exp->exp_obd;
176 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
178 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
179 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
183 flags = body->lgd_llh_flags;
184 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
189 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
191 rc = req_capsule_server_pack(&req->rq_pill);
193 GOTO(out_close, rc = -ENOMEM);
195 repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
198 ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
199 rc = llog_next_block(req->rq_svc_thread->t_env, loghandle,
200 &repbody->lgd_saved_index, repbody->lgd_index,
201 &repbody->lgd_cur_offset, ptr, LLOG_CHUNK_SIZE);
205 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
207 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
211 EXPORT_SYMBOL(llog_origin_handle_next_block);
213 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
215 struct llog_handle *loghandle;
216 struct llogd_body *body;
217 struct llogd_body *repbody;
218 struct obd_device *disk_obd;
219 struct lvfs_run_ctxt saved;
220 struct llog_ctxt *ctxt;
225 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
229 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
233 disk_obd = ctxt->loc_exp->exp_obd;
234 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
236 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
237 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
241 flags = body->lgd_llh_flags;
242 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
247 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
249 rc = req_capsule_server_pack(&req->rq_pill);
251 GOTO(out_close, rc = -ENOMEM);
253 repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
256 ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
257 rc = llog_prev_block(req->rq_svc_thread->t_env, loghandle,
258 body->lgd_index, ptr, LLOG_CHUNK_SIZE);
263 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
265 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
269 EXPORT_SYMBOL(llog_origin_handle_prev_block);
271 int llog_origin_handle_read_header(struct ptlrpc_request *req)
273 struct obd_device *disk_obd;
274 struct llog_handle *loghandle;
275 struct llogd_body *body;
276 struct llog_log_hdr *hdr;
277 struct lvfs_run_ctxt saved;
278 struct llog_ctxt *ctxt;
282 body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
286 ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
290 disk_obd = ctxt->loc_exp->exp_obd;
291 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
293 rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
294 &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
299 * llog_init_handle() reads the llog header
301 flags = body->lgd_llh_flags;
302 rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
306 flags = loghandle->lgh_hdr->llh_flags;
308 rc = req_capsule_server_pack(&req->rq_pill);
310 GOTO(out_close, rc = -ENOMEM);
312 hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
313 *hdr = *loghandle->lgh_hdr;
315 llog_origin_close(req->rq_svc_thread->t_env, loghandle);
317 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
321 EXPORT_SYMBOL(llog_origin_handle_read_header);
323 int llog_origin_handle_close(struct ptlrpc_request *req)
328 EXPORT_SYMBOL(llog_origin_handle_close);
330 int llog_origin_handle_cancel(struct ptlrpc_request *req)
332 int num_cookies, rc = 0, err, i, failed = 0;
333 struct obd_device *disk_obd;
334 struct llog_cookie *logcookies;
335 struct llog_ctxt *ctxt = NULL;
336 struct lvfs_run_ctxt saved;
337 struct llog_handle *cathandle;
341 logcookies = req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES);
342 num_cookies = req_capsule_get_size(&req->rq_pill, &RMF_LOGCOOKIES,
343 RCL_CLIENT) / sizeof(*logcookies);
344 if (logcookies == NULL || num_cookies == 0) {
345 DEBUG_REQ(D_HA, req, "No llog cookies sent");
349 ctxt = llog_get_context(req->rq_export->exp_obd,
350 logcookies->lgc_subsys);
354 disk_obd = ctxt->loc_exp->exp_obd;
355 push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
356 for (i = 0; i < num_cookies; i++, logcookies++) {
357 cathandle = ctxt->loc_handle;
358 LASSERT(cathandle != NULL);
359 inode = cathandle->lgh_file->f_dentry->d_inode;
361 handle = fsfilt_start_log(disk_obd, inode,
362 FSFILT_OP_CANCEL_UNLINK, NULL, 1);
363 if (IS_ERR(handle)) {
364 CERROR("fsfilt_start_log() failed: %ld\n",
366 GOTO(pop_ctxt, rc = PTR_ERR(handle));
369 rc = llog_cat_cancel_records(req->rq_svc_thread->t_env,
370 cathandle, 1, logcookies);
373 * Do not raise -ENOENT errors for resent rpcs. This rec already
377 (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT)) {
379 * Do not change this message, reply-single.sh test_59b
380 * expects to find this in log.
382 CDEBUG(D_RPCTRACE, "RESENT cancel req %p - ignored\n",
385 } else if (rc == 0) {
386 CDEBUG(D_RPCTRACE, "Canceled %d llog-records\n",
390 err = fsfilt_commit(disk_obd, inode, handle, 0);
392 CERROR("Error committing transaction: %d\n", err);
402 pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
404 CERROR("Cancel %d of %d llog-records failed: %d\n",
405 failed, num_cookies, rc);
410 EXPORT_SYMBOL(llog_origin_handle_cancel);
412 #else /* !__KERNEL__ */
413 int llog_origin_handle_open(struct ptlrpc_request *req)
419 int llog_origin_handle_destroy(struct ptlrpc_request *req)
425 int llog_origin_handle_next_block(struct ptlrpc_request *req)
430 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
435 int llog_origin_handle_read_header(struct ptlrpc_request *req)
440 int llog_origin_handle_close(struct ptlrpc_request *req)
445 int llog_origin_handle_cancel(struct ptlrpc_request *req)