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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Mostly platform independent upcall operations to Venus:
  3.  *  -- upcalls
  4.  *  -- upcall routines
  5.  *
  6.  * Linux 2.0 version
  7.  * Copyright (C) 1996 Peter J. Braam <braam@cs.cmu.edu>,
  8.  * Michael Callahan <callahan@maths.ox.ac.uk>
  9.  *
  10.  * Redone for Linux 2.1
  11.  * Copyright (C) 1997 Carnegie Mellon University
  12.  *
  13.  * Carnegie Mellon University encourages users of this code to contribute
  14.  * improvements to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
  15.  *
  16.  * Much cleaned up for InterMezzo
  17.  * Copyright (C) 1998 Peter J. Braam <braam@cs.cmu.edu>,
  18.  * Copyright (C) 1999 Carnegie Mellon University
  19.  *
  20.  */
  21. #include <asm/system.h>
  22. #include <asm/segment.h>
  23. #include <asm/signal.h>
  24. #include <linux/signal.h>
  25. #include <linux/types.h>
  26. #include <linux/kernel.h>
  27. #include <linux/mm.h>
  28. #include <linux/vmalloc.h>
  29. #include <linux/slab.h>
  30. #include <linux/sched.h>
  31. #include <linux/fs.h>
  32. #include <linux/stat.h>
  33. #include <linux/errno.h>
  34. #include <linux/locks.h>
  35. #include <linux/string.h>
  36. #include <asm/uaccess.h>
  37. #include <linux/vmalloc.h>
  38. #include <asm/segment.h>
  39. #include <linux/intermezzo_fs.h>
  40. #include <linux/intermezzo_upcall.h>
  41. #include <linux/intermezzo_psdev.h>
  42. /*
  43.   At present: four upcalls
  44.   - opendir: fetch a directory (synchronous & asynchronous)
  45.   - open: fetch file (synchronous)
  46.   - journal: send a journal page (asynchronous)
  47.   - permit: get a permit (synchronous)
  48.   Errors returned here are positive.
  49.  */
  50. #define INSIZE(tag) sizeof(struct lento_ ## tag ## _in)
  51. #define OUTSIZE(tag) sizeof(struct lento_ ## tag ## _out)
  52. #define SIZE(tag)  ( (INSIZE(tag)>OUTSIZE(tag)) ? INSIZE(tag) : OUTSIZE(tag) )
  53. #define UPARG(op)
  54. do {
  55.         PRESTO_ALLOC(inp, union up_args *, insize);
  56.         if ( !inp ) { return -ENOMEM; }
  57.         outp = (union down_args *) (inp);
  58.         inp->uh.opcode = (op);
  59.         inp->uh.pid = current->pid;
  60.         inp->uh.uid = current->fsuid;
  61.         outsize = insize;
  62. } while (0)
  63. #define BUFF_ALLOC(buffer)                              
  64.         PRESTO_ALLOC(buffer, char *, PAGE_SIZE);        
  65.         if ( !buffer ) {                                
  66.                 printk("PRESTO: out of memory!n");     
  67.                 return -ENOMEM;                         
  68.         }
  69. /* the upcalls */
  70. int lento_kml(int minor, unsigned int offset, unsigned int first_recno,
  71.               unsigned int length, unsigned int last_recno, int namelen,
  72.               char *fsetname)
  73. {
  74.         union up_args *inp;
  75.         union down_args *outp;
  76.         int insize, outsize, error;
  77.         ENTRY;
  78.         if (!presto_lento_up(minor)) {
  79.                 EXIT;
  80.                 return 0;
  81.         }
  82.         insize = SIZE(kml) + namelen + 1;
  83.         UPARG(LENTO_KML);
  84.         inp->lento_kml.namelen = namelen;
  85.         memcpy(inp->lento_kml.fsetname, fsetname, namelen);
  86.         inp->lento_kml.fsetname[namelen] = '';
  87.         inp->lento_kml.offset = offset;
  88.         inp->lento_kml.first_recno = first_recno;
  89.         inp->lento_kml.length = length;
  90.         inp->lento_kml.last_recno = last_recno;
  91.         CDEBUG(D_UPCALL, "KML: fileset %s, offset %d, length %d, "
  92.                "first %d, last %d; minor %dn",
  93.                inp->lento_kml.fsetname,
  94.                inp->lento_kml.offset,
  95.                inp->lento_kml.length,
  96.                inp->lento_kml.first_recno,
  97.                inp->lento_kml.last_recno, minor);
  98.         error = lento_upcall(minor, insize, &outsize, inp,
  99.                              ASYNCHRONOUS, NULL);
  100.         EXIT;
  101.         return error;
  102. }
  103. int lento_release_permit( int minor, int mycookie )
  104. {
  105.         union up_args *inp;
  106.         union down_args *outp;
  107.         int insize, outsize, error;
  108.         ENTRY;
  109.         if (!presto_lento_up(minor)) {
  110.                 EXIT;
  111.                 return 0;
  112.         }
  113.         insize= SIZE(response_cookie);
  114.         UPARG(LENTO_COOKIE);
  115.         inp->lento_response_cookie.cookie= mycookie;
  116.         CDEBUG(D_UPCALL, "cookie %dn", mycookie);
  117.         error = lento_upcall(minor, insize, &outsize, inp,
  118.                              ASYNCHRONOUS, NULL);
  119.         EXIT;
  120.         return error;
  121. }
  122. int lento_opendir(int minor, int pathlen, char *path, int async)
  123. {
  124.         union up_args *inp;
  125.         union down_args *outp;
  126.         int insize, outsize, error;
  127.         ENTRY;
  128.         insize = SIZE(opendir) + pathlen + 1;
  129.         UPARG(LENTO_OPENDIR);
  130.         inp->lento_opendir.async = async;
  131.         inp->lento_opendir.pathlen = pathlen;
  132.         memcpy(inp->lento_opendir.path, path, pathlen);
  133.         inp->lento_opendir.path[pathlen] = '';
  134.         CDEBUG(D_UPCALL, "path %sn", inp->lento_opendir.path);
  135.         if (async) {
  136.                 error = lento_upcall(minor, insize, &outsize, inp,
  137.                                      ASYNCHRONOUS, NULL);
  138.                 return 0;
  139.         }
  140.         error = lento_upcall(minor, insize, &outsize, inp,
  141.                              SYNCHRONOUS, NULL);
  142.         if (error && error != EISFSETROOT) {
  143.                 printk("lento_opendir: error %dn", error);
  144.         }
  145.         EXIT;
  146.         return error;
  147. }
  148. int lento_open(int minor, int pathlen, char *path)
  149. {
  150.         union up_args *inp;
  151.         union down_args *outp;
  152.         int insize, outsize, error;
  153. ENTRY;
  154. insize = SIZE(open) + pathlen + 1;
  155. UPARG(LENTO_OPEN);
  156. inp->lento_open.pathlen = pathlen;
  157. memcpy(inp->lento_open.path, path, pathlen);
  158. inp->lento_open.path[pathlen] = '';
  159. CDEBUG(D_UPCALL, "path %sn", inp->lento_open.path);
  160. error = lento_upcall(minor, insize, &outsize, inp,
  161.      SYNCHRONOUS, NULL);
  162. if (error) {
  163.         printk("lento_open: error %dn", error);
  164. }
  165.         EXIT;
  166.         return error;
  167. }
  168. int lento_permit(int minor, int pathlen, int fsetnamelen, char *path, char *fsetname)
  169. {
  170.         union up_args *inp;
  171.         union down_args *outp;
  172.         int insize, outsize, error;
  173.         ENTRY;
  174.         insize = SIZE(permit) + pathlen + 1 + fsetnamelen + 1;
  175.         UPARG(LENTO_PERMIT);
  176.         inp->lento_permit.pathlen = pathlen;
  177.         inp->lento_permit.fsetnamelen = fsetnamelen;
  178.         memcpy(inp->lento_permit.path, path, pathlen);
  179.         inp->lento_permit.path[pathlen] = '';
  180. memcpy(&(inp->lento_permit.path[pathlen+1]), fsetname, fsetnamelen); 
  181.         inp->lento_permit.path[fsetnamelen + 1 + pathlen] = '';
  182.         CDEBUG(D_UPCALL, "Permit minor %d path %sn", minor,
  183.                inp->lento_permit.path);
  184.         error = lento_upcall(minor, insize, &outsize, inp,
  185.                              SYNCHRONOUS, NULL);
  186.         if (error) {
  187.                 if( error == -EROFS ) {
  188.                         int err;
  189.                         printk("lento_permit: ERROR - requested permit for "
  190.                                "read-only fileset.n"
  191.                                "   Setting "%s" read-only!n",
  192.                                path);
  193.                         err= presto_mark_cache(path, 0xFFFFFFFF, 
  194.                                                CACHE_CLIENT_RO, NULL);
  195.                         if( err ) {
  196.                                 printk("ERROR : mark_cache %dn", err);
  197.                         }
  198.                 }
  199.                 else {
  200.                         printk("lento_permit: error %dn", error);
  201.                 }
  202.         }
  203.         EXIT;
  204.         return error;
  205. }