This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / fs / intermezzo / kml_decode.c
1 /*
2  * KML Decoding
3  *
4  * Copryright (C) 1996 Arthur Ma <arthur.ma@mountainviewdata.com> 
5  *
6  * Copyright (C) 2001 Mountainview Data, Inc.
7  */
8 #include <linux/module.h>
9 #include <linux/errno.h>
10 #include <linux/kernel.h>
11 #include <linux/major.h>
12 #include <linux/slab.h>
13 #include <linux/vmalloc.h>
14 #include <linux/mm.h>
15 #include "intermezzo_fs.h"
16 #include "intermezzo_kml.h"
17
18 static int size_round (int val);
19 static int unpack_create (struct kml_create *rec, char *buf,
20                                 int pos, int *rec_offs);
21 static int unpack_open (struct kml_open *rec, char *buf,
22                                 int pos, int *rec_offs);
23 static int unpack_symlink (struct kml_symlink *rec, char *buf,
24                                 int pos, int *rec_offs);
25 static int unpack_mknod (struct kml_mknod *rec, char *buf,
26                                 int pos, int *rec_offs);
27 static int unpack_link (struct kml_link *rec, char *buf,
28                                 int pos, int *rec_offs);
29 static int unpack_rename (struct kml_rename *rec, char *buf,
30                                 int pos, int *rec_offs);
31 static int unpack_unlink (struct kml_unlink *rec, char *buf,
32                                 int pos, int *rec_offs);
33 static int unpack_rmdir (struct kml_rmdir *rec, char *buf,
34                                 int pos, int *rec_offs);
35 static int unpack_setattr (struct kml_setattr *rec, char *buf,
36                                 int pos, int *rec_offs);
37 static int unpack_close (struct kml_close *rec, char *buf,
38                                 int pos, int *rec_offs);
39 static int unpack_mkdir (struct kml_mkdir *rec, char *buf,
40                                 int pos, int *rec_offs);
41
42 #if 0
43 static int unpack_endmark (struct kml_endmark *rec, char *buf,
44                                 int pos, int *rec_offs);
45 static void print_kml_endmark (struct kml_endmark *rec);
46 #endif
47
48 static int kml_unpack (char *kml_buf, int rec_size, int kml_offset,
49                         struct kml_rec **newrec);
50 static char *kml_version (struct presto_version *ver);
51 static void print_kml_prefix (struct big_journal_prefix *head);
52 static void print_kml_create (struct kml_create *rec);
53 static void print_kml_mkdir (struct kml_mkdir *rec);
54 static void print_kml_unlink (struct kml_unlink *rec);
55 static void print_kml_rmdir (struct kml_rmdir *rec);
56 static void print_kml_close (struct kml_close *rec);
57 static void print_kml_symlink (struct kml_symlink *rec);
58 static void print_kml_rename (struct kml_rename *rec);
59 static void print_kml_setattr (struct kml_setattr *rec);
60 static void print_kml_link (struct kml_link *rec);
61 static void print_kml_mknod (struct kml_mknod *rec);
62 static void print_kml_open (struct kml_open *rec);
63 static void print_kml_suffix (struct journal_suffix *tail);
64 static char *readrec (char *recbuf, int reclen, int pos, int *size);
65
66 #define  KML_PREFIX_WORDS           8
67 static int kml_unpack (char *kml_buf, int rec_size, int kml_offset, 
68                         struct kml_rec **newrec)
69 {
70         struct kml_rec  *rec;
71         char            *p;
72         int             pos, rec_offs;
73         int             error;
74
75         ENTRY;
76         if (rec_size < sizeof (struct journal_prefix) +
77                        sizeof (struct journal_suffix))
78                 return -EBADF;
79
80         PRESTO_ALLOC(rec, struct kml_rec *, sizeof (struct kml_rec));
81         if (rec == NULL) {
82                 EXIT;
83                 return -ENOMEM;
84         }
85         rec->rec_kml_offset = kml_offset;
86         rec->rec_size = rec_size;
87         p = kml_buf;
88         p = dlogit (&rec->rec_head, p, KML_PREFIX_WORDS * sizeof (int));
89         p = dlogit (&rec->rec_head.groups, p, 
90                         sizeof (int) * rec->rec_head.ngroups);
91
92         pos = sizeof (struct journal_prefix) + 
93                         sizeof (int) * rec->rec_head.ngroups;
94         switch (rec->rec_head.opcode)
95         {
96                 case KML_CREATE:
97                         error = unpack_create (&rec->rec_kml.create, 
98                                         kml_buf, pos, &rec_offs);
99                         break;
100                 case KML_MKDIR:
101                         error = unpack_mkdir (&rec->rec_kml.mkdir, 
102                                         kml_buf, pos, &rec_offs);
103                         break;
104                 case KML_UNLINK:
105                         error = unpack_unlink (&rec->rec_kml.unlink, 
106                                         kml_buf, pos, &rec_offs);
107                         break;
108                 case KML_RMDIR:
109                         error = unpack_rmdir (&rec->rec_kml.rmdir, 
110                                         kml_buf, pos, &rec_offs);
111                         break;
112                 case KML_CLOSE:
113                         error = unpack_close (&rec->rec_kml.close, 
114                                         kml_buf, pos, &rec_offs);
115                         break;
116                 case KML_SYMLINK:
117                         error = unpack_symlink (&rec->rec_kml.symlink, 
118                                         kml_buf, pos, &rec_offs);
119                         break;
120                 case KML_RENAME:
121                         error = unpack_rename (&rec->rec_kml.rename, 
122                                         kml_buf, pos, &rec_offs);
123                         break;
124                 case KML_SETATTR:
125                         error = unpack_setattr (&rec->rec_kml.setattr, 
126                                         kml_buf, pos, &rec_offs);
127                         break;
128                 case KML_LINK:
129                         error = unpack_link (&rec->rec_kml.link, 
130                                         kml_buf, pos, &rec_offs);
131                         break;
132                 case KML_OPEN:
133                         error = unpack_open (&rec->rec_kml.open, 
134                                         kml_buf, pos, &rec_offs);
135                         break;
136                 case KML_MKNOD:
137                         error = unpack_mknod (&rec->rec_kml.mknod, 
138                                         kml_buf, pos, &rec_offs);
139                         break;
140 #if 0
141                 case KML_ENDMARK:
142                         error = unpack_endmark (&rec->rec_kml.endmark, 
143                                         kml_buf, pos, &rec_offs);
144                         break;
145 #endif
146                 default:
147                         CDEBUG (D_KML, "wrong opcode::%u\n", 
148                                         rec->rec_head.opcode);
149                         EXIT;
150                         return -EINVAL;
151         } 
152         if (error) {
153                 PRESTO_FREE (rec, sizeof (struct kml_rec));
154                 return -EINVAL;
155         }
156         p = kml_buf + rec_offs;
157         p = dlogit (&rec->rec_tail, p, sizeof (struct journal_suffix));
158         memset (&rec->kml_optimize, 0, sizeof (struct kml_optimize));
159         *newrec = rec;
160         EXIT;
161         return 0;
162 }
163
164 static int size_round (int val)
165 {
166         return (val + 3) & (~0x3);
167 }
168
169 static int unpack_create (struct kml_create *rec, char *buf, 
170                                 int pos, int *rec_offs)
171 {
172         char *p, *q;
173         int unpack_size = 88;
174         int pathlen;
175
176         ENTRY;
177         p = buf + pos;
178         p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));
179         p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));
180         p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));
181         p = dlogit (&rec->mode, p, sizeof (int));
182         p = dlogit (&rec->uid, p, sizeof (int));
183         p = dlogit (&rec->gid, p, sizeof (int));
184         p = dlogit (&pathlen, p, sizeof (int));
185
186         PRESTO_ALLOC(q, char *, pathlen + 1);
187         if (q == NULL) {
188                 EXIT;
189                 return -ENOMEM;
190         }
191
192         memcpy (q, p, pathlen);
193         q[pathlen] = '\0';
194         rec->path = q;
195
196         *rec_offs = pos + unpack_size + size_round(pathlen);
197         EXIT;
198         return 0;
199 }
200
201 static int unpack_open (struct kml_open *rec, char *buf, 
202                                 int pos, int *rec_offs)
203 {
204         *rec_offs = pos;
205         return 0;
206 }
207
208 static int unpack_symlink (struct kml_symlink *rec, char *buf, 
209                                 int pos, int *rec_offs)
210 {
211         char *p, *q;
212         int unpack_size = 88;
213         int pathlen, targetlen;
214
215         ENTRY;
216         p = buf + pos;
217         p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));
218         p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));
219         p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));
220         p = dlogit (&rec->uid, p, sizeof (int));
221         p = dlogit (&rec->gid, p, sizeof (int));
222         p = dlogit (&pathlen, p, sizeof (int));
223         p = dlogit (&targetlen, p, sizeof (int));
224
225         PRESTO_ALLOC(q, char *, pathlen + 1);
226         if (q == NULL) {
227                 EXIT;
228                 return -ENOMEM;
229         }
230
231         memcpy (q, p, pathlen);
232         q[pathlen] = '\0';
233         rec->sourcepath = q;
234
235         PRESTO_ALLOC(q, char *, targetlen + 1);
236         if (q == NULL) {
237                 PRESTO_FREE (rec->sourcepath, pathlen + 1);
238                 EXIT;
239                 return -ENOMEM;
240         }
241
242         memcpy (q, p, targetlen);
243         q[targetlen] = '\0';
244         rec->targetpath = q;
245
246         *rec_offs = pos + unpack_size + size_round(pathlen) +
247                         size_round(targetlen);
248         EXIT;
249         return 0;
250 }
251
252 static int unpack_mknod (struct kml_mknod *rec, char *buf, 
253                                 int pos, int *rec_offs)
254 {
255         char *p, *q;
256         int unpack_size = 96;
257         int pathlen;
258
259         ENTRY;
260         p = buf + pos;
261         p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));
262         p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));
263         p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));
264         p = dlogit (&rec->mode, p, sizeof (int));
265         p = dlogit (&rec->uid, p, sizeof (int));
266         p = dlogit (&rec->gid, p, sizeof (int));
267         p = dlogit (&rec->major, p, sizeof (int));
268         p = dlogit (&rec->minor, p, sizeof (int));
269         p = dlogit (&pathlen, p, sizeof (int));
270
271         PRESTO_ALLOC(q, char *, pathlen + 1);
272         if (q == NULL) {
273                 EXIT;
274                 return -ENOMEM;
275         }
276
277         memcpy (q, p, pathlen);
278         q[pathlen] = '\0';
279         rec->path = q;
280
281         *rec_offs = pos + unpack_size + size_round(pathlen);
282         EXIT;
283         return 0;
284 }
285
286 static int unpack_link (struct kml_link *rec, char *buf, 
287                                 int pos, int *rec_offs)
288 {
289         char *p, *q;
290         int unpack_size = 80;
291         int pathlen, targetlen;
292
293         ENTRY;
294         p = buf + pos;
295         p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));
296         p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));
297         p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));
298         p = dlogit (&pathlen, p, sizeof (int));
299         p = dlogit (&targetlen, p, sizeof (int));
300
301         PRESTO_ALLOC(q, char *, pathlen + 1);
302         if (q == NULL) {
303                 EXIT;
304                 return -ENOMEM;
305         }
306
307         memcpy (q, p, pathlen);
308         q[pathlen] = '\0';
309         rec->sourcepath = q;
310         p += size_round (pathlen);
311
312         PRESTO_ALLOC(q, char *, targetlen + 1);
313         if (q == NULL) {
314                 PRESTO_FREE (rec->sourcepath, pathlen + 1);
315                 EXIT;
316                 return -ENOMEM;
317         }
318         memcpy (q, p, targetlen);
319         q[targetlen] = '\0';
320         rec->targetpath = q;
321
322         *rec_offs = pos + unpack_size + size_round(pathlen) +
323                         size_round(targetlen);
324         EXIT;
325         return 0;
326 }
327
328 static int unpack_rename (struct kml_rename *rec, char *buf, 
329                                 int pos, int *rec_offs)
330 {
331         char *p, *q;
332         int unpack_size = 104;
333         int pathlen, targetlen;
334
335         ENTRY;
336         p = buf + pos;
337         p = dlogit (&rec->old_objectv, p, sizeof (struct presto_version));
338         p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));
339         p = dlogit (&rec->new_tgtv, p, sizeof (struct presto_version));
340         p = dlogit (&rec->old_tgtv, p, sizeof (struct presto_version));
341         p = dlogit (&pathlen, p, sizeof (int));
342         p = dlogit (&targetlen, p, sizeof (int));
343
344         PRESTO_ALLOC(q, char *, pathlen + 1);
345         if (q == NULL) {
346                 EXIT;
347                 return -ENOMEM;
348         }
349
350         memcpy (q, p, pathlen);
351         q[pathlen] = '\0';
352         rec->sourcepath = q;
353         p += size_round (pathlen);
354
355         PRESTO_ALLOC(q, char *, targetlen + 1);
356         if (q == NULL) {
357                 PRESTO_FREE (rec->sourcepath, pathlen + 1);
358                 EXIT;
359                 return -ENOMEM;
360         }
361
362         memcpy (q, p, targetlen);
363         q[targetlen] = '\0';
364         rec->targetpath = q;
365
366         *rec_offs = pos + unpack_size + size_round(pathlen) +
367                         size_round(targetlen);
368         EXIT;
369         return 0;
370 }
371
372 static int unpack_unlink (struct kml_unlink *rec, char *buf, 
373                                 int pos, int *rec_offs)
374 {
375         char *p, *q;
376         int unpack_size = 80;
377         int pathlen, targetlen;
378
379         ENTRY;
380         p = buf + pos;
381         p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));
382         p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));
383         p = dlogit (&rec->old_tgtv, p, sizeof (struct presto_version));
384         p = dlogit (&pathlen, p, sizeof (int));
385         p = dlogit (&targetlen, p, sizeof (int));
386
387         PRESTO_ALLOC(q, char *, pathlen + 1);
388         if (q == NULL) {
389                 EXIT;
390                 return -ENOMEM;
391         }
392
393         memcpy (q, p, pathlen);
394         q[pathlen] = '\0';
395         rec->path = q;
396         p += size_round (pathlen);
397
398         PRESTO_ALLOC(q, char *, targetlen + 1);
399         if (q == NULL) {
400                 PRESTO_FREE (rec->path, pathlen + 1);
401                 EXIT;
402                 return -ENOMEM;
403         }
404
405         memcpy (q, p, targetlen);
406         q[targetlen] = '\0';
407         rec->name = q;
408
409         /* fix the presto_journal_unlink problem */
410         *rec_offs = pos + unpack_size + size_round(pathlen) +
411                         size_round(targetlen);
412         EXIT;
413         return 0;
414 }
415
416 static int unpack_rmdir (struct kml_rmdir *rec, char *buf, 
417                                 int pos, int *rec_offs)
418 {
419         char *p, *q;
420         int unpack_size = 80;
421         int pathlen, targetlen;
422
423         ENTRY;
424         p = buf + pos;
425         p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));
426         p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));
427         p = dlogit (&rec->old_tgtv, p, sizeof (struct presto_version));
428         p = dlogit (&pathlen, p, sizeof (int));
429         p = dlogit (&targetlen, p, sizeof (int));
430
431         PRESTO_ALLOC(q, char *, pathlen + 1);
432         if (q == NULL) {
433                 EXIT;
434                 return -ENOMEM;
435         }
436
437         memcpy (q, p, pathlen);
438         q[pathlen] = '\0';
439         rec->path = q;
440         p += size_round (pathlen);
441
442         PRESTO_ALLOC(q, char *, targetlen + 1);
443         if (q == NULL) {
444                 PRESTO_FREE (rec->path, pathlen + 1);
445                 EXIT;
446                 return -ENOMEM;
447         }
448         memcpy (q, p, targetlen);
449         q[targetlen] = '\0';
450         rec->name = q;
451
452         *rec_offs = pos + unpack_size + size_round(pathlen) +
453                         size_round(targetlen);
454         EXIT;
455         return 0;
456 }
457
458 static int unpack_setattr (struct kml_setattr *rec, char *buf, 
459                                 int pos, int *rec_offs)
460 {
461         char *p, *q;
462         int unpack_size = 72;
463         struct kml_attr {
464                 __u64   size, mtime, ctime;
465         } objattr;
466         int     valid, mode, uid, gid, flags;
467         int pathlen;
468
469         ENTRY;
470         p = buf + pos;
471         p = dlogit (&rec->old_objectv, p, sizeof (struct presto_version));
472         p = dlogit (&valid, p, sizeof (int));
473         p = dlogit (&mode, p, sizeof (int));
474         p = dlogit (&uid, p, sizeof (int));
475         p = dlogit (&gid, p, sizeof (int));
476         p = dlogit (&objattr, p, sizeof (struct kml_attr));
477         p = dlogit (&flags, p, sizeof (int));
478         p = dlogit (&pathlen, p, sizeof (int));
479
480         rec->iattr.ia_valid = valid;
481         rec->iattr.ia_mode = mode;
482         rec->iattr.ia_uid = uid;
483         rec->iattr.ia_gid = gid;
484         rec->iattr.ia_size = objattr.size;
485         rec->iattr.ia_mtime = objattr.mtime;
486         rec->iattr.ia_ctime = objattr.ctime;
487         rec->iattr.ia_atime = 0;
488         rec->iattr.ia_attr_flags = flags;
489
490         PRESTO_ALLOC(q, char *, pathlen + 1);
491         if (q == NULL) {
492                 EXIT;
493                 return -ENOMEM;
494         }
495         memcpy (q, p, pathlen);
496         q[pathlen] = '\0';
497         rec->path = q;
498         p += pathlen;
499
500         *rec_offs = pos + unpack_size + size_round(pathlen);
501         EXIT;
502         return 0;
503 }
504
505 static int unpack_close (struct kml_close *rec, char *buf, 
506                                 int pos, int *rec_offs)
507 {
508         char *p, *q;
509         int unpack_size = 52;
510         int pathlen;
511
512         ENTRY;
513         p = buf + pos;
514         p = dlogit (&rec->open_mode, p, sizeof (int));
515         p = dlogit (&rec->open_uid, p, sizeof (int));
516         p = dlogit (&rec->open_gid, p, sizeof (int));
517         p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));
518         p = dlogit (&rec->ino, p, sizeof (__u64));
519         p = dlogit (&rec->generation, p, sizeof (int));
520         p = dlogit (&pathlen, p, sizeof (int));
521
522         PRESTO_ALLOC(q, char *, pathlen + 1);
523         if (q == NULL) {
524                 EXIT;
525                 return -ENOMEM;
526         }
527
528         memcpy (q, p, pathlen);
529         q[pathlen] = '\0';
530         rec->path = q;
531         p += pathlen;
532
533         *rec_offs = pos + unpack_size + size_round(pathlen);
534         EXIT;
535         return 0;
536 }
537
538 static int unpack_mkdir (struct kml_mkdir *rec, char *buf, 
539                                 int pos, int *rec_offs)
540 {
541         char *p, *q;
542         int unpack_size = 88;
543         int pathlen;
544
545         ENTRY;
546         p = buf + pos;
547         p = dlogit (&rec->old_parentv, p, sizeof (struct presto_version));
548         p = dlogit (&rec->new_parentv, p, sizeof (struct presto_version));
549         p = dlogit (&rec->new_objectv, p, sizeof (struct presto_version));
550         p = dlogit (&rec->mode, p, sizeof (int));
551         p = dlogit (&rec->uid, p, sizeof (int));
552         p = dlogit (&rec->gid, p, sizeof (int));
553         p = dlogit (&pathlen, p, sizeof (int));
554
555         PRESTO_ALLOC(q, char *, pathlen + 1);
556         if (q == NULL) {
557                 EXIT;
558                 return -ENOMEM;
559         }
560
561         memcpy (q, p, pathlen);
562         q[pathlen] = '\0';
563         rec->path = q;
564         p += pathlen;
565
566         *rec_offs = pos + unpack_size + size_round(pathlen);
567         EXIT;
568         return 0;
569 }
570
571 #if 0
572 static int unpack_endmark (struct kml_endmark *rec, char *buf, 
573                                 int pos, int *rec_offs)
574 {
575         char *p;
576         p = buf + pos;
577         p = dlogit (&rec->total, p, sizeof (int));
578
579         PRESTO_ALLOC (rec->kop, struct kml_kop_node *, 
580                         sizeof (struct kml_kop_node) * rec->total);
581         if (rec->kop == NULL) {
582                 EXIT;
583                 return -ENOMEM;
584         }
585
586         p = dlogit (rec->kop, p, sizeof (struct kml_kop_node) * rec->total);
587
588         *rec_offs = pos + sizeof (int) + sizeof (struct kml_kop_node) * rec->total;
589         return 0;
590 }
591 #endif
592
593 static char *kml_version (struct presto_version *ver)
594 {
595         static char buf[256];
596         sprintf (buf, "mt::%lld, ct::%lld, size::%lld",
597                 ver->pv_mtime, ver->pv_ctime, ver->pv_size); 
598         return buf;
599 }
600
601 static void print_kml_prefix (struct big_journal_prefix *head)
602 {
603         int i;
604
605         CDEBUG (D_KML, " === KML PREFIX\n");
606         CDEBUG (D_KML, "     len        = %u\n", head->len);
607         CDEBUG (D_KML, "     version    = %u\n", head->version);
608         CDEBUG (D_KML, "     pid        = %u\n", head->pid);
609         CDEBUG (D_KML, "     uid        = %u\n", head->uid);
610         CDEBUG (D_KML, "     fsuid      = %u\n", head->fsuid);
611         CDEBUG (D_KML, "     fsgid      = %u\n", head->fsgid);
612         CDEBUG (D_KML, "     opcode     = %u\n", head->opcode);
613         CDEBUG (D_KML, "     ngroup     = %u",  head->ngroups);
614         for (i = 0; i < head->ngroups; i++)
615                 CDEBUG (D_KML, "%u  ",  head->groups[i]);
616         CDEBUG (D_KML, "\n");
617 }
618
619 static void print_kml_create (struct kml_create *rec)
620 {
621         CDEBUG (D_KML, " === CREATE\n");
622         CDEBUG (D_KML, "     path::%s\n", rec->path);
623         CDEBUG (D_KML, "     new_objv::%s\n", kml_version (&rec->new_objectv));
624         CDEBUG (D_KML, "     old_parv::%s\n", kml_version (&rec->old_parentv));
625         CDEBUG (D_KML, "     new_parv::%s\n", kml_version (&rec->new_parentv));
626         CDEBUG (D_KML, "     mode::%o\n", rec->mode);
627         CDEBUG (D_KML, "     uid::%d\n", rec->uid);
628         CDEBUG (D_KML, "     gid::%d\n", rec->gid);
629 }
630
631 static void print_kml_mkdir (struct kml_mkdir *rec)
632 {
633         CDEBUG (D_KML, " === MKDIR\n");
634         CDEBUG (D_KML, "     path::%s\n", rec->path);
635         CDEBUG (D_KML, "     new_objv::%s\n", kml_version (&rec->new_objectv));
636         CDEBUG (D_KML, "     old_parv::%s\n", kml_version (&rec->old_parentv));
637         CDEBUG (D_KML, "     new_parv::%s\n", kml_version (&rec->new_parentv));
638         CDEBUG (D_KML, "     mode::%o\n", rec->mode);
639         CDEBUG (D_KML, "     uid::%d\n", rec->uid);
640         CDEBUG (D_KML, "     gid::%d\n", rec->gid);
641 }
642
643 static void print_kml_unlink (struct kml_unlink *rec)
644 {
645         CDEBUG (D_KML, " === UNLINK\n");
646         CDEBUG (D_KML, "     path::%s/%s\n", rec->path, rec->name);
647         CDEBUG (D_KML, "     old_tgtv::%s\n", kml_version (&rec->old_tgtv));
648         CDEBUG (D_KML, "     old_parv::%s\n", kml_version (&rec->old_parentv));
649         CDEBUG (D_KML, "     new_parv::%s\n", kml_version (&rec->new_parentv));
650 }
651
652 static void print_kml_rmdir (struct kml_rmdir *rec)
653 {
654         CDEBUG (D_KML, " === RMDIR\n");
655         CDEBUG (D_KML, "     path::%s/%s\n", rec->path, rec->name);
656         CDEBUG (D_KML, "     old_tgtv::%s\n", kml_version (&rec->old_tgtv));
657         CDEBUG (D_KML, "     old_parv::%s\n", kml_version (&rec->old_parentv));
658         CDEBUG (D_KML, "     new_parv::%s\n", kml_version (&rec->new_parentv));
659 }
660
661 static void print_kml_close (struct kml_close *rec)
662 {
663         CDEBUG (D_KML, " === CLOSE\n");
664         CDEBUG (D_KML, "     mode::%o\n", rec->open_mode);
665         CDEBUG (D_KML, "     uid::%d\n", rec->open_uid);
666         CDEBUG (D_KML, "     gid::%d\n", rec->open_gid);
667         CDEBUG (D_KML, "     path::%s\n", rec->path);
668         CDEBUG (D_KML, "     new_objv::%s\n", kml_version (&rec->new_objectv));
669         CDEBUG (D_KML, "     ino::%lld\n", rec->ino);
670         CDEBUG (D_KML, "     gen::%u\n", rec->generation);
671 }
672
673 static void print_kml_symlink (struct kml_symlink *rec)
674 {
675         CDEBUG (D_KML, " === SYMLINK\n");
676         CDEBUG (D_KML, "     s-path::%s\n", rec->sourcepath);
677         CDEBUG (D_KML, "     t-path::%s\n", rec->targetpath);
678         CDEBUG (D_KML, "     old_parv::%s\n", kml_version (&rec->old_parentv));
679         CDEBUG (D_KML, "     new_parv::%s\n", kml_version (&rec->new_parentv));
680         CDEBUG (D_KML, "     new_objv::%s\n", kml_version (&rec->new_objectv));
681         CDEBUG (D_KML, "     uid::%d\n", rec->uid);
682         CDEBUG (D_KML, "     gid::%d\n", rec->gid);
683 }
684
685 static void print_kml_rename (struct kml_rename *rec)
686 {
687         CDEBUG (D_KML, " === RENAME\n");
688         CDEBUG (D_KML, "     s-path::%s\n", rec->sourcepath);
689         CDEBUG (D_KML, "     t-path::%s\n", rec->targetpath);
690         CDEBUG (D_KML, "     old_tgtv::%s\n", kml_version (&rec->old_tgtv));
691         CDEBUG (D_KML, "     new_tgtv::%s\n", kml_version (&rec->new_tgtv));
692         CDEBUG (D_KML, "     new_objv::%s\n", kml_version (&rec->new_objectv));
693         CDEBUG (D_KML, "     old_objv::%s\n", kml_version (&rec->old_objectv));
694 }
695
696 static void print_kml_setattr (struct kml_setattr *rec)
697 {
698         CDEBUG (D_KML, " === SETATTR\n");
699         CDEBUG (D_KML, "     path::%s\n", rec->path);
700         CDEBUG (D_KML, "     old_objv::%s\n", kml_version (&rec->old_objectv));
701         CDEBUG (D_KML, "     valid::0x%x\n", rec->iattr.ia_valid);
702         CDEBUG (D_KML, "     mode::%o\n", rec->iattr.ia_mode);
703         CDEBUG (D_KML, "     uid::%d\n", rec->iattr.ia_uid);
704         CDEBUG (D_KML, "     gid::%d\n", rec->iattr.ia_gid);
705         CDEBUG (D_KML, "     size::%u\n", (u32) rec->iattr.ia_size);
706         CDEBUG (D_KML, "     mtime::%u\n", (u32) rec->iattr.ia_mtime);
707         CDEBUG (D_KML, "     ctime::%u\n", (u32) rec->iattr.ia_ctime);
708         CDEBUG (D_KML, "     flags::%u\n", (u32) rec->iattr.ia_attr_flags);
709 }
710
711 static void print_kml_link (struct kml_link *rec)
712 {
713         CDEBUG (D_KML, " === LINK\n");
714         CDEBUG (D_KML, "     path::%s ==> %s\n", rec->sourcepath, rec->targetpath);
715         CDEBUG (D_KML, "     old_parv::%s\n", kml_version (&rec->old_parentv));
716         CDEBUG (D_KML, "     new_obj::%s\n", kml_version (&rec->new_objectv));
717         CDEBUG (D_KML, "     new_parv::%s\n", kml_version (&rec->new_parentv));
718 }
719
720 static void print_kml_mknod (struct kml_mknod *rec)
721 {
722         CDEBUG (D_KML, " === MKNOD\n");
723         CDEBUG (D_KML, "     path::%s\n", rec->path);
724         CDEBUG (D_KML, "     new_obj::%s\n", kml_version (&rec->new_objectv));
725         CDEBUG (D_KML, "     old_parv::%s\n", kml_version (&rec->old_parentv));
726         CDEBUG (D_KML, "     new_parv::%s\n", kml_version (&rec->new_parentv));
727         CDEBUG (D_KML, "     mode::%o\n", rec->mode);
728         CDEBUG (D_KML, "     uid::%d\n", rec->uid);
729         CDEBUG (D_KML, "     gid::%d\n", rec->gid);
730         CDEBUG (D_KML, "     major::%d\n", rec->major);
731         CDEBUG (D_KML, "     minor::%d\n", rec->minor);
732 }
733
734 static void print_kml_open (struct kml_open *rec)
735 {
736         CDEBUG (D_KML, " === OPEN\n");
737 }
738
739 #if 0
740 static void print_kml_endmark (struct kml_endmark *rec)
741 {
742         int i;
743         CDEBUG (D_KML, " === ENDMARK\n");
744         CDEBUG (D_KML, "     total::%u\n", rec->total);
745         for (i = 0; i < rec->total; i++)
746         {       
747                 CDEBUG (D_KML, "         recno=%ld::flag=%ld,op=%ld, i_ino=%ld, \
748                         i_nlink=%ld\n", (long) rec->kop[i].kml_recno, 
749                         (long) rec->kop[i].kml_flag, (long) rec->kop[i].kml_op, 
750                         (long) rec->kop[i].i_ino, (long) rec->kop[i].i_nlink);
751         }
752 }
753 #endif
754
755 static void print_kml_optimize (struct kml_optimize  *rec)
756 {
757         CDEBUG (D_KML, " === OPTIMIZE\n");
758         if (rec->kml_flag == KML_REC_DELETE)
759                 CDEBUG (D_KML, "     kml_flag::deleted\n");
760         else
761                 CDEBUG (D_KML, "     kml_flag::exist\n");
762         CDEBUG (D_KML, "     kml_op::%u\n", rec->kml_op);
763         CDEBUG (D_KML, "     i_nlink::%d\n", rec->i_nlink);
764         CDEBUG (D_KML, "     i_ino::%u\n", rec->i_ino);
765 }
766
767 static void print_kml_suffix (struct journal_suffix *tail)
768 {
769         CDEBUG (D_KML, " === KML SUFFIX\n");
770         CDEBUG (D_KML, "     prevrec::%ld\n", tail->prevrec);
771         CDEBUG (D_KML, "     recno::%ld\n", (long) tail->recno);
772         CDEBUG (D_KML, "     time::%d\n", tail->time);
773         CDEBUG (D_KML, "     len::%d\n", tail->len);
774 }
775
776 void kml_printrec (struct kml_rec *rec, int kml_printop)
777 {
778         if (kml_printop & PRINT_KML_PREFIX)
779                 print_kml_prefix (&rec->rec_head);
780         if (kml_printop & PRINT_KML_REC) 
781         { 
782                 switch (rec->rec_head.opcode)
783                 {
784                         case KML_CREATE:
785                                 print_kml_create (&rec->rec_kml.create);
786                                 break;
787                         case KML_MKDIR:
788                                 print_kml_mkdir (&rec->rec_kml.mkdir);
789                                 break;
790                         case KML_UNLINK:
791                                 print_kml_unlink (&rec->rec_kml.unlink);
792                                 break;
793                         case KML_RMDIR:
794                                 print_kml_rmdir (&rec->rec_kml.rmdir);
795                                 break;
796                         case KML_CLOSE:
797                                 print_kml_close (&rec->rec_kml.close);
798                                 break;
799                         case KML_SYMLINK:
800                                 print_kml_symlink (&rec->rec_kml.symlink);
801                                 break;
802                         case KML_RENAME:
803                                 print_kml_rename (&rec->rec_kml.rename);
804                                 break;
805                         case KML_SETATTR:
806                                 print_kml_setattr (&rec->rec_kml.setattr);
807                                 break;
808                         case KML_LINK:
809                                 print_kml_link (&rec->rec_kml.link);
810                                 break;
811                         case KML_OPEN:
812                                 print_kml_open (&rec->rec_kml.open);
813                                 break;
814                         case KML_MKNOD:
815                                 print_kml_mknod (&rec->rec_kml.mknod);
816                                 break;
817 #if 0
818                         case KML_ENDMARK:
819                                 print_kml_endmark (&rec->rec_kml.endmark);
820 #endif
821                                 break;
822                         default:
823                                 CDEBUG (D_KML, " === BAD RECORD, opcode=%u\n",
824                                         rec->rec_head.opcode);
825                                 break;
826                 }
827         }
828         if (kml_printop & PRINT_KML_SUFFIX)
829                 print_kml_suffix (&rec->rec_tail);
830         if (kml_printop & PRINT_KML_OPTIMIZE)
831                 print_kml_optimize (&rec->kml_optimize);
832 }
833
834 void kml_freerec (struct kml_rec *rec)
835 {
836         char *sourcepath = NULL,
837              *targetpath = NULL;
838         switch (rec->rec_head.opcode)
839         {
840                 case KML_CREATE:
841                         sourcepath = rec->rec_kml.create.path;
842                         break;
843                 case KML_MKDIR:
844                         sourcepath = rec->rec_kml.create.path;
845                         break;
846                 case KML_UNLINK:
847                         sourcepath = rec->rec_kml.unlink.path;
848                         targetpath = rec->rec_kml.unlink.name;
849                         break;
850                 case KML_RMDIR:
851                         sourcepath = rec->rec_kml.rmdir.path;
852                         targetpath = rec->rec_kml.rmdir.name;
853                         break;
854                 case KML_CLOSE:
855                         sourcepath = rec->rec_kml.close.path;
856                         break;
857                 case KML_SYMLINK:
858                         sourcepath = rec->rec_kml.symlink.sourcepath;
859                         targetpath = rec->rec_kml.symlink.targetpath;
860                         break;
861                 case KML_RENAME:
862                         sourcepath = rec->rec_kml.rename.sourcepath;
863                         targetpath = rec->rec_kml.rename.targetpath;
864                         break;
865                 case KML_SETATTR:
866                         sourcepath = rec->rec_kml.setattr.path;
867                         break;
868                 case KML_LINK:
869                         sourcepath = rec->rec_kml.link.sourcepath;
870                         targetpath = rec->rec_kml.link.targetpath;
871                         break;
872                 case KML_OPEN:
873                         break;
874                 case KML_MKNOD:
875                         sourcepath = rec->rec_kml.mknod.path;
876                         break;
877 #if 0
878                 case KML_ENDMARK:
879                         PRESTO_FREE (rec->rec_kml.endmark.kop, sizeof (int) + 
880                                 sizeof (struct kml_kop_node) * 
881                                 rec->rec_kml.endmark.total);
882 #endif
883                         break;
884                 default:
885                         break;
886         }
887         if (sourcepath != NULL)
888                 PRESTO_FREE (sourcepath, strlen (sourcepath) + 1);
889         if (targetpath != NULL)
890                 PRESTO_FREE (targetpath, strlen (targetpath) + 1);
891 }
892
893 char *readrec (char *recbuf, int reclen, int pos, int *size)
894 {
895         char *p = recbuf + pos;
896         *size = *((int *) p);
897         if (*size > (reclen - pos))
898             return NULL;
899         return p; 
900 }
901
902 int kml_decoderec (char *buf, int pos, int buflen, int *size, 
903                         struct kml_rec **newrec)
904 {
905         char *tmp;
906         int  error;
907         tmp = readrec (buf, buflen, pos, size);
908         if (tmp == NULL)
909                 return -EBADF;
910         error = kml_unpack (tmp, *size, pos, newrec); 
911         return error;
912 }
913
914 #if 0
915 static void fill_kmlrec_optimize (struct list_head *head, 
916                 struct kml_rec *optrec)
917 {
918         struct kml_rec *kmlrec;
919         struct list_head *tmp;
920         struct kml_endmark *km;
921         struct kml_optimize *ko;
922         int    n;
923
924         if (optrec->rec_kml.endmark.total == 0)
925                 return;
926         n = optrec->rec_kml.endmark.total - 1;
927         tmp = head->prev;
928         km = &optrec->rec_kml.endmark;
929         while ( n >= 0 && tmp != head ) 
930         {
931                 kmlrec = list_entry(tmp, struct kml_rec,
932                         kml_optimize.kml_chains);
933                 tmp = tmp->prev;
934                 if (kmlrec->rec_tail.recno == km->kop[n].kml_recno) 
935                 {
936                         ko = &kmlrec->kml_optimize;
937                         ko->kml_flag = km->kop[n].kml_flag;
938                         ko->kml_op   = km->kop[n].kml_op;
939                         ko->i_nlink  = km->kop[n].i_nlink;
940                         ko->i_ino    = km->kop[n].i_ino;
941                         n --;
942                 }
943         }
944         if (n != -1)
945                 CDEBUG (D_KML, "Yeah!!!, KML optimize error, recno=%d, n=%d\n",
946                         optrec->rec_tail.recno, n);     
947 }
948 #endif
949
950 int decode_kmlrec (struct list_head *head, char *kml_buf, int buflen)
951 {
952         struct kml_rec *rec;
953         int    pos = 0, size;
954         int    err;
955         while (pos < buflen) {
956                 err = kml_decoderec (kml_buf, pos, buflen, &size, &rec);
957                 if (err != 0)
958                         break;
959 #if 0
960                 if (rec->rec_head.opcode == KML_ENDMARK) {
961                         fill_kmlrec_optimize (head, rec);
962                         mark_rec_deleted (rec);
963                 }
964 #endif
965                 list_add_tail (&rec->kml_optimize.kml_chains, head);
966                 pos += size;
967         }
968         return err;
969 }
970
971 int delete_kmlrec (struct list_head *head)
972 {
973         struct kml_rec *rec;
974         struct list_head *tmp;
975
976         if (list_empty(head))
977                 return 0;
978         tmp = head->next;
979         while ( tmp != head ) {
980                 rec = list_entry(tmp, struct kml_rec, 
981                         kml_optimize.kml_chains);
982                 tmp = tmp->next;
983                 kml_freerec (rec);
984         }
985         INIT_LIST_HEAD(head);
986         return 0;
987 }
988
989 int print_allkmlrec (struct list_head *head, int printop)
990 {
991         struct kml_rec *rec;
992         struct list_head *tmp;
993
994         if (list_empty(head))
995                 return 0;
996         tmp = head->next;
997         while ( tmp != head ) {
998                 rec = list_entry(tmp, struct kml_rec,
999                         kml_optimize.kml_chains);
1000                 tmp = tmp->next;
1001 #if 0
1002                 if (printop & PRINT_KML_EXIST) {
1003                         if (is_deleted_node (rec))
1004                                 continue;
1005                 }
1006                 else if (printop & PRINT_KML_DELETE) {
1007                         if (! is_deleted_node (rec))
1008                                 continue;
1009                 }
1010 #endif
1011                 kml_printrec (rec, printop);
1012         }
1013         INIT_LIST_HEAD(head);
1014         return 0;
1015 }
1016