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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * KML REINT
  3.  *
  4.  * Copryright (C) 1996 Arthur Ma <arthur.ma@mountainviewdata.com>
  5.  *
  6.  * Copyright (C) 2000 Mountainview Data, Inc.
  7.  */
  8. #define __NO_VERSION__
  9. #include <linux/module.h>
  10. #include <linux/errno.h>
  11. #include <linux/fs.h>
  12. #include <linux/kernel.h>
  13. #include <linux/major.h>
  14. #include <linux/slab.h>
  15. #include <linux/vmalloc.h>
  16. #include <linux/mm.h>
  17. #include <asm/uaccess.h>
  18. #include <asm/pgtable.h>
  19. #include <asm/mmu_context.h>
  20. #include <linux/intermezzo_fs.h>
  21. #include <linux/intermezzo_kml.h>
  22. #include <linux/intermezzo_psdev.h>
  23. #include <linux/intermezzo_upcall.h>
  24. static void kmlreint_pre_secure (struct kml_rec *rec);
  25. static void kmlreint_post_secure (struct kml_rec *rec);
  26. static void kmlreint_pre_secure (struct kml_rec *rec)
  27. {
  28.         if (current->fsuid != current->uid)
  29.                 CDEBUG (D_KML, "reint_kmlreint_pre_secure: cannot setfsuidn");
  30.         if (current->fsgid != current->gid)
  31.                 CDEBUG (D_KML, "reint_kmlreint_pre_secure: cannot setfsgidn");
  32.         current->fsuid = rec->rec_head.uid;
  33.         current->fsgid = rec->rec_head.fsgid;
  34. }
  35. static void kmlreint_post_secure (struct kml_rec *rec)
  36. {
  37.         current->fsuid = current->uid; 
  38.         current->fsgid = current->gid;
  39.         /* current->egid = current->gid; */ 
  40.         /* ????????????? */
  41. }
  42. static int reint_create (int slot_offset, struct kml_rec *rec)
  43. {
  44.         struct  lento_vfs_context info;
  45.         struct  kml_create *create = &rec->rec_kml.create;
  46.         mm_segment_t old_fs;
  47.         int     error;
  48.         ENTRY;
  49.         kmlreint_pre_secure (rec);
  50.         info.slot_offset = slot_offset;
  51.         info.recno = rec->rec_tail.recno;
  52.         info.kml_offset = rec->rec_kml_offset;
  53.         info.flags = 0; 
  54.         CDEBUG (D_KML, "=====REINT_CREATE::%sn", create->path);
  55.         old_fs = get_fs();
  56.         set_fs (get_ds());
  57.         error = lento_create(create->path, create->mode, &info);
  58.         set_fs (old_fs);
  59.         kmlreint_post_secure (rec);
  60.         EXIT;
  61.         return error;
  62. }
  63. static int reint_open (int slot_offset, struct kml_rec *rec)
  64. {
  65.         return 0;
  66. }
  67. static int reint_mkdir (int slot_offset, struct kml_rec *rec)
  68. {
  69.         struct  lento_vfs_context info;
  70.         struct  kml_mkdir *mkdir = &rec->rec_kml.mkdir;
  71.         mm_segment_t old_fs;
  72.         int     error;
  73.         ENTRY;
  74.         kmlreint_pre_secure (rec);
  75.         info.slot_offset = slot_offset;
  76.         info.recno = rec->rec_tail.recno;
  77.         info.kml_offset = rec->rec_kml_offset;
  78.         info.flags = 0; 
  79.         old_fs = get_fs();
  80.         set_fs (get_ds());
  81.         error = lento_mkdir (mkdir->path, mkdir->mode, &info);
  82.         set_fs (old_fs);
  83.         kmlreint_post_secure (rec);
  84.         EXIT;
  85.         return error;
  86. }
  87. static int reint_rmdir (int slot_offset, struct kml_rec *rec)
  88. {
  89.         struct  kml_rmdir  *rmdir = &rec->rec_kml.rmdir;
  90.         struct  lento_vfs_context info;
  91.         mm_segment_t old_fs;
  92.         char *name;
  93.         int error;
  94.         ENTRY;
  95.         kmlreint_pre_secure (rec);
  96.         name = bdup_printf ("%s/%s", rmdir->path, rmdir->name);
  97.         if (name == NULL)
  98.         {
  99.                 kmlreint_post_secure (rec);
  100.                 EXIT;
  101.                 return -ENOMEM;
  102.         }
  103.         info.slot_offset = slot_offset;
  104.         info.recno = rec->rec_tail.recno;
  105.         info.kml_offset = rec->rec_kml_offset;
  106.         info.flags = 0;
  107.         old_fs = get_fs();
  108.         set_fs (get_ds());
  109.         error = lento_rmdir (name, &info);
  110.         set_fs (old_fs);
  111.         PRESTO_FREE (name, strlen (name) + 1);
  112.         kmlreint_post_secure (rec);
  113.         EXIT;
  114.         return error;
  115. }
  116. static int reint_link (int slot_offset, struct kml_rec *rec)
  117. {
  118.         struct  kml_link *link = &rec->rec_kml.link;
  119.         struct  lento_vfs_context info;
  120.         mm_segment_t old_fs;
  121.         int     error;
  122.         ENTRY;
  123.         kmlreint_pre_secure (rec);
  124.         info.slot_offset = slot_offset;
  125.         info.recno = rec->rec_tail.recno;
  126.         info.kml_offset = rec->rec_kml_offset;
  127.         info.flags = 0; 
  128.         old_fs = get_fs();
  129.         set_fs (get_ds());
  130.         error = lento_link (link->sourcepath, link->targetpath, &info);
  131.         set_fs (old_fs);
  132.         kmlreint_post_secure (rec);
  133.         EXIT;
  134.         return error;
  135. }
  136. static int reint_unlink (int slot_offset, struct kml_rec *rec)
  137. {
  138.         struct  kml_unlink *unlink = &rec->rec_kml.unlink;
  139.         struct  lento_vfs_context info;
  140.         mm_segment_t old_fs;
  141.         int     error;
  142.         char   *name;
  143.         ENTRY;
  144.         kmlreint_pre_secure (rec);
  145.         name = bdup_printf ("%s/%s", unlink->path, unlink->name);
  146.         if (name == NULL)
  147.         {
  148.                 kmlreint_post_secure (rec);
  149.                 EXIT;
  150.                 return -ENOMEM;
  151.         }
  152.         info.slot_offset = slot_offset;
  153.         info.recno = rec->rec_tail.recno;
  154.         info.kml_offset = rec->rec_kml_offset;
  155.         info.flags = 0;
  156.         old_fs = get_fs();
  157.         set_fs (get_ds());
  158.         error = lento_unlink (name, &info);
  159.         set_fs (old_fs);
  160.         PRESTO_FREE (name, strlen (name));
  161.         kmlreint_post_secure (rec);
  162.         EXIT;
  163.         return error;
  164. }
  165. static int reint_symlink (int slot_offset, struct kml_rec *rec)
  166. {
  167.         struct  kml_symlink *symlink = &rec->rec_kml.symlink;
  168.         struct  lento_vfs_context info;
  169.         mm_segment_t old_fs;
  170.         int     error;
  171.         ENTRY;
  172.         kmlreint_pre_secure (rec);
  173.         info.slot_offset = slot_offset;
  174.         info.recno = rec->rec_tail.recno;
  175.         info.kml_offset = rec->rec_kml_offset;
  176.         info.flags = 0; 
  177.         old_fs = get_fs();
  178.         set_fs (get_ds());
  179.         error = lento_symlink (symlink->targetpath, 
  180.                         symlink->sourcepath, &info);
  181.         set_fs (old_fs);
  182.         kmlreint_post_secure (rec);
  183.         EXIT;
  184.         return error;
  185. }
  186. static int reint_rename (int slot_offset, struct kml_rec *rec)
  187. {
  188.         struct  kml_rename *rename = &rec->rec_kml.rename;
  189.         struct  lento_vfs_context info;
  190.         mm_segment_t old_fs;
  191.         int     error;
  192.         ENTRY;
  193.         kmlreint_pre_secure (rec);
  194.         info.slot_offset = slot_offset;
  195.         info.recno = rec->rec_tail.recno;
  196.         info.kml_offset = rec->rec_kml_offset;
  197.         info.flags = 0;
  198.         old_fs = get_fs();
  199.         set_fs (get_ds());
  200.         error = lento_rename (rename->sourcepath, rename->targetpath, &info);
  201.         set_fs (old_fs);
  202.         kmlreint_post_secure (rec);
  203.         EXIT;
  204.         return error;
  205. }
  206. static int reint_setattr (int slot_offset, struct kml_rec *rec)
  207. {
  208.         struct  kml_setattr *setattr = &rec->rec_kml.setattr;
  209.         struct  lento_vfs_context info;
  210.         mm_segment_t old_fs;
  211.         int     error;
  212.         ENTRY;
  213.         kmlreint_pre_secure (rec);
  214.         info.slot_offset = slot_offset;
  215.         info.recno = rec->rec_tail.recno;
  216.         info.kml_offset = rec->rec_kml_offset;
  217.         info.flags = setattr->iattr.ia_attr_flags;
  218.         old_fs = get_fs();
  219.         set_fs (get_ds());
  220.         error = lento_setattr (setattr->path, &setattr->iattr, &info);
  221.         set_fs (old_fs);
  222.         kmlreint_post_secure (rec);
  223.         EXIT;
  224.         return error;
  225. }
  226. static int reint_mknod (int slot_offset, struct kml_rec *rec)
  227. {
  228.         struct  kml_mknod *mknod = &rec->rec_kml.mknod;
  229.         struct  lento_vfs_context info;
  230.         mm_segment_t old_fs;
  231.         int     error;
  232.         ENTRY;
  233.         kmlreint_pre_secure (rec);
  234.         info.slot_offset = slot_offset;
  235.         info.recno = rec->rec_tail.recno;
  236.         info.kml_offset = rec->rec_kml_offset;
  237.         info.flags = 0;
  238.         old_fs = get_fs();
  239.         set_fs (get_ds());
  240.         error = lento_mknod (mknod->path, mknod->mode, 
  241.                 MKDEV(mknod->major, mknod->minor), &info);
  242.         set_fs (old_fs);
  243.         kmlreint_post_secure (rec);
  244.         EXIT;
  245.         return error;
  246. }
  247. int kml_reint (char *mtpt, int slot_offset, struct kml_rec *rec)
  248. {
  249.         int error = 0;
  250.         switch (rec->rec_head.opcode)
  251.         {
  252.                 case KML_CREATE:
  253.                         error = reint_create (slot_offset, rec);
  254.                         break;
  255.                 case KML_OPEN:
  256.                         error = reint_open (slot_offset, rec);
  257.                         break;
  258.                 case KML_CLOSE:
  259.                         /* error = reint_close (slot_offset, rec);
  260.                            force the system to return to lento */
  261.                         error = KML_CLOSE_BACKFETCH;
  262.                         break;
  263.                 case KML_MKDIR:
  264.                         error = reint_mkdir (slot_offset, rec);
  265.                         break;
  266.                 case KML_RMDIR:
  267.                         error = reint_rmdir (slot_offset, rec);
  268.                         break;
  269.                 case KML_UNLINK:
  270.                         error = reint_unlink (slot_offset, rec);
  271.                         break;
  272.                 case KML_LINK:
  273.                         error =  reint_link (slot_offset, rec);
  274.                         break;
  275.                 case KML_SYMLINK:
  276.                         error = reint_symlink (slot_offset, rec);
  277.                         break;
  278.                 case KML_RENAME:
  279.                         error = reint_rename (slot_offset, rec);
  280.                         break;
  281.                 case KML_SETATTR:
  282.                         error =  reint_setattr (slot_offset, rec);
  283.                         break;
  284.                 case KML_MKNOD:
  285.                         error = reint_mknod (slot_offset, rec);
  286.                         break;
  287.                 default:
  288.                         CDEBUG (D_KML, "wrong opcode::%dn", rec->rec_head.opcode);
  289.                         return -EBADF;
  290.         }
  291.         if (error != 0 && error != KML_CLOSE_BACKFETCH)
  292.                 CDEBUG (D_KML, "KML_ERROR::error = %dn", error);
  293.         return error;
  294. }
  295. /* return the old mtpt */
  296. /*
  297. struct fs_struct {
  298.         atomic_t count;
  299.         int umask;
  300.         struct dentry * root, * pwd;
  301. };
  302. */
  303. static int do_set_fs_root (struct dentry *newroot, 
  304.                                         struct dentry **old_root)
  305. {
  306.         struct dentry *de = current->fs->root;
  307.         current->fs->root = newroot;
  308. if (old_root != (struct dentry **) NULL)
  309.          *old_root = de;
  310.         return 0;
  311. }
  312. static int set_system_mtpt (char *mtpt, struct dentry **old_root)
  313. {
  314. struct nameidata nd;
  315.         struct dentry *dentry;
  316. int error;
  317. if (path_init(pathname, LOOKUP_PARENT, &nd))
  318. error = path_walk(mtpt, &nd);
  319.         if (error) {
  320.                 CDEBUG (D_KML, "Yean!!!!::Can't find mtpt::%sn", mtpt);
  321.                 return error;
  322. }
  323.         dentry = nd.dentry;
  324.         error = do_set_fs_root (dentry, old_root);
  325.         path_release (&nd);
  326.         return error;
  327. }
  328. int kml_reintbuf (struct  kml_fsdata *kml_fsdata,
  329.                   char *mtpt, struct kml_rec **close_rec)
  330. {
  331.         struct kml_rec *rec = NULL;
  332.         struct list_head *head, *tmp;
  333.         struct dentry *old_root;
  334.         int    error = 0;
  335.         head = &kml_fsdata->kml_reint_cache;
  336.         if (list_empty(head))
  337.                 return 0;
  338.         if (kml_fsdata->kml_reint_current == NULL ||
  339.             kml_fsdata->kml_reint_current == head->next)
  340.                 return 0;
  341.         error = set_system_mtpt (mtpt, &old_root);
  342.         if (error)
  343.                 return error;
  344.         tmp = head->next;
  345.         while (error == 0 &&  tmp != head ) {
  346.                 rec = list_entry(tmp, struct kml_rec, kml_optimize.kml_chains);
  347.                 error = kml_reint (mtpt, rec->rec_kml_offset, rec);
  348.                 tmp = tmp->next;
  349.         }
  350.         do_set_fs_root (old_root, NULL);
  351.         if (error == KML_CLOSE_BACKFETCH)
  352.                 *close_rec = rec;
  353.         kml_fsdata->kml_reint_current = tmp;
  354.         return error;
  355. }