Whamcloud - gitweb
LU-5223 lmv: build master LMV EA dynamically build via readdir
[fs/lustre-release.git] / lustre / ptlrpc / llog_server.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
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
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2013, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/ptlrpc/llog_server.c
37  *
38  * remote api for llog - server side
39  *
40  * Author: Andreas Dilger <adilger@clusterfs.com>
41  */
42
43 #define DEBUG_SUBSYSTEM S_LOG
44
45 #ifndef __KERNEL__
46 #include <liblustre.h>
47 #endif
48
49 #include <obd_class.h>
50 #include <lu_target.h>
51 #include <lustre_log.h>
52 #include <lustre_net.h>
53
54 #if defined(__KERNEL__) && defined(LUSTRE_LOG_SERVER)
55 static int llog_origin_close(const struct lu_env *env, struct llog_handle *lgh)
56 {
57         if (lgh->lgh_hdr != NULL && lgh->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
58                 return llog_cat_close(env, lgh);
59         else
60                 return llog_close(env, lgh);
61 }
62
63 /* Only open is supported, no new llog can be created remotely */
64 int llog_origin_handle_open(struct ptlrpc_request *req)
65 {
66         struct obd_export       *exp = req->rq_export;
67         struct obd_device       *obd = exp->exp_obd;
68         struct llog_handle      *loghandle;
69         struct llogd_body       *body;
70         struct llog_logid       *logid = NULL;
71         struct llog_ctxt        *ctxt;
72         char                    *name = NULL;
73         int                      rc;
74
75         ENTRY;
76
77         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
78         if (body == NULL)
79                 RETURN(err_serious(-EFAULT));
80
81         rc = req_capsule_server_pack(&req->rq_pill);
82         if (rc)
83                 RETURN(err_serious(-ENOMEM));
84
85         if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
86                 logid = &body->lgd_logid;
87
88         if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
89                 name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
90                 if (name == NULL)
91                         RETURN(-EFAULT);
92                 CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
93         }
94
95         if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
96                 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d name=%s\n",
97                        obd->obd_name, body->lgd_ctxt_idx, name);
98                 RETURN(-EPROTO);
99         }
100
101         ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
102         if (ctxt == NULL) {
103                 CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
104                        obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
105                 RETURN(-ENODEV);
106         }
107
108         rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid,
109                        name, LLOG_OPEN_EXISTS);
110         if (rc)
111                 GOTO(out_ctxt, rc);
112
113         body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
114         body->lgd_logid = loghandle->lgh_id;
115
116         llog_origin_close(req->rq_svc_thread->t_env, loghandle);
117         EXIT;
118 out_ctxt:
119         llog_ctxt_put(ctxt);
120         return rc;
121 }
122 EXPORT_SYMBOL(llog_origin_handle_open);
123
124 int llog_origin_handle_destroy(struct ptlrpc_request *req)
125 {
126         struct llogd_body       *body;
127         struct llog_logid       *logid = NULL;
128         struct llog_ctxt        *ctxt;
129         int                      rc;
130
131         ENTRY;
132
133         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
134         if (body == NULL)
135                 RETURN(err_serious(-EFAULT));
136
137         rc = req_capsule_server_pack(&req->rq_pill);
138         if (rc < 0)
139                 RETURN(err_serious(-ENOMEM));
140
141         if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
142                 logid = &body->lgd_logid;
143
144         if (!(body->lgd_llh_flags & LLOG_F_IS_PLAIN))
145                 CERROR("%s: wrong llog flags %x\n",
146                        req->rq_export->exp_obd->obd_name, body->lgd_llh_flags);
147
148         if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
149                 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n",
150                        req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx);
151                 RETURN(-EPROTO);
152         }
153
154         ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
155         if (ctxt == NULL)
156                 RETURN(-ENODEV);
157
158         rc = llog_erase(req->rq_svc_thread->t_env, ctxt, logid, NULL);
159         llog_ctxt_put(ctxt);
160         RETURN(rc);
161 }
162 EXPORT_SYMBOL(llog_origin_handle_destroy);
163
164 int llog_origin_handle_next_block(struct ptlrpc_request *req)
165 {
166         struct llog_handle      *loghandle;
167         struct llogd_body       *body;
168         struct llogd_body       *repbody;
169         struct llog_ctxt        *ctxt;
170         __u32                    flags;
171         void                    *ptr;
172         int                      rc;
173
174         ENTRY;
175
176         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
177         if (body == NULL)
178                 RETURN(err_serious(-EFAULT));
179
180         req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
181                              LLOG_CHUNK_SIZE);
182         rc = req_capsule_server_pack(&req->rq_pill);
183         if (rc)
184                 RETURN(err_serious(-ENOMEM));
185
186         if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
187                 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n",
188                        req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx);
189                 RETURN(-EPROTO);
190         }
191
192         ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
193         if (ctxt == NULL)
194                 RETURN(-ENODEV);
195
196         rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
197                        &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
198         if (rc)
199                 GOTO(out_ctxt, rc);
200
201         flags = body->lgd_llh_flags;
202         rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
203                               NULL);
204         if (rc)
205                 GOTO(out_close, rc);
206
207         repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
208         *repbody = *body;
209
210         ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
211         rc = llog_next_block(req->rq_svc_thread->t_env, loghandle,
212                              &repbody->lgd_saved_index, repbody->lgd_index,
213                              &repbody->lgd_cur_offset, ptr, LLOG_CHUNK_SIZE);
214         if (rc)
215                 GOTO(out_close, rc);
216         EXIT;
217 out_close:
218         llog_origin_close(req->rq_svc_thread->t_env, loghandle);
219 out_ctxt:
220         llog_ctxt_put(ctxt);
221         return rc;
222 }
223 EXPORT_SYMBOL(llog_origin_handle_next_block);
224
225 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
226 {
227         struct llog_handle      *loghandle;
228         struct llogd_body       *body;
229         struct llogd_body       *repbody;
230         struct llog_ctxt        *ctxt;
231         __u32                    flags;
232         void                    *ptr;
233         int                      rc;
234
235         ENTRY;
236
237         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
238         if (body == NULL)
239                 RETURN(err_serious(-EFAULT));
240
241         req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
242                              LLOG_CHUNK_SIZE);
243         rc = req_capsule_server_pack(&req->rq_pill);
244         if (rc)
245                 RETURN(err_serious(-ENOMEM));
246
247         if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
248                 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n",
249                        req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx);
250                 RETURN(-EPROTO);
251         }
252
253         ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
254         if (ctxt == NULL)
255                 RETURN(-ENODEV);
256
257         rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
258                          &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
259         if (rc)
260                 GOTO(out_ctxt, rc);
261
262         flags = body->lgd_llh_flags;
263         rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
264                               NULL);
265         if (rc)
266                 GOTO(out_close, rc);
267
268         repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
269         *repbody = *body;
270
271         ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
272         rc = llog_prev_block(req->rq_svc_thread->t_env, loghandle,
273                              body->lgd_index, ptr, LLOG_CHUNK_SIZE);
274         if (rc)
275                 GOTO(out_close, rc);
276
277         EXIT;
278 out_close:
279         llog_origin_close(req->rq_svc_thread->t_env, loghandle);
280 out_ctxt:
281         llog_ctxt_put(ctxt);
282         return rc;
283 }
284 EXPORT_SYMBOL(llog_origin_handle_prev_block);
285
286 int llog_origin_handle_read_header(struct ptlrpc_request *req)
287 {
288         struct llog_handle      *loghandle;
289         struct llogd_body       *body;
290         struct llog_log_hdr     *hdr;
291         struct llog_ctxt        *ctxt;
292         __u32                    flags;
293         int                      rc;
294
295         ENTRY;
296
297         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
298         if (body == NULL)
299                 RETURN(err_serious(-EFAULT));
300
301         rc = req_capsule_server_pack(&req->rq_pill);
302         if (rc)
303                 RETURN(err_serious(-ENOMEM));
304
305         if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
306                 CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n",
307                        req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx);
308                 RETURN(-EPROTO);
309         }
310
311         ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx);
312         if (ctxt == NULL)
313                 RETURN(-ENODEV);
314
315         rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle,
316                        &body->lgd_logid, NULL, LLOG_OPEN_EXISTS);
317         if (rc)
318                 GOTO(out_ctxt, rc);
319
320         /*
321          * llog_init_handle() reads the llog header
322          */
323         flags = body->lgd_llh_flags;
324         rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags,
325                               NULL);
326         if (rc)
327                 GOTO(out_close, rc);
328         flags = loghandle->lgh_hdr->llh_flags;
329
330         hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
331         *hdr = *loghandle->lgh_hdr;
332         EXIT;
333 out_close:
334         llog_origin_close(req->rq_svc_thread->t_env, loghandle);
335 out_ctxt:
336         llog_ctxt_put(ctxt);
337         return rc;
338 }
339 EXPORT_SYMBOL(llog_origin_handle_read_header);
340
341 int llog_origin_handle_close(struct ptlrpc_request *req)
342 {
343         int      rc;
344
345         ENTRY;
346
347         rc = req_capsule_server_pack(&req->rq_pill);
348         if (rc)
349                 RETURN(err_serious(-ENOMEM));
350         RETURN(0);
351 }
352 EXPORT_SYMBOL(llog_origin_handle_close);
353
354 #else /* !__KERNEL__ */
355 int llog_origin_handle_open(struct ptlrpc_request *req)
356 {
357         LBUG();
358         return 0;
359 }
360
361 int llog_origin_handle_destroy(struct ptlrpc_request *req)
362 {
363         LBUG();
364         return 0;
365 }
366
367 int llog_origin_handle_next_block(struct ptlrpc_request *req)
368 {
369         LBUG();
370         return 0;
371 }
372 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
373 {
374         LBUG();
375         return 0;
376 }
377 int llog_origin_handle_read_header(struct ptlrpc_request *req)
378 {
379         LBUG();
380         return 0;
381 }
382 int llog_origin_handle_close(struct ptlrpc_request *req)
383 {
384         LBUG();
385         return 0;
386 }
387 #endif