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

嵌入式Linux

开发平台:

Unix_Linux

  1. #include <linux/errno.h>
  2. #include <linux/slab.h>
  3. #include <linux/vmalloc.h>
  4. #define __NO_VERSION__
  5. #include <linux/module.h>
  6. #include <asm/uaccess.h>
  7. #include <linux/intermezzo_fs.h>
  8. #include <linux/intermezzo_upcall.h>
  9. #include <linux/intermezzo_psdev.h>
  10. #include <linux/intermezzo_kml.h>
  11. static struct presto_file_set * kml_getfset (char *path)
  12. {
  13.         return presto_path2fileset(path);
  14. }
  15. /* Send the KML buffer and related volume info into kernel */
  16. int begin_kml_reint (struct file *file, unsigned long arg)
  17. {
  18.         struct {
  19.                 char *volname;
  20.                 int   namelen;  
  21.                 char *recbuf;
  22.                 int   reclen;     /* int   newpos; */
  23.         } input;
  24.         struct kml_fsdata *kml_fsdata = NULL;
  25.         struct presto_file_set *fset = NULL;
  26.         char   *path;
  27.         int    error;
  28.         ENTRY;
  29.         /* allocate buffer & copy it to kernel space */
  30.         error = copy_from_user(&input, (char *)arg, sizeof(input));
  31.         if ( error ) {
  32.                 EXIT;
  33.                 return error;
  34.         }
  35.         if (input.reclen > kml_fsdata->kml_maxsize)
  36.                 return -ENOMEM; /* we'll find solution to this in the future */
  37.         PRESTO_ALLOC(path, char *, input.namelen + 1);
  38.         if ( !path ) {
  39.                 EXIT;
  40.                 return -ENOMEM;
  41.         }
  42.         error = copy_from_user(path, input.volname, input.namelen);
  43.         if ( error ) {
  44.                 PRESTO_FREE(path, input.namelen + 1);
  45.                 EXIT;
  46.                 return error;
  47.         }
  48.         path[input.namelen] = '';
  49.         fset = kml_getfset (path);
  50.         PRESTO_FREE(path, input.namelen + 1);
  51.         kml_fsdata = FSET_GET_KMLDATA(fset);
  52.         /* read the buf from user memory here */
  53.         error = copy_from_user(kml_fsdata->kml_buf, input.recbuf, input.reclen);
  54.         if ( error ) {
  55.                 EXIT;
  56.                 return error;
  57.         }
  58.         kml_fsdata->kml_len = input.reclen;
  59.         decode_kmlrec (&kml_fsdata->kml_reint_cache,
  60.                         kml_fsdata->kml_buf, kml_fsdata->kml_len);
  61.         kml_fsdata->kml_reint_current = kml_fsdata->kml_reint_cache.next;
  62.         kml_fsdata->kml_reintpos = 0;
  63.         kml_fsdata->kml_count = 0;
  64.         return 0;
  65. }
  66. /* DO_KML_REINT  */
  67. int do_kml_reint (struct file *file, unsigned long arg)
  68. {
  69.         struct {
  70.                 char *volname;
  71.                 int   namelen;  
  72.                 char *path;
  73.                 int pathlen;
  74.                 int recno;
  75.                 int offset;
  76.                 int len;
  77.                 int generation;
  78.                 __u64 ino;
  79.         } input;
  80.         int error;
  81.         char   *path;
  82.         struct kml_rec *close_rec;
  83.         struct kml_fsdata *kml_fsdata;
  84.         struct presto_file_set *fset;
  85.         ENTRY;
  86.         error = copy_from_user(&input, (char *)arg, sizeof(input));
  87.         if ( error ) {
  88.                 EXIT;
  89.                 return error;
  90.         }
  91.         PRESTO_ALLOC(path, char *, input.namelen + 1);
  92.         if ( !path ) {
  93.                 EXIT;
  94.                 return -ENOMEM;
  95.         }
  96.         error = copy_from_user(path, input.volname, input.namelen);
  97.         if ( error ) {
  98.                 PRESTO_FREE(path, input.namelen + 1);
  99.                 EXIT;
  100.                 return error;
  101.         }
  102.         path[input.namelen] = '';
  103.         fset = kml_getfset (path);
  104.         PRESTO_FREE(path, input.namelen + 1);
  105.         kml_fsdata = FSET_GET_KMLDATA(fset);
  106.         error = kml_reintbuf(kml_fsdata, 
  107.                 fset->fset_mtpt->d_name.name, 
  108.                 &close_rec);
  109.         if (error == KML_CLOSE_BACKFETCH && close_rec != NULL) {
  110.                 struct kml_close *close = &close_rec->rec_kml.close;
  111.                 input.ino = close->ino;
  112.                 input.generation = close->generation;
  113.                 if (strlen (close->path) + 1 < input.pathlen) {
  114.                         strcpy (input.path, close->path);
  115.                         input.pathlen = strlen (close->path) + 1;
  116.                         input.recno = close_rec->rec_tail.recno;
  117.                         input.offset = close_rec->rec_kml_offset;
  118.                         input.len = close_rec->rec_size;
  119.                         input.generation = close->generation;
  120.                         input.ino = close->ino;
  121.                 }
  122.                 else {
  123.                         CDEBUG(D_KML, "KML_DO_REINT::no space to save:%d < %d",
  124.                                 strlen (close->path) + 1, input.pathlen);
  125.                         error = -ENOMEM;
  126.                 }
  127.                 copy_to_user((char *)arg, &input, sizeof (input));
  128.         }
  129.         return error;
  130. }
  131. /* END_KML_REINT */
  132. int end_kml_reint (struct file *file, unsigned long arg)
  133. {
  134.         /* Free KML buffer and related volume info */
  135.         struct {
  136.                 char *volname;
  137.                 int   namelen;  
  138. #if 0
  139.                 int   count; 
  140.                 int   newpos; 
  141. #endif
  142.         } input;
  143.         struct presto_file_set *fset = NULL;
  144.         struct kml_fsdata *kml_fsdata = NULL;
  145.         int error;
  146.         char *path;
  147.         ENTRY;
  148.         error = copy_from_user(&input, (char *)arg, sizeof(input));
  149.         if ( error ) {
  150.                EXIT;
  151.                return error;
  152.         }
  153.         PRESTO_ALLOC(path, char *, input.namelen + 1);
  154.         if ( !path ) {
  155.                 EXIT;
  156.                 return -ENOMEM;
  157.         }
  158.         error = copy_from_user(path, input.volname, input.namelen);
  159.         if ( error ) {
  160.                 PRESTO_FREE(path, input.namelen + 1);
  161.                 EXIT;
  162.                 return error;
  163.         }
  164.         path[input.namelen] = '';
  165.         fset = kml_getfset (path);
  166.         PRESTO_FREE(path, input.namelen + 1);
  167.         kml_fsdata = FSET_GET_KMLDATA(fset);
  168.         delete_kmlrec (&kml_fsdata->kml_reint_cache);
  169.         /* kml reint support */
  170.         kml_fsdata->kml_reint_current = NULL;
  171.         kml_fsdata->kml_len = 0;
  172.         kml_fsdata->kml_reintpos = 0;
  173.         kml_fsdata->kml_count = 0;
  174. #if 0
  175.         input.newpos = kml_upc->newpos;
  176.         input.count = kml_upc->count;
  177.         copy_to_user((char *)arg, &input, sizeof (input));
  178. #endif
  179.         return error;
  180. }