kml_decode.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:35k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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