upcall.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
- /*
- * Mostly platform independent upcall operations to Venus:
- * -- upcalls
- * -- upcall routines
- *
- * Linux 2.0 version
- * Copyright (C) 1996 Peter J. Braam <braam@cs.cmu.edu>,
- * Michael Callahan <callahan@maths.ox.ac.uk>
- *
- * Redone for Linux 2.1
- * Copyright (C) 1997 Carnegie Mellon University
- *
- * Carnegie Mellon University encourages users of this code to contribute
- * improvements to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
- *
- * Much cleaned up for InterMezzo
- * Copyright (C) 1998 Peter J. Braam <braam@cs.cmu.edu>,
- * Copyright (C) 1999 Carnegie Mellon University
- *
- */
- #include <asm/system.h>
- #include <asm/segment.h>
- #include <asm/signal.h>
- #include <linux/signal.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/mm.h>
- #include <linux/vmalloc.h>
- #include <linux/slab.h>
- #include <linux/sched.h>
- #include <linux/fs.h>
- #include <linux/stat.h>
- #include <linux/errno.h>
- #include <linux/locks.h>
- #include <linux/string.h>
- #include <asm/uaccess.h>
- #include <linux/vmalloc.h>
- #include <asm/segment.h>
- #include <linux/intermezzo_fs.h>
- #include <linux/intermezzo_upcall.h>
- #include <linux/intermezzo_psdev.h>
- /*
- At present: four upcalls
- - opendir: fetch a directory (synchronous & asynchronous)
- - open: fetch file (synchronous)
- - journal: send a journal page (asynchronous)
- - permit: get a permit (synchronous)
- Errors returned here are positive.
- */
- #define INSIZE(tag) sizeof(struct lento_ ## tag ## _in)
- #define OUTSIZE(tag) sizeof(struct lento_ ## tag ## _out)
- #define SIZE(tag) ( (INSIZE(tag)>OUTSIZE(tag)) ? INSIZE(tag) : OUTSIZE(tag) )
- #define UPARG(op)
- do {
- PRESTO_ALLOC(inp, union up_args *, insize);
- if ( !inp ) { return -ENOMEM; }
- outp = (union down_args *) (inp);
- inp->uh.opcode = (op);
- inp->uh.pid = current->pid;
- inp->uh.uid = current->fsuid;
- outsize = insize;
- } while (0)
- #define BUFF_ALLOC(buffer)
- PRESTO_ALLOC(buffer, char *, PAGE_SIZE);
- if ( !buffer ) {
- printk("PRESTO: out of memory!n");
- return -ENOMEM;
- }
- /* the upcalls */
- int lento_kml(int minor, unsigned int offset, unsigned int first_recno,
- unsigned int length, unsigned int last_recno, int namelen,
- char *fsetname)
- {
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
- ENTRY;
- if (!presto_lento_up(minor)) {
- EXIT;
- return 0;
- }
- insize = SIZE(kml) + namelen + 1;
- UPARG(LENTO_KML);
- inp->lento_kml.namelen = namelen;
- memcpy(inp->lento_kml.fsetname, fsetname, namelen);
- inp->lento_kml.fsetname[namelen] = ' ';
- inp->lento_kml.offset = offset;
- inp->lento_kml.first_recno = first_recno;
- inp->lento_kml.length = length;
- inp->lento_kml.last_recno = last_recno;
- CDEBUG(D_UPCALL, "KML: fileset %s, offset %d, length %d, "
- "first %d, last %d; minor %dn",
- inp->lento_kml.fsetname,
- inp->lento_kml.offset,
- inp->lento_kml.length,
- inp->lento_kml.first_recno,
- inp->lento_kml.last_recno, minor);
- error = lento_upcall(minor, insize, &outsize, inp,
- ASYNCHRONOUS, NULL);
- EXIT;
- return error;
- }
- int lento_release_permit( int minor, int mycookie )
- {
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
- ENTRY;
- if (!presto_lento_up(minor)) {
- EXIT;
- return 0;
- }
- insize= SIZE(response_cookie);
- UPARG(LENTO_COOKIE);
- inp->lento_response_cookie.cookie= mycookie;
- CDEBUG(D_UPCALL, "cookie %dn", mycookie);
- error = lento_upcall(minor, insize, &outsize, inp,
- ASYNCHRONOUS, NULL);
- EXIT;
- return error;
- }
- int lento_opendir(int minor, int pathlen, char *path, int async)
- {
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
- ENTRY;
- insize = SIZE(opendir) + pathlen + 1;
- UPARG(LENTO_OPENDIR);
- inp->lento_opendir.async = async;
- inp->lento_opendir.pathlen = pathlen;
- memcpy(inp->lento_opendir.path, path, pathlen);
- inp->lento_opendir.path[pathlen] = ' ';
- CDEBUG(D_UPCALL, "path %sn", inp->lento_opendir.path);
- if (async) {
- error = lento_upcall(minor, insize, &outsize, inp,
- ASYNCHRONOUS, NULL);
- return 0;
- }
- error = lento_upcall(minor, insize, &outsize, inp,
- SYNCHRONOUS, NULL);
- if (error && error != EISFSETROOT) {
- printk("lento_opendir: error %dn", error);
- }
- EXIT;
- return error;
- }
- int lento_open(int minor, int pathlen, char *path)
- {
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
- ENTRY;
- insize = SIZE(open) + pathlen + 1;
- UPARG(LENTO_OPEN);
- inp->lento_open.pathlen = pathlen;
- memcpy(inp->lento_open.path, path, pathlen);
- inp->lento_open.path[pathlen] = ' ';
- CDEBUG(D_UPCALL, "path %sn", inp->lento_open.path);
- error = lento_upcall(minor, insize, &outsize, inp,
- SYNCHRONOUS, NULL);
- if (error) {
- printk("lento_open: error %dn", error);
- }
- EXIT;
- return error;
- }
- int lento_permit(int minor, int pathlen, int fsetnamelen, char *path, char *fsetname)
- {
- union up_args *inp;
- union down_args *outp;
- int insize, outsize, error;
- ENTRY;
- insize = SIZE(permit) + pathlen + 1 + fsetnamelen + 1;
- UPARG(LENTO_PERMIT);
- inp->lento_permit.pathlen = pathlen;
- inp->lento_permit.fsetnamelen = fsetnamelen;
- memcpy(inp->lento_permit.path, path, pathlen);
- inp->lento_permit.path[pathlen] = ' ';
- memcpy(&(inp->lento_permit.path[pathlen+1]), fsetname, fsetnamelen);
- inp->lento_permit.path[fsetnamelen + 1 + pathlen] = ' ';
- CDEBUG(D_UPCALL, "Permit minor %d path %sn", minor,
- inp->lento_permit.path);
- error = lento_upcall(minor, insize, &outsize, inp,
- SYNCHRONOUS, NULL);
- if (error) {
- if( error == -EROFS ) {
- int err;
- printk("lento_permit: ERROR - requested permit for "
- "read-only fileset.n"
- " Setting "%s" read-only!n",
- path);
- err= presto_mark_cache(path, 0xFFFFFFFF,
- CACHE_CLIENT_RO, NULL);
- if( err ) {
- printk("ERROR : mark_cache %dn", err);
- }
- }
- else {
- printk("lento_permit: error %dn", error);
- }
- }
- EXIT;
- return error;
- }