⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upcall.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Mostly platform independent upcall operations to Venus: *  -- upcalls *  -- upcall routines * * Linux 2.0 version * Copyright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk>,  * 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>. */#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/sched.h>#include <linux/fs.h>#include <linux/file.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 <linux/coda.h>#include <linux/coda_linux.h>#include <linux/coda_psdev.h>#include <linux/coda_fs_i.h>#include <linux/coda_cache.h>#include <linux/coda_proc.h> #define upc_alloc() kmalloc(sizeof(struct upc_req), GFP_KERNEL)#define upc_free(r) kfree(r)static int coda_upcall(struct coda_sb_info *mntinfo, int inSize, int *outSize, 		       union inputArgs *buffer);static void *alloc_upcall(int opcode, int size){	union inputArgs *inp;	CODA_ALLOC(inp, union inputArgs *, size);        if (!inp)		return ERR_PTR(-ENOMEM);        inp->ih.opcode = opcode;	inp->ih.pid = current->pid;	inp->ih.pgid = current->pgrp;	coda_load_creds(&(inp->ih.cred));	return (void*)inp;}#define UPARG(op)\do {\	inp = (union inputArgs *)alloc_upcall(op, insize); \        if (IS_ERR(inp)) { return PTR_ERR(inp); }\        outp = (union outputArgs *)(inp); \        outsize = insize; \} while (0)#define INSIZE(tag) sizeof(struct coda_ ## tag ## _in)#define OUTSIZE(tag) sizeof(struct coda_ ## tag ## _out)#define SIZE(tag)  max_t(unsigned int, INSIZE(tag), OUTSIZE(tag))/* the upcalls */int venus_rootfid(struct super_block *sb, ViceFid *fidp){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        insize = SIZE(root);        UPARG(CODA_ROOT);	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);		if (error) {	        printk("coda_get_rootfid: error %d\n", error);	} else {		*fidp = (ViceFid) outp->coda_root.VFid;		CDEBUG(D_SUPER, "VolumeId: %lx, VnodeId: %lx.\n",		       fidp->Volume, fidp->Vnode);	}	CODA_FREE(inp, insize);	return error;}int venus_getattr(struct super_block *sb, struct ViceFid *fid, 		     struct coda_vattr *attr) {        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        insize = SIZE(getattr); 	UPARG(CODA_GETATTR);        inp->coda_getattr.VFid = *fid;        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);		*attr = outp->coda_getattr.attr;	CODA_FREE(inp, insize);        return error;}int venus_setattr(struct super_block *sb, struct ViceFid *fid, 		  struct coda_vattr *vattr){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;		insize = SIZE(setattr);	UPARG(CODA_SETATTR);        inp->coda_setattr.VFid = *fid;	inp->coda_setattr.attr = *vattr;        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);        CDEBUG(D_SUPER, " result %d\n", error);         CODA_FREE(inp, insize);        return error;}int venus_lookup(struct super_block *sb, struct ViceFid *fid, 		    const char *name, int length, int * type, 		    struct ViceFid *resfid){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;	int offset;	offset = INSIZE(lookup);        insize = max_t(unsigned int, offset + length +1, OUTSIZE(lookup));	UPARG(CODA_LOOKUP);        inp->coda_lookup.VFid = *fid;	inp->coda_lookup.name = offset;	inp->coda_lookup.flags = CLU_CASE_SENSITIVE;        /* send Venus a null terminated string */        memcpy((char *)(inp) + offset, name, length);        *((char *)inp + offset + length) = '\0';        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	*resfid = outp->coda_lookup.VFid;	*type = outp->coda_lookup.vtype;	CODA_FREE(inp, insize);	return error;}int venus_store(struct super_block *sb, struct ViceFid *fid, int flags,                struct coda_cred *cred){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;		insize = SIZE(store);	UPARG(CODA_STORE);		if ( cred ) {		memcpy(&(inp->ih.cred), cred, sizeof(*cred));	} else 		printk("CODA: store without valid file creds.\n");	        inp->coda_store.VFid = *fid;        inp->coda_store.flags = flags;        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	CODA_FREE(inp, insize);        return error;}int venus_release(struct super_block *sb, struct ViceFid *fid, int flags){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;		insize = SIZE(release);	UPARG(CODA_RELEASE);		inp->coda_release.VFid = *fid;	inp->coda_release.flags = flags;	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	CODA_FREE(inp, insize);	return error;}int venus_close(struct super_block *sb, struct ViceFid *fid, int flags,                struct coda_cred *cred){	union inputArgs *inp;	union outputArgs *outp;	int insize, outsize, error;		insize = SIZE(release);	UPARG(CODA_CLOSE);		if ( cred ) {		memcpy(&(inp->ih.cred), cred, sizeof(*cred));	} else 		printk("CODA: close without valid file creds.\n");	        inp->coda_close.VFid = *fid;        inp->coda_close.flags = flags;        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	CODA_FREE(inp, insize);        return error;}int venus_open(struct super_block *sb, struct ViceFid *fid,		  int flags, struct file **fh){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;       	insize = SIZE(open_by_fd);	UPARG(CODA_OPEN_BY_FD);        inp->coda_open.VFid = *fid;        inp->coda_open.flags = flags;        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	*fh = outp->coda_open_by_fd.fh;	CODA_FREE(inp, insize);	return error;}	int venus_mkdir(struct super_block *sb, struct ViceFid *dirfid, 		   const char *name, int length, 		   struct ViceFid *newfid, struct coda_vattr *attrs){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        int offset;	offset = INSIZE(mkdir);	insize = max_t(unsigned int, offset + length + 1, OUTSIZE(mkdir));	UPARG(CODA_MKDIR);        inp->coda_mkdir.VFid = *dirfid;        inp->coda_mkdir.attr = *attrs;	inp->coda_mkdir.name = offset;        /* Venus must get null terminated string */        memcpy((char *)(inp) + offset, name, length);        *((char *)inp + offset + length) = '\0';                error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	*attrs = outp->coda_mkdir.attr;	*newfid = outp->coda_mkdir.VFid;	CODA_FREE(inp, insize);	return error;        }int venus_rename(struct super_block *sb, struct ViceFid *old_fid, 		 struct ViceFid *new_fid, size_t old_length, 		 size_t new_length, const char *old_name, 		 const char *new_name){	union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error; 	int offset, s;		offset = INSIZE(rename);	insize = max_t(unsigned int, offset + new_length + old_length + 8,		     OUTSIZE(rename));  	UPARG(CODA_RENAME);        inp->coda_rename.sourceFid = *old_fid;        inp->coda_rename.destFid =  *new_fid;        inp->coda_rename.srcname = offset;        /* Venus must receive an null terminated string */        s = ( old_length & ~0x3) +4; /* round up to word boundary */        memcpy((char *)(inp) + offset, old_name, old_length);        *((char *)inp + offset + old_length) = '\0';        /* another null terminated string for Venus */        offset += s;        inp->coda_rename.destname = offset;        s = ( new_length & ~0x3) +4; /* round up to word boundary */        memcpy((char *)(inp) + offset, new_name, new_length);        *((char *)inp + offset + new_length) = '\0';        CDEBUG(D_INODE, "destname in packet: %s\n",               (char *)inp + (int) inp->coda_rename.destname);        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	CODA_FREE(inp, insize);	return error;}int venus_create(struct super_block *sb, struct ViceFid *dirfid, 		    const char *name, int length, int excl, int mode, int rdev,		    struct ViceFid *newfid, struct coda_vattr *attrs) {        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        int offset;        offset = INSIZE(create);	insize = max_t(unsigned int, offset + length + 1, OUTSIZE(create));	UPARG(CODA_CREATE);        inp->coda_create.VFid = *dirfid;        inp->coda_create.attr.va_mode = mode;        inp->coda_create.attr.va_rdev = rdev;	inp->coda_create.excl = excl;        inp->coda_create.mode = mode;        inp->coda_create.name = offset;        /* Venus must get null terminated string */        memcpy((char *)(inp) + offset, name, length);        *((char *)inp + offset + length) = '\0';                        error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	*attrs = outp->coda_create.attr;	*newfid = outp->coda_create.VFid;	CODA_FREE(inp, insize);	return error;        }int venus_rmdir(struct super_block *sb, struct ViceFid *dirfid, 		    const char *name, int length){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        int offset;        offset = INSIZE(rmdir);	insize = max_t(unsigned int, offset + length + 1, OUTSIZE(rmdir));	UPARG(CODA_RMDIR);        inp->coda_rmdir.VFid = *dirfid;        inp->coda_rmdir.name = offset;        memcpy((char *)(inp) + offset, name, length);	*((char *)inp + offset + length) = '\0';                error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	CODA_FREE(inp, insize);	return error;}int venus_remove(struct super_block *sb, struct ViceFid *dirfid, 		    const char *name, int length){        union inputArgs *inp;        union outputArgs *outp;        int error=0, insize, outsize, offset;        offset = INSIZE(remove);	insize = max_t(unsigned int, offset + length + 1, OUTSIZE(remove));	UPARG(CODA_REMOVE);        inp->coda_remove.VFid = *dirfid;        inp->coda_remove.name = offset;        memcpy((char *)(inp) + offset, name, length);	*((char *)inp + offset + length) = '\0';                error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);	CODA_FREE(inp, insize);	return error;}int venus_readlink(struct super_block *sb, struct ViceFid *fid, 		      char *buffer, int *length){         union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        int retlen;        char *result;        	insize = max_t(unsigned int,		     INSIZE(readlink), OUTSIZE(readlink)+ *length + 1);	UPARG(CODA_READLINK);        inp->coda_readlink.VFid = *fid;            error =  coda_upcall(coda_sbp(sb), insize, &outsize, inp);		if (! error) {                retlen = outp->coda_readlink.count;		if ( retlen > *length )		        retlen = *length;		*length = retlen;		result =  (char *)outp + (long)outp->coda_readlink.data;		memcpy(buffer, result, retlen);		*(buffer + retlen) = '\0';	}                CDEBUG(D_INODE, " result %d\n",error);        CODA_FREE(inp, insize);        return error;}int venus_link(struct super_block *sb, struct ViceFid *fid, 		  struct ViceFid *dirfid, const char *name, int len ){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        int offset;	offset = INSIZE(link);	insize = max_t(unsigned int, offset  + len + 1, OUTSIZE(link));        UPARG(CODA_LINK);        inp->coda_link.sourceFid = *fid;        inp->coda_link.destFid = *dirfid;        inp->coda_link.tname = offset;        /* make sure strings are null terminated */        memcpy((char *)(inp) + offset, name, len);        *((char *)inp + offset + len) = '\0';                error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);        CDEBUG(D_INODE, " result %d\n",error);	CODA_FREE(inp, insize);        return error;}int venus_symlink(struct super_block *sb, struct ViceFid *fid,		     const char *name, int len,		     const char *symname, int symlen){        union inputArgs *inp;        union outputArgs *outp;        int insize, outsize, error;        int offset, s;        offset = INSIZE(symlink);	insize = max_t(unsigned int, offset + len + symlen + 8, OUTSIZE(symlink));	UPARG(CODA_SYMLINK);                /*        inp->coda_symlink.attr = *tva; XXXXXX */         inp->coda_symlink.VFid = *fid;	/* Round up to word boundary and null terminate */        inp->coda_symlink.srcname = offset;        s = ( symlen  & ~0x3 ) + 4;         memcpy((char *)(inp) + offset, symname, symlen);        *((char *)inp + offset + symlen) = '\0';        	/* Round up to word boundary and null terminate */        offset += s;        inp->coda_symlink.tname = offset;        s = (len & ~0x3) + 4;        memcpy((char *)(inp) + offset, name, len);        *((char *)inp + offset + len) = '\0';	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -