Whamcloud - gitweb
port llog fixes from b1_6 into HEAD
[fs/lustre-release.git] / lustre / ptlrpc / llog_server.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
5  *   Author: Andreas Dilger <adilger@clusterfs.com>
6  *
7  *   This file is part of the Lustre file system, http://www.lustre.org
8  *   Lustre is a trademark of Cluster File Systems, Inc.
9  *
10  *   You may have signed or agreed to another license before downloading
11  *   this software.  If so, you are bound by the terms and conditions
12  *   of that agreement, and the following does not apply to you.  See the
13  *   LICENSE file included with this distribution for more information.
14  *
15  *   If you did not agree to a different license, then this copy of Lustre
16  *   is open source software; you can redistribute it and/or modify it
17  *   under the terms of version 2 of the GNU General Public License as
18  *   published by the Free Software Foundation.
19  *
20  *   In either case, Lustre is distributed in the hope that it will be
21  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
22  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *   license text for more details.
24  *
25  *  remote api for llog - server side
26  *
27  */
28
29 #define DEBUG_SUBSYSTEM S_LOG
30
31 #ifndef EXPORT_SYMTAB
32 #define EXPORT_SYMTAB
33 #endif
34
35 #ifndef __KERNEL__
36 #include <liblustre.h>
37 #endif
38
39 #include <obd_class.h>
40 #include <lustre_log.h>
41 #include <lustre_net.h>
42 #include <libcfs/list.h>
43 #include <lustre_fsfilt.h>
44
45 #if defined(__KERNEL__) && defined(LUSTRE_LOG_SERVER)
46
47 int llog_origin_handle_create(struct ptlrpc_request *req)
48 {
49         struct obd_export    *exp = req->rq_export;
50         struct obd_device    *obd = exp->exp_obd;
51         struct obd_device    *disk_obd;
52         struct llog_handle   *loghandle;
53         struct llogd_body    *body;
54         struct lvfs_run_ctxt  saved;
55         struct llog_logid    *logid = NULL;
56         struct llog_ctxt     *ctxt;
57         char                 *name = NULL;
58         int                   rc, rc2;
59         ENTRY;
60
61         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
62         if (body == NULL)
63                 RETURN(-EFAULT);
64
65         if (body->lgd_logid.lgl_oid > 0)
66                 logid = &body->lgd_logid;
67
68         if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
69                 name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
70                 if (name == NULL)
71                         RETURN(-EFAULT);
72                 CDEBUG(D_INFO, "opening log %s\n", name);
73         }
74
75         ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
76         if (ctxt == NULL)
77                 RETURN(-EINVAL);
78         disk_obd = ctxt->loc_exp->exp_obd;
79         push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
80
81         rc = llog_create(ctxt, &loghandle, logid, name);
82         if (rc)
83                 GOTO(out_pop, rc);
84
85         rc = req_capsule_server_pack(&req->rq_pill);
86         if (rc)
87                 GOTO(out_close, rc = -ENOMEM);
88
89         body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
90         body->lgd_logid = loghandle->lgh_id;
91
92 out_close:
93         rc2 = llog_close(loghandle);
94         if (!rc)
95                 rc = rc2;
96 out_pop:
97         pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
98         llog_ctxt_put(ctxt);
99         RETURN(rc);
100 }
101
102 int llog_origin_handle_destroy(struct ptlrpc_request *req)
103 {
104         struct obd_export    *exp = req->rq_export;
105         struct obd_device    *obd = exp->exp_obd;
106         struct obd_device    *disk_obd;
107         struct llog_handle   *loghandle;
108         struct llogd_body    *body;
109         struct lvfs_run_ctxt  saved;
110         struct llog_logid    *logid = NULL;
111         struct llog_ctxt     *ctxt;
112         __u32                 flags;
113         int                   rc;
114         ENTRY;
115
116         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
117         if (body == NULL)
118                 RETURN(-EFAULT);
119
120         if (body->lgd_logid.lgl_oid > 0)
121                 logid = &body->lgd_logid;
122
123         ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
124         if (ctxt == NULL)
125                 RETURN(-EINVAL);
126
127         disk_obd = ctxt->loc_exp->exp_obd;
128         push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
129
130         rc = llog_create(ctxt, &loghandle, logid, NULL);
131         if (rc)
132                 GOTO(out_pop, rc);
133
134         rc = req_capsule_server_pack(&req->rq_pill);
135         if (rc)
136                 GOTO(out_close, rc = -ENOMEM);
137
138         body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
139         body->lgd_logid = loghandle->lgh_id;
140         flags = body->lgd_llh_flags;
141         rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
142         if (rc)
143                 GOTO(out_close, rc);
144         rc = llog_destroy(loghandle);
145         if (rc)
146                 GOTO(out_close, rc);
147         llog_free_handle(loghandle);
148
149 out_close:
150         if (rc)
151                 llog_close(loghandle);
152 out_pop:
153         pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
154         llog_ctxt_put(ctxt);
155         RETURN(rc);
156 }
157
158 int llog_origin_handle_next_block(struct ptlrpc_request *req)
159 {
160         struct obd_export   *exp = req->rq_export;
161         struct obd_device   *obd = exp->exp_obd;
162         struct obd_device   *disk_obd;
163         struct llog_handle  *loghandle;
164         struct llogd_body   *body;
165         struct llogd_body   *repbody;
166         struct lvfs_run_ctxt saved;
167         struct llog_ctxt    *ctxt;
168         __u32                flags;
169         __u8                *buf;
170         void                *ptr;
171         int                  rc, rc2;
172         ENTRY;
173
174         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
175         if (body == NULL)
176                 RETURN(-EFAULT);
177
178         OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
179         if (!buf)
180                 RETURN(-ENOMEM);
181
182         ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
183         if (ctxt == NULL)
184                 GOTO(out_free, rc = -EINVAL);
185         disk_obd = ctxt->loc_exp->exp_obd;
186         push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
187
188         rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
189         if (rc)
190                 GOTO(out_pop, rc);
191
192         flags = body->lgd_llh_flags;
193         rc = llog_init_handle(loghandle, flags, NULL);
194         if (rc)
195                 GOTO(out_close, rc);
196
197         memset(buf, 0, LLOG_CHUNK_SIZE);
198         rc = llog_next_block(loghandle, &body->lgd_saved_index,
199                              body->lgd_index,
200                              &body->lgd_cur_offset, buf, LLOG_CHUNK_SIZE);
201         if (rc)
202                 GOTO(out_close, rc);
203
204         req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
205                              LLOG_CHUNK_SIZE);
206         rc = req_capsule_server_pack(&req->rq_pill);
207         if (rc)
208                 GOTO(out_close, rc = -ENOMEM);
209
210         repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
211         *repbody = *body;
212
213         ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
214         memcpy(ptr, buf, LLOG_CHUNK_SIZE);
215
216 out_close:
217         rc2 = llog_close(loghandle);
218         if (!rc)
219                 rc = rc2;
220
221 out_pop:
222         pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
223         llog_ctxt_put(ctxt);
224 out_free:
225         OBD_FREE(buf, LLOG_CHUNK_SIZE);
226         RETURN(rc);
227 }
228
229 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
230 {
231         struct obd_export    *exp = req->rq_export;
232         struct obd_device    *obd = exp->exp_obd;
233         struct llog_handle   *loghandle;
234         struct llogd_body    *body;
235         struct llogd_body    *repbody;
236         struct obd_device    *disk_obd;
237         struct lvfs_run_ctxt  saved;
238         struct llog_ctxt     *ctxt;
239         __u32                 flags;
240         __u8                 *buf;
241         void                 *ptr;
242         int                   rc, rc2;
243         ENTRY;
244
245         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
246         if (body == NULL)
247                 RETURN(-EFAULT);
248
249         OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
250         if (!buf)
251                 RETURN(-ENOMEM);
252
253         ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
254         LASSERT(ctxt != NULL);
255         disk_obd = ctxt->loc_exp->exp_obd;
256         push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
257
258         rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
259         if (rc)
260                 GOTO(out_pop, rc);
261
262         flags = body->lgd_llh_flags;
263         rc = llog_init_handle(loghandle, flags, NULL);
264         if (rc)
265                 GOTO(out_close, rc);
266
267         memset(buf, 0, LLOG_CHUNK_SIZE);
268         rc = llog_prev_block(loghandle, body->lgd_index,
269                              buf, LLOG_CHUNK_SIZE);
270         if (rc)
271                 GOTO(out_close, rc);
272
273         req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
274                              LLOG_CHUNK_SIZE);
275         rc = req_capsule_server_pack(&req->rq_pill);
276         if (rc)
277                 GOTO(out_close, rc = -ENOMEM);
278
279         repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
280         *repbody = *body;
281
282         ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
283         memcpy(ptr, buf, LLOG_CHUNK_SIZE);
284
285 out_close:
286         rc2 = llog_close(loghandle);
287         if (!rc)
288                 rc = rc2;
289
290 out_pop:
291         pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
292         llog_ctxt_put(ctxt);
293         OBD_FREE(buf, LLOG_CHUNK_SIZE);
294         RETURN(rc);
295 }
296
297 int llog_origin_handle_read_header(struct ptlrpc_request *req)
298 {
299         struct obd_export    *exp = req->rq_export;
300         struct obd_device    *obd = exp->exp_obd;
301         struct obd_device    *disk_obd;
302         struct llog_handle   *loghandle;
303         struct llogd_body    *body;
304         struct llog_log_hdr  *hdr;
305         struct lvfs_run_ctxt  saved;
306         struct llog_ctxt     *ctxt;
307         __u32                 flags;
308         int                   rc, rc2;
309         ENTRY;
310
311         body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
312         if (body == NULL)
313                 RETURN(-EFAULT);
314
315         ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
316         if (ctxt == NULL)
317                 RETURN(-EINVAL);
318         disk_obd = ctxt->loc_exp->exp_obd;
319         push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
320
321         rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
322         if (rc)
323                 GOTO(out_pop, rc);
324
325         /* init_handle reads the header */
326         flags = body->lgd_llh_flags;
327         rc = llog_init_handle(loghandle, flags, NULL);
328         if (rc)
329                 GOTO(out_close, rc);
330
331         rc = req_capsule_server_pack(&req->rq_pill);
332         if (rc)
333                 GOTO(out_close, rc = -ENOMEM);
334
335         hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
336         *hdr = *loghandle->lgh_hdr;
337
338 out_close:
339         rc2 = llog_close(loghandle);
340         if (!rc)
341                 rc = rc2;
342 out_pop:
343         pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
344         llog_ctxt_put(ctxt);
345         RETURN(rc);
346 }
347
348 int llog_origin_handle_close(struct ptlrpc_request *req)
349 {
350         int rc;
351
352         rc = 0;
353
354         RETURN(rc);
355 }
356
357 int llog_origin_handle_cancel(struct ptlrpc_request *req)
358 {
359         struct obd_device *obd = req->rq_export->exp_obd;
360         struct obd_device *disk_obd;
361         struct llog_cookie *logcookies;
362         struct llog_ctxt *ctxt = NULL;
363         int num_cookies, rc = 0, err, i;
364         struct lvfs_run_ctxt saved;
365         struct llog_handle *cathandle;
366         struct inode *inode;
367         void *handle;
368         ENTRY;
369
370         logcookies = req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES);
371         num_cookies = req_capsule_get_size(&req->rq_pill, &RMF_LOGCOOKIES,
372                                            RCL_CLIENT) / sizeof(*logcookies);
373         if (logcookies == NULL || num_cookies == 0) {
374                 DEBUG_REQ(D_HA, req, "no cookies sent");
375                 RETURN(-EFAULT);
376         }
377
378         ctxt = llog_get_context(obd, logcookies->lgc_subsys);
379         if (ctxt == NULL) {
380                 CWARN("llog subsys not setup or already cleanup\n");
381                 RETURN(-ENOENT);
382         }
383
384         disk_obd = ctxt->loc_exp->exp_obd;
385         push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
386         for (i = 0; i < num_cookies; i++, logcookies++) {
387                 cathandle = ctxt->loc_handle;
388                 LASSERT(cathandle != NULL);
389                 inode = cathandle->lgh_file->f_dentry->d_inode;
390
391                 handle = fsfilt_start_log(disk_obd, inode,
392                                           FSFILT_OP_CANCEL_UNLINK, NULL, 1);
393                 if (IS_ERR(handle)) {
394                         CERROR("fsfilt_start failed: %ld\n", PTR_ERR(handle));
395                         GOTO(pop_ctxt, rc = PTR_ERR(handle));
396                 }
397
398                 rc = llog_cat_cancel_records(cathandle, 1, logcookies);
399
400                 err = fsfilt_commit(disk_obd, inode, handle, 0);
401                 if (err) {
402                         CERROR("error committing transaction: %d\n", err);
403                         if (!rc)
404                                 rc = err;
405                         GOTO(pop_ctxt, rc);
406                 }
407         }
408 pop_ctxt:
409         pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
410         if (rc)
411                 CERROR("cancel %d llog-records failed: %d\n", num_cookies, rc);
412         else
413                 CDEBUG(D_RPCTRACE, "cancel %d llog-records\n", num_cookies);
414
415         llog_ctxt_put(ctxt);
416         RETURN(rc);
417 }
418 EXPORT_SYMBOL(llog_origin_handle_cancel);
419
420 static int llog_catinfo_config(struct obd_device *obd, char *buf, int buf_len,
421                                char *client)
422 {
423         struct mds_obd       *mds = &obd->u.mds;
424         struct llog_ctxt     *ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
425         struct lvfs_run_ctxt  saved;
426         struct llog_handle   *handle = NULL;
427         char                  name[4][64];
428         int                   rc, i, l, remains = buf_len;
429         char                 *out = buf;
430
431         if (ctxt == NULL || mds == NULL)
432                 GOTO(release_ctxt, rc = -EOPNOTSUPP);
433
434         push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
435
436         sprintf(name[0], "%s", mds->mds_profile);
437         sprintf(name[1], "%s-clean", mds->mds_profile);
438         sprintf(name[2], "%s", client);
439         sprintf(name[3], "%s-clean", client);
440
441         for (i = 0; i < 4; i++) {
442                 int index, uncanceled = 0;
443                 rc = llog_create(ctxt, &handle, NULL, name[i]);
444                 if (rc)
445                         GOTO(out_pop, rc);
446                 rc = llog_init_handle(handle, 0, NULL);
447                 if (rc) {
448                         llog_close(handle);
449                         GOTO(out_pop, rc = -ENOENT);
450                 }
451
452                 for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index ++) {
453                         if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap))
454                                 uncanceled++;
455                 }
456
457                 l = snprintf(out, remains, "[Log Name]: %s\nLog Size: %llu\n"
458                              "Last Index: %d\nUncanceled Records: %d\n\n",
459                              name[i],
460                              i_size_read(handle->lgh_file->f_dentry->d_inode),
461                              handle->lgh_last_idx, uncanceled);
462                 out += l;
463                 remains -= l;
464
465                 llog_close(handle);
466                 if (remains <= 0)
467                         break;
468         }
469 out_pop:
470         pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
471 release_ctxt:
472         llog_ctxt_put(ctxt);
473         RETURN(rc);
474 }
475
476 struct cb_data {
477         struct llog_ctxt *ctxt;
478         char *out;
479         int  remains;
480         int  init;
481 };
482
483 static int llog_catinfo_cb(struct llog_handle *cat,
484                            struct llog_rec_hdr *rec, void *data)
485 {
486         static char *out = NULL;
487         static int remains = 0;
488         struct llog_ctxt *ctxt = NULL;
489         struct llog_handle *handle;
490         struct llog_logid *logid;
491         struct llog_logid_rec *lir;
492         int l, rc, index, count = 0;
493         struct cb_data *cbd = (struct cb_data*)data;
494
495         if (cbd->init) {
496                 out = cbd->out;
497                 remains = cbd->remains;
498                 cbd->init = 0;
499         }
500
501         if (!(cat->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
502                 RETURN(-EINVAL);
503
504         if (!cbd->ctxt)
505                 RETURN(-EINVAL);
506         
507         lir = (struct llog_logid_rec *)rec;
508         logid = &lir->lid_id;
509         rc = llog_create(ctxt, &handle, logid, NULL);
510         if (rc)
511                 RETURN(-EINVAL);
512         rc = llog_init_handle(handle, 0, NULL);
513         if (rc)
514                 GOTO(out_close, rc);
515
516         for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index++) {
517                 if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap))
518                         count++;
519         }
520
521         l = snprintf(out, remains, "\t[Log ID]: #"LPX64"#"LPX64"#%08x\n"
522                      "\tLog Size: %llu\n\tLast Index: %d\n"
523                      "\tUncanceled Records: %d\n",
524                      logid->lgl_oid, logid->lgl_ogr, logid->lgl_ogen,
525                      i_size_read(handle->lgh_file->f_dentry->d_inode),
526                      handle->lgh_last_idx, count);
527         out += l;
528         remains -= l;
529         cbd->out = out;
530         cbd->remains = remains;
531         if (remains <= 0) {
532                 CWARN("Not enough memory\n");
533                 rc = -ENOMEM;
534         }
535
536 out_close:
537         llog_close(handle);
538         RETURN(rc);
539 }
540
541 static int llog_catinfo_deletions(struct obd_device *obd, char *buf,
542                                   int buf_len)
543 {
544         struct mds_obd *mds = &obd->u.mds;
545         struct llog_handle *handle;
546         struct lvfs_run_ctxt saved;
547         int size, i, count;
548         struct llog_catid *idarray;
549         struct llog_logid *id;
550         char name[32] = CATLIST;
551         struct cb_data data;
552         struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
553         int rc;
554
555         if (ctxt == NULL || mds == NULL)
556                 GOTO(release_ctxt, rc = -EOPNOTSUPP);
557
558         count = mds->mds_lov_desc.ld_tgt_count;
559         size = sizeof(*idarray) * count;
560
561         OBD_ALLOC(idarray, size);
562         if (!idarray)
563                 GOTO(release_ctxt, rc = -ENOMEM);
564
565         rc = llog_get_cat_list(obd, obd, name, count, idarray);
566         if (rc)
567                 GOTO(out_free, rc);
568
569         push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
570
571         data.ctxt = ctxt;
572         data.out = buf;
573         data.remains = buf_len;
574         for (i = 0; i < count; i++) {
575                 int l, index, uncanceled = 0;
576
577                 id = &idarray[i].lci_logid;
578                 rc = llog_create(ctxt, &handle, id, NULL);
579                 if (rc)
580                         GOTO(out_pop, rc);
581                 rc = llog_init_handle(handle, 0, NULL);
582                 if (rc) {
583                         llog_close(handle);
584                         GOTO(out_pop, rc = -ENOENT);
585                 }
586                 for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index++) {
587                         if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap))
588                                 uncanceled++;
589                 }
590                 l = snprintf(data.out, data.remains,
591                              "\n[Catlog ID]: #"LPX64"#"LPX64"#%08x  "
592                              "[Log Count]: %d\n",
593                              id->lgl_oid, id->lgl_ogr, id->lgl_ogen,
594                              uncanceled);
595
596                 data.out += l;
597                 data.remains -= l;
598                 data.init = 1;
599
600                 llog_process(handle, llog_catinfo_cb, &data, NULL);
601                 llog_close(handle);
602
603                 if (data.remains <= 0)
604                         break;
605         }
606 out_pop:
607         pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
608 out_free:
609         OBD_FREE(idarray, size);
610 release_ctxt:
611         llog_ctxt_put(ctxt);
612
613         RETURN(rc);
614 }
615
616 int llog_catinfo(struct ptlrpc_request *req)
617 {
618         struct obd_export *exp = req->rq_export;
619         struct obd_device *obd = exp->exp_obd;
620         char              *keyword;
621         char              *buf, *reply;
622         int                rc;
623
624         OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
625         if (buf == NULL)
626                 return -ENOMEM;
627         memset(buf, 0, LLOG_CHUNK_SIZE);
628
629         keyword = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
630         LASSERT(keyword);
631
632         if (strcmp(keyword, "config") == 0) {
633                 char *client = req_capsule_client_get(&req->rq_pill,
634                                                       &RMF_STRING);
635
636                 LASSERT(client);
637                 rc = llog_catinfo_config(obd, buf, LLOG_CHUNK_SIZE, client);
638         } else if (strcmp(keyword, "deletions") == 0) {
639                 rc = llog_catinfo_deletions(obd, buf, LLOG_CHUNK_SIZE);
640         } else {
641                 rc = -EOPNOTSUPP;
642         }
643
644         req_capsule_set_size(&req->rq_pill, &RMF_STRING, RCL_SERVER,
645                              LLOG_CHUNK_SIZE);
646         rc = req_capsule_server_pack(&req->rq_pill);
647         if (rc)
648                 GOTO(out_free, rc = -ENOMEM);
649
650         reply = req_capsule_server_get(&req->rq_pill, &RMF_STRING);
651         if (strlen(buf) == 0)
652                 sprintf(buf, "%s", "No log informations\n");
653         memcpy(reply, buf, LLOG_CHUNK_SIZE);
654
655 out_free:
656         OBD_FREE(buf, LLOG_CHUNK_SIZE);
657         return rc;
658 }
659
660 #else /* !__KERNEL__ */
661 int llog_origin_handle_create(struct ptlrpc_request *req)
662 {
663         LBUG();
664         return 0;
665 }
666
667 int llog_origin_handle_destroy(struct ptlrpc_request *req)
668 {
669         LBUG();
670         return 0;
671 }
672
673 int llog_origin_handle_next_block(struct ptlrpc_request *req)
674 {
675         LBUG();
676         return 0;
677 }
678 int llog_origin_handle_prev_block(struct ptlrpc_request *req)
679 {
680         LBUG();
681         return 0;
682 }
683 int llog_origin_handle_read_header(struct ptlrpc_request *req)
684 {
685         LBUG();
686         return 0;
687 }
688 int llog_origin_handle_close(struct ptlrpc_request *req)
689 {
690         LBUG();
691         return 0;
692 }
693 int llog_origin_handle_cancel(struct ptlrpc_request *req)
694 {
695         LBUG();
696         return 0;
697 }
698 #endif