From: Eric V. H. <er...@us...> - 2006-03-02 21:30:26
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16402 Modified Files: 9p.c 9p.h Makefile TODO conv.c conv.h debug.h error.c error.h fid.c fid.h mux.c mux.h transport.h v9fs.c v9fs.h v9fs_vfs.h vfs_dentry.c vfs_dir.c vfs_file.c vfs_inode.c vfs_super.c Removed Files: idpool.c idpool.h Log Message: Merge code from kernel.org and make sure it builds as a stand-alone module on 2.6.12. Index: mux.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/mux.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** mux.h 21 Sep 2005 17:43:51 -0000 2.2 --- mux.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 4,7 **** --- 4,8 ---- * Multiplexer Definitions * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * *************** *** 24,41 **** */ ! /* structure to manage each RPC transaction */ ! struct v9fs_rpcreq { ! struct v9fs_fcall *tcall; ! struct v9fs_fcall *rcall; ! int err; /* error code if response failed */ ! /* XXX - could we put scatter/gather buffers here? */ ! struct list_head next; ! }; ! int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name); ! long v9fs_mux_rpc(struct v9fs_session_info *v9ses, ! struct v9fs_fcall *tcall, struct v9fs_fcall **rcall); ! void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err); --- 25,58 ---- */ ! struct v9fs_mux_data; ! /** ! * v9fs_mux_req_callback - callback function that is called when the ! * response of a request is received. The callback is called from ! * a workqueue and shouldn't block. ! * ! * @a - the pointer that was specified when the request was send to be ! * passed to the callback ! * @tc - request call ! * @rc - response call ! * @err - error code (non-zero if error occured) ! */ ! typedef void (*v9fs_mux_req_callback)(void *a, struct v9fs_fcall *tc, ! struct v9fs_fcall *rc, int err); ! int v9fs_mux_global_init(void); ! void v9fs_mux_global_exit(void); ! struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, ! unsigned char *extended); ! void v9fs_mux_destroy(struct v9fs_mux_data *); ! int v9fs_mux_send(struct v9fs_mux_data *m, struct v9fs_fcall *tc); ! struct v9fs_fcall *v9fs_mux_recv(struct v9fs_mux_data *m); ! int v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, struct v9fs_fcall **rc); ! int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc, ! v9fs_mux_req_callback cb, void *a); ! ! void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush); ! void v9fs_mux_cancel(struct v9fs_mux_data *m, int err); ! int v9fs_errstr2errno(char *errstr, int len); Index: vfs_file.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_file.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_file.c 21 Sep 2005 17:43:51 -0000 2.3 --- vfs_file.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 33,36 **** --- 33,37 ---- #include <linux/smp_lock.h> #include <linux/inet.h> + #include <linux/version.h> #include <linux/list.h> #include <asm/uaccess.h> *************** *** 53,58 **** { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK); ! struct v9fs_fid *v9newfid = NULL; struct v9fs_fcall *fcall = NULL; int open_mode = 0; --- 54,58 ---- { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *v9fid, *fid; struct v9fs_fcall *fcall = NULL; int open_mode = 0; *************** *** 61,80 **** long result = -1; ! dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file, ! v9fid); if (!v9fid) { - struct dentry *dentry = file->f_dentry; dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); ! /* XXX - some duplication from lookup, generalize later */ ! /* basically vfs_lookup is too heavy weight */ ! v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP); ! if (!v9fid) ! return -EBADF; ! v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK); ! if (!v9fid) ! return -EBADF; newfid = v9fs_get_idpool(&v9ses->fidpool); --- 61,87 ---- long result = -1; ! dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); ! ! v9fid = v9fs_fid_get_created(file->f_dentry); ! if (!v9fid) ! v9fid = v9fs_fid_lookup(file->f_dentry); if (!v9fid) { dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); + return -EBADF; + } ! if (!v9fid->fidcreate) { ! fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); ! if (fid == NULL) { ! dprintk(DEBUG_ERROR, "Out of Memory\n"); ! return -ENOMEM; ! } ! fid->fidopen = 0; ! fid->fidcreate = 0; ! fid->fidclunked = 0; ! fid->iounit = 0; ! fid->v9ses = v9ses; newfid = v9fs_get_idpool(&v9ses->fidpool); *************** *** 85,90 **** result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, ! (char *)file->f_dentry->d_name.name, NULL); if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); --- 92,97 ---- result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL); ! if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); *************** *** 93,140 **** } ! v9fid = v9fs_fid_create(dentry); ! if (v9fid == NULL) { ! dprintk(DEBUG_ERROR, "couldn't insert\n"); ! return -ENOMEM; ! } ! v9fid->fid = newfid; ! } ! ! if (v9fid->fidcreate) { ! /* create case */ ! newfid = v9fid->fid; ! iounit = v9fid->iounit; ! v9fid->fidcreate = 0; ! } else { ! if (!S_ISDIR(inode->i_mode)) ! newfid = v9fid->fid; ! else { ! newfid = v9fs_get_idpool(&v9ses->fidpool); ! if (newfid < 0) { ! eprintk(KERN_WARNING, "allocation failed\n"); ! return -ENOSPC; ! } ! /* This would be a somewhat critical clone */ ! result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, ! &fcall); ! if (result < 0) { ! dprintk(DEBUG_ERROR, "clone error: %s\n", ! FCALL_ERROR(fcall)); ! kfree(fcall); ! return result; ! } ! ! v9newfid = v9fs_fid_create(file->f_dentry); ! v9newfid->fid = newfid; ! v9newfid->qid = v9fid->qid; ! v9newfid->iounit = v9fid->iounit; ! v9newfid->fidopen = 0; ! v9newfid->fidclunked = 0; ! v9newfid->v9ses = v9ses; ! v9fid = v9newfid; ! kfree(fcall); ! } ! /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ --- 100,105 ---- } ! fid->fid = newfid; ! v9fid = fid; /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ *************** *** 154,160 **** result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); if (result < 0) { ! dprintk(DEBUG_ERROR, ! "open failed, open_mode 0x%x: %s\n", open_mode, ! FCALL_ERROR(fcall)); kfree(fcall); return result; --- 119,123 ---- result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); if (result < 0) { ! PRINT_FCALL_ERROR("open failed", fcall); kfree(fcall); return result; *************** *** 163,169 **** iounit = fcall->params.ropen.iounit; kfree(fcall); } - file->private_data = v9fid; --- 126,136 ---- iounit = fcall->params.ropen.iounit; kfree(fcall); + } else { + /* create case */ + newfid = v9fid->fid; + iounit = v9fid->iounit; + v9fid->fidcreate = 0; } file->private_data = v9fid; *************** *** 198,203 **** if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { ! filemap_fdatawrite(inode->i_mapping); ! filemap_fdatawait(inode->i_mapping); invalidate_inode_pages(&inode->i_data); } --- 165,169 ---- if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { ! filemap_write_and_wait(inode->i_mapping); invalidate_inode_pages(&inode->i_data); } *************** *** 207,211 **** /** ! * v9fs_read - read from a file (internal) * @filep: file pointer to read * @data: data buffer to read data into --- 173,177 ---- /** ! * v9fs_file_read - read from a file * @filep: file pointer to read * @data: data buffer to read data into *************** *** 214,220 **** * */ - static ssize_t ! v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; --- 180,186 ---- * */ static ssize_t ! v9fs_file_read(struct file *filp, char __user * data, size_t count, ! loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; *************** *** 226,229 **** --- 192,196 ---- int result = 0; int total = 0; + int n; dprintk(DEBUG_VFS, "\n"); *************** *** 248,255 **** *offset += result; ! /* XXX - extra copy */ ! memcpy(buffer, fcall->params.rread.data, result); count -= result; ! buffer += result; total += result; --- 215,227 ---- *offset += result; ! n = copy_to_user(data, fcall->params.rread.data, result); ! if (n) { ! dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n); ! kfree(fcall); ! return -EFAULT; ! } ! count -= result; ! data += result; total += result; *************** *** 264,303 **** /** ! * v9fs_file_read - read from a file ! * @filep: file pointer to read ! * @data: data buffer to read data into ! * @count: size of buffer ! * @offset: offset at which to read data ! * ! */ ! ! static ssize_t ! v9fs_file_read(struct file *filp, char __user * data, size_t count, ! loff_t * offset) ! { ! int retval = -1; ! int ret = 0; ! char *buffer; ! ! buffer = kmalloc(count, GFP_KERNEL); ! if (!buffer) ! return -ENOMEM; ! ! retval = v9fs_read(filp, buffer, count, offset); ! if (retval > 0) { ! if ((ret = copy_to_user(data, buffer, retval)) != 0) { ! dprintk(DEBUG_ERROR, "Problem copying to user %d\n", ! ret); ! retval = ret; ! } ! } ! ! kfree(buffer); ! ! return retval; ! } ! ! /** ! * v9fs_write - write to a file * @filep: file pointer to write * @data: data buffer to write data from --- 236,240 ---- /** ! * v9fs_file_write - write to a file * @filep: file pointer to write * @data: data buffer to write data from *************** *** 308,312 **** static ssize_t ! v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; --- 245,250 ---- static ssize_t ! v9fs_file_write(struct file *filp, const char __user * data, ! size_t count, loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; *************** *** 319,323 **** int total = 0; ! dprintk(DEBUG_VFS, "data %p count %d offset %x\n", buffer, (int)count, (int)*offset); rsize = v9ses->maxdata - V9FS_IOHDRSZ; --- 257,261 ---- int total = 0; ! dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count, (int)*offset); rsize = v9ses->maxdata - V9FS_IOHDRSZ; *************** *** 325,339 **** rsize = v9fid->iounit; - dump_data(buffer, count); - do { if (count < rsize) rsize = count; ! result = ! v9fs_t_write(v9ses, fid, *offset, rsize, buffer, &fcall); if (result < 0) { ! eprintk(KERN_ERR, "error while writing: %s(%d)\n", ! FCALL_ERROR(fcall), result); kfree(fcall); return result; --- 263,273 ---- rsize = v9fid->iounit; do { if (count < rsize) rsize = count; ! result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall); if (result < 0) { ! PRINT_FCALL_ERROR("error while writing", fcall); kfree(fcall); return result; *************** *** 342,345 **** --- 276,280 ---- kfree(fcall); + fcall = NULL; if (result != rsize) { *************** *** 351,392 **** count -= result; ! buffer += result; total += result; } while (count); ! return total; ! } ! ! /** ! * v9fs_file_write - write to a file ! * @filep: file pointer to write ! * @data: data buffer to write data from ! * @count: size of buffer ! * @offset: offset at which to write data ! * ! */ ! ! static ssize_t ! v9fs_file_write(struct file *filp, const char __user * data, ! size_t count, loff_t * offset) ! { ! int ret = -1; ! char *buffer; ! ! buffer = kmalloc(count, GFP_KERNEL); ! if (buffer == NULL) ! return -ENOMEM; ! ! ret = copy_from_user(buffer, data, count); ! if (ret) { ! dprintk(DEBUG_ERROR, "Problem copying from user\n"); ! ret = -EFAULT; ! } else { ! ret = v9fs_write(filp, buffer, count, offset); ! } ! ! kfree(buffer); ! return ret; } --- 286,297 ---- count -= result; ! data += result; total += result; } while (count); ! if(inode->i_mapping->nrpages) ! invalidate_inode_pages2(inode->i_mapping); ! return total; } *************** *** 398,400 **** --- 303,306 ---- .release = v9fs_dir_release, .lock = v9fs_file_lock, + .mmap = generic_file_mmap, }; Index: error.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/error.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** error.h 21 Sep 2005 17:43:51 -0000 2.2 --- error.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 37,40 **** --- 37,41 ---- int val; + int namelen; struct hlist_node list; }; *************** *** 176,178 **** extern int v9fs_error_init(void); - extern int v9fs_errstr2errno(char *errstr); --- 177,178 ---- Index: mux.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/mux.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** mux.c 21 Sep 2005 17:43:51 -0000 2.3 --- mux.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 5,9 **** * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> ! * Copyright (C) 2004 by Latchesar Ionkov <lu...@io...> * * This program is free software; you can redistribute it and/or modify --- 5,9 ---- * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> ! * Copyright (C) 2004-2005 by Latchesar Ionkov <lu...@io...> * [...1375 lines suppressed...] ! wake_up(&m->equeue); ! } ! static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m) ! { ! int tag; ! ! tag = v9fs_get_idpool(&m->tidpool); ! if (tag < 0) ! return V9FS_NOTAG; ! else ! return (u16) tag; ! } ! ! static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) ! { ! if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tidpool)) ! v9fs_put_idpool(tag, &m->tidpool); } Index: error.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/error.c,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** error.c 21 Sep 2005 17:43:51 -0000 2.2 --- error.c 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 55,59 **** /* load initial error map into hash table */ for (c = errmap; c->name != NULL; c++) { ! bucket = jhash(c->name, strlen(c->name), 0) % ERRHASHSZ; INIT_HLIST_NODE(&c->list); hlist_add_head(&c->list, &hash_errmap[bucket]); --- 55,60 ---- /* load initial error map into hash table */ for (c = errmap; c->name != NULL; c++) { ! c->namelen = strlen(c->name); ! bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ; INIT_HLIST_NODE(&c->list); hlist_add_head(&c->list, &hash_errmap[bucket]); *************** *** 69,81 **** */ ! int v9fs_errstr2errno(char *errstr) { int errno = 0; struct hlist_node *p = NULL; struct errormap *c = NULL; ! int bucket = jhash(errstr, strlen(errstr), 0) % ERRHASHSZ; hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { ! if (!strcmp(c->name, errstr)) { errno = c->val; break; --- 70,82 ---- */ ! int v9fs_errstr2errno(char *errstr, int len) { int errno = 0; struct hlist_node *p = NULL; struct errormap *c = NULL; ! int bucket = jhash(errstr, len, 0) % ERRHASHSZ; hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { ! if (c->namelen==len && !memcmp(c->name, errstr, len)) { errno = c->val; break; Index: vfs_super.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_super.c,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** vfs_super.c 21 Sep 2005 17:43:51 -0000 2.2 --- vfs_super.c 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 45,49 **** #include "9p.h" #include "v9fs_vfs.h" - #include "conv.h" #include "fid.h" --- 45,48 ---- *************** *** 93,97 **** sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | ! MS_NODIRATIME | MS_NOATIME; } --- 92,96 ---- sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | ! MS_NOATIME; } *************** *** 124,128 **** dprintk(DEBUG_VFS, " \n"); ! v9ses = kcalloc(1, sizeof(struct v9fs_session_info), GFP_KERNEL); if (!v9ses) return ERR_PTR(-ENOMEM); --- 123,127 ---- dprintk(DEBUG_VFS, " \n"); ! v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); if (!v9ses) return ERR_PTR(-ENOMEM); *************** *** 130,135 **** if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { dprintk(DEBUG_ERROR, "problem initiating session\n"); ! retval = newfid; ! goto free_session; } --- 129,134 ---- if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { dprintk(DEBUG_ERROR, "problem initiating session\n"); ! kfree(v9ses); ! return ERR_PTR(newfid); } *************** *** 151,180 **** if (!root) { retval = -ENOMEM; ! goto release_inode; } sb->s_root = root; - /* Setup the Root Inode */ - root_fid = v9fs_fid_create(root); - if (root_fid == NULL) { - retval = -ENOMEM; - goto release_dentry; - } - - root_fid->fidopen = 0; - root_fid->v9ses = v9ses; - stat_result = v9fs_t_stat(v9ses, newfid, &fcall); if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); ! v9fs_t_clunk(v9ses, newfid, NULL); v9fs_put_idpool(newfid, &v9ses->fidpool); } else { ! root_fid->fid = newfid; ! root_fid->qid = fcall->params.rstat.stat->qid; root->d_inode->i_ino = ! v9fs_qid2ino(&fcall->params.rstat.stat->qid); ! v9fs_mistat2inode(fcall->params.rstat.stat, root->d_inode, sb); } --- 150,175 ---- if (!root) { retval = -ENOMEM; ! goto put_back_sb; } sb->s_root = root; stat_result = v9fs_t_stat(v9ses, newfid, &fcall); if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); ! v9fs_t_clunk(v9ses, newfid); v9fs_put_idpool(newfid, &v9ses->fidpool); } else { ! /* Setup the Root Inode */ ! root_fid = v9fs_fid_create(root, v9ses, newfid, 0); ! if (root_fid == NULL) { ! retval = -ENOMEM; ! goto put_back_sb; ! } ! ! root_fid->qid = fcall->params.rstat.stat.qid; root->d_inode->i_ino = ! v9fs_qid2ino(&fcall->params.rstat.stat.qid); ! v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb); } *************** *** 183,205 **** if (stat_result < 0) { retval = stat_result; ! goto release_dentry; } return sb; ! release_dentry: ! dput(sb->s_root); ! ! release_inode: ! iput(inode); ! ! put_back_sb: up_write(&sb->s_umount); deactivate_super(sb); - v9fs_session_close(v9ses); - - free_session: - kfree(v9ses); - return ERR_PTR(retval); } --- 178,190 ---- if (stat_result < 0) { retval = stat_result; ! goto put_back_sb; } return sb; ! put_back_sb: ! /* deactivate_super calls v9fs_kill_super which will frees the rest */ up_write(&sb->s_umount); deactivate_super(sb); return ERR_PTR(retval); } --- idpool.c DELETED --- Index: conv.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/conv.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** conv.h 21 Sep 2005 17:43:51 -0000 2.2 --- conv.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 2,7 **** * linux/fs/9p/conv.h * ! * 9P protocol conversion definitions * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> --- 2,8 ---- * linux/fs/9p/conv.h * ! * 9P protocol conversion definitions. * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 25,36 **** */ ! int v9fs_deserialize_stat(struct v9fs_session_info *, void *buf, ! u32 buflen, struct v9fs_stat *stat, u32 statlen); ! int v9fs_serialize_fcall(struct v9fs_session_info *, struct v9fs_fcall *tcall, ! void *buf, u32 buflen); ! int v9fs_deserialize_fcall(struct v9fs_session_info *, u32 msglen, ! void *buf, u32 buflen, struct v9fs_fcall *rcall, ! int rcalllen); ! /* this one is actually in error.c right now */ ! int v9fs_errstr2errno(char *errstr); --- 26,51 ---- */ ! int v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, ! int extended); ! int v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, ! int extended); ! void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag); ! ! struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version); ! struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname); ! struct v9fs_fcall *v9fs_create_tattach(u32 fid, u32 afid, char *uname, ! char *aname); ! struct v9fs_fcall *v9fs_create_tflush(u16 oldtag); ! struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, ! char **wnames); ! struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); ! struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode); ! struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); ! struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, ! const char __user *data); ! struct v9fs_fcall *v9fs_create_tclunk(u32 fid); ! struct v9fs_fcall *v9fs_create_tremove(u32 fid); ! struct v9fs_fcall *v9fs_create_tstat(u32 fid); ! struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat, ! int extended); Index: 9p.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.c,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** 9p.c 21 Sep 2005 17:43:51 -0000 2.2 --- 9p.c 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 2,7 **** * linux/fs/9p/9p.c * ! * This file contains functions 9P2000 functions * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> --- 2,8 ---- * linux/fs/9p/9p.c * ! * This file contains functions to perform synchronous 9P calls * + * Copyright (C) 2004 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 34,37 **** --- 35,39 ---- #include "v9fs.h" #include "9p.h" + #include "conv.h" #include "mux.h" *************** *** 47,60 **** int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, ! char *version, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version); ! msg.id = TVERSION; ! msg.params.tversion.msize = msize; ! msg.params.tversion.version = version; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 49,67 ---- int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, ! char *version, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version); ! tc = v9fs_create_tversion(msize, version); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 72,88 **** int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, ! u32 fid, u32 afid, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname, aname, fid, afid); - msg.id = TATTACH; - msg.params.tattach.fid = fid; - msg.params.tattach.afid = afid; - msg.params.tattach.uname = uname; - msg.params.tattach.aname = aname; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 79,121 ---- int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, ! u32 fid, u32 afid, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall* tc; dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname, aname, fid, afid); ! tc = v9fs_create_tattach(fid, afid, uname, aname); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; ! } ! ! static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, ! struct v9fs_fcall *rc, int err) ! { ! int fid; ! struct v9fs_session_info *v9ses; ! ! if (err) ! return; ! ! fid = tc->params.tclunk.fid; ! kfree(tc); ! ! if (!rc) ! return; ! ! dprintk(DEBUG_9P, "tcall id %d rcall id %d\n", tc->id, rc->id); ! v9ses = a; ! if (rc->id == RCLUNK) ! v9fs_put_idpool(fid, &v9ses->fidpool); ! ! kfree(rc); } *************** *** 96,109 **** int ! v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d\n", fid); - msg.id = TCLUNK; - msg.params.tclunk.fid = fid; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 129,151 ---- int ! v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid) { ! int ret; ! struct v9fs_fcall *tc, *rc; dprintk(DEBUG_9P, "fid %d\n", fid); ! rc = NULL; ! tc = v9fs_create_tclunk(fid); ! if (!IS_ERR(tc)) ! ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); ! else ! ret = PTR_ERR(tc); ! ! if (ret) ! dprintk(DEBUG_ERROR, "failed fid %d err %d\n", fid, ret); ! ! v9fs_t_clunk_cb(v9ses, tc, rc, ret); ! return ret; } *************** *** 115,126 **** */ ! int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 tag) { ! struct v9fs_fcall msg; ! dprintk(DEBUG_9P, "oldtag %d\n", tag); ! msg.id = TFLUSH; ! msg.params.tflush.oldtag = tag; ! return v9fs_mux_rpc(v9ses, &msg, NULL); } --- 157,175 ---- */ ! int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) { ! int ret; ! struct v9fs_fcall *tc; ! dprintk(DEBUG_9P, "oldtag %d\n", oldtag); ! ! tc = v9fs_create_tflush(oldtag); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, NULL); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 134,148 **** int ! v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d\n", fid); - if (fcall) - *fcall = NULL; ! msg.id = TSTAT; ! msg.params.tstat.fid = fid; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 183,202 ---- int ! v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d\n", fid); ! ret = -ENOMEM; ! tc = v9fs_create_tstat(fid); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 158,171 **** int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_stat *stat, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! dprintk(DEBUG_9P, "fid %d length %d\n", fid, (int)stat->length); ! msg.id = TWSTAT; ! msg.params.twstat.fid = fid; ! msg.params.twstat.stat = stat; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 212,230 ---- int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_wstat *wstat, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; ! dprintk(DEBUG_9P, "fid %d\n", fid); ! tc = v9fs_create_twstat(fid, wstat, v9ses->extended); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 184,204 **** int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, ! char *name, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name); - msg.id = TWALK; - msg.params.twalk.fid = fid; - msg.params.twalk.newfid = newfid; ! if (name) { ! msg.params.twalk.nwname = 1; ! msg.params.twalk.wnames = &name; ! } else { ! msg.params.twalk.nwname = 0; ! } ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 243,267 ---- int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, ! char *name, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; ! int nwname; dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name); ! if (name) ! nwname = 1; ! else ! nwname = 0; ! tc = v9fs_create_twalk(fid, newfid, nwname, &name); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 215,231 **** int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, ! struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! long errorno = -1; dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode); - msg.id = TOPEN; - msg.params.topen.fid = fid; - msg.params.topen.mode = mode; ! errorno = v9fs_mux_rpc(v9ses, &msg, fcall); ! return errorno; } --- 278,296 ---- int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, ! struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode); ! tc = v9fs_create_topen(fid, mode); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } *************** *** 240,251 **** int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d\n", fid); ! msg.id = TREMOVE; ! msg.params.tremove.fid = fid; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 305,323 ---- int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d\n", fid); ! ! tc = v9fs_create_tremove(fid); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 263,280 **** int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, ! u32 perm, u8 mode, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", fid, name, perm, mode); ! msg.id = TCREATE; ! msg.params.tcreate.fid = fid; ! msg.params.tcreate.name = name; ! msg.params.tcreate.perm = perm; ! msg.params.tcreate.mode = mode; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 335,354 ---- int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, ! u32 perm, u8 mode, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", fid, name, perm, mode); ! tc = v9fs_create_tcreate(fid, name, perm, mode); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } *************** *** 291,319 **** int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, ! u32 count, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! struct v9fs_fcall *rc = NULL; ! long errorno = -1; ! dprintk(DEBUG_9P, "fid %d offset 0x%lx count 0x%x\n", fid, ! (long unsigned int)offset, count); ! msg.id = TREAD; ! msg.params.tread.fid = fid; ! msg.params.tread.offset = offset; ! msg.params.tread.count = count; ! errorno = v9fs_mux_rpc(v9ses, &msg, &rc); ! if (!errorno) { ! errorno = rc->params.rread.count; ! dump_data(rc->params.rread.data, rc->params.rread.count); ! } ! if (fcall) ! *fcall = rc; ! else ! kfree(rc); ! return errorno; } --- 365,391 ---- int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, ! u32 count, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc, *rc; ! dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, ! (long long unsigned) offset, count); ! tc = v9fs_create_tread(fid, offset, count); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); ! if (!ret) ! ret = rc->params.rread.count; ! if (rcp) ! *rcp = rc; ! else ! kfree(rc); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } *************** *** 329,359 **** int ! v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, ! u64 offset, u32 count, void *data, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! struct v9fs_fcall *rc = NULL; ! long errorno = -1; ! ! dprintk(DEBUG_9P, "fid %d offset 0x%llx count 0x%x\n", fid, ! (unsigned long long)offset, count); ! dump_data(data, count); ! msg.id = TWRITE; ! msg.params.twrite.fid = fid; ! msg.params.twrite.offset = offset; ! msg.params.twrite.count = count; ! msg.params.twrite.data = data; ! errorno = v9fs_mux_rpc(v9ses, &msg, &rc); ! if (!errorno) ! errorno = rc->params.rwrite.count; ! if (fcall) ! *fcall = rc; ! else ! kfree(rc); ! return errorno; } --- 401,429 ---- int ! v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count, ! const char __user *data, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc, *rc; ! dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, ! (long long unsigned) offset, count); ! tc = v9fs_create_twrite(fid, offset, count, data); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); ! if (!ret) ! ret = rc->params.rwrite.count; ! if (rcp) ! *rcp = rc; ! else ! kfree(rc); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } + Index: conv.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/conv.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** conv.c 21 Sep 2005 17:43:51 -0000 2.3 --- conv.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 4,7 **** --- 4,8 ---- * 9P protocol conversion functions * + * Copyright (C) 2004, 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 30,34 **** #include <linux/fs.h> #include <linux/idr.h> [...1355 lines suppressed...] ! struct cbuf buffer; ! struct cbuf *bufp = &buffer; ! ! statsz = v9fs_size_wstat(wstat, extended); ! size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ ! fc = v9fs_create_common(bufp, size, TWSTAT); ! if (IS_ERR(fc)) ! goto error; ! ! v9fs_put_int32(bufp, fid, &fc->params.twstat.fid); ! buf_put_int16(bufp, statsz + 2); ! v9fs_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, extended); ! ! if (buf_check_overflow(bufp)) { ! kfree(fc); ! fc = ERR_PTR(-ENOMEM); ! } ! error: ! return fc; } --- idpool.h DELETED --- Index: v9fs.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** v9fs.c 21 Sep 2005 17:43:51 -0000 2.3 --- v9fs.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 38,42 **** #include "transport.h" #include "mux.h" - #include "conv.h" /* TODO: sysfs or debugfs interface */ --- 38,41 ---- *************** *** 68,72 **** {Opt_rfdno, "rfdno=%u"}, {Opt_wfdno, "wfdno=%u"}, ! {Opt_debug, "debug=%u"}, {Opt_name, "name=%s"}, {Opt_remotename, "aname=%s"}, --- 67,71 ---- {Opt_rfdno, "rfdno=%u"}, {Opt_wfdno, "wfdno=%u"}, ! {Opt_debug, "debug=%x"}, {Opt_name, "name=%s"}, {Opt_remotename, "aname=%s"}, *************** *** 214,218 **** } ! error = idr_get_new(&p->pool, NULL, &i); up(&p->lock); --- 213,218 ---- } ! /* no need to store exactly p, we just need something non-null */ ! error = idr_get_new(&p->pool, p, &i); up(&p->lock); *************** *** 244,247 **** --- 244,257 ---- /** + * v9fs_check_idpool - check if the specified id is available + * @id - id to check + * @p - pool + */ + int v9fs_check_idpool(int id, struct v9fs_idpool *p) + { + return idr_find(&p->pool, id) != NULL; + } + + /** * v9fs_session_init - initialize session * @v9ses: session information structure *************** *** 260,263 **** --- 270,274 ---- int newfid = -1; int retval = -EINVAL; + struct v9fs_str *version; v9ses->name = __getname(); *************** *** 267,271 **** v9ses->remotename = __getname(); if (!v9ses->remotename) { ! putname(v9ses->name); return -ENOMEM; } --- 278,282 ---- v9ses->remotename = __getname(); if (!v9ses->remotename) { ! __putname(v9ses->name); return -ENOMEM; } *************** *** 282,288 **** idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); - idr_init(&v9ses->tidpool.pool); - init_MUTEX(&v9ses->tidpool.lock); - switch (v9ses->proto) { --- 293,296 ---- *************** *** 304,308 **** }; ! v9ses->transport = trans_proto; if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { --- 312,322 ---- }; ! v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL); ! if (!v9ses->transport) { ! retval = -ENOMEM; ! goto SessCleanUp; ! } ! ! memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport)); if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { *************** *** 315,319 **** v9ses->session_hung = 0; ! if ((retval = v9fs_mux_init(v9ses, dev_name)) < 0) { dprintk(DEBUG_ERROR, "problem initializing mux\n"); goto SessCleanUp; --- 329,338 ---- v9ses->session_hung = 0; ! v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ, ! &v9ses->extended); ! ! if (IS_ERR(v9ses->mux)) { ! retval = PTR_ERR(v9ses->mux); ! v9ses->mux = NULL; dprintk(DEBUG_ERROR, "problem initializing mux\n"); goto SessCleanUp; *************** *** 334,344 **** } ! /* Really should check for 9P1 and report error */ ! if (!strcmp(fcall->params.rversion.version, "9P2000.u")) { dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); v9ses->extended = 1; ! } else { dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); v9ses->extended = 0; } --- 353,366 ---- } ! version = &fcall->params.rversion.version; ! if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) { dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); v9ses->extended = 1; ! } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) { dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); v9ses->extended = 0; + } else { + retval = -EREMOTEIO; + goto FreeFcall; } *************** *** 376,380 **** if (v9ses->afid != ~0) { ! if (v9fs_t_clunk(v9ses, v9ses->afid, NULL)) dprintk(DEBUG_ERROR, "clunk failed\n"); } --- 398,402 ---- if (v9ses->afid != ~0) { ! if (v9fs_t_clunk(v9ses, v9ses->afid)) dprintk(DEBUG_ERROR, "clunk failed\n"); } *************** *** 398,420 **** void v9fs_session_close(struct v9fs_session_info *v9ses) { ! if (v9ses->recvproc) { ! send_sig(SIGKILL, v9ses->recvproc, 1); ! wait_for_completion(&v9ses->proccmpl); } ! if (v9ses->transport) v9ses->transport->close(v9ses->transport); ! putname(v9ses->name); ! putname(v9ses->remotename); } /** ! * v9fs_session_cancel - mark transport as disconnected * and cancel all pending requests. */ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { v9ses->transport->status = Disconnected; ! v9fs_mux_cancel_requests(v9ses, -EIO); } --- 420,446 ---- void v9fs_session_close(struct v9fs_session_info *v9ses) { ! if (v9ses->mux) { ! v9fs_mux_destroy(v9ses->mux); ! v9ses->mux = NULL; } ! if (v9ses->transport) { v9ses->transport->close(v9ses->transport); + kfree(v9ses->transport); + v9ses->transport = NULL; + } ! __putname(v9ses->name); ! __putname(v9ses->remotename); } /** ! * v9fs_session_cancel - mark transport as disconnected * and cancel all pending requests. */ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { + dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses); v9ses->transport->status = Disconnected; ! v9fs_mux_cancel(v9ses->mux, -EIO); } *************** *** 428,436 **** static int __init init_v9fs(void) { v9fs_error_init(); printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); ! return register_filesystem(&v9fs_fs_type); } --- 454,468 ---- static int __init init_v9fs(void) { + int ret; + v9fs_error_init(); printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); ! ret = v9fs_mux_global_init(); ! if (!ret) ! ret = register_filesystem(&v9fs_fs_type); ! ! return ret; } *************** *** 442,445 **** --- 474,478 ---- static void __exit exit_v9fs(void) { + v9fs_mux_global_exit(); unregister_filesystem(&v9fs_fs_type); } Index: transport.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/transport.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** transport.h 21 Sep 2005 17:43:51 -0000 2.2 --- transport.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 4,7 **** --- 4,8 ---- * Transport Definition * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * *************** *** 32,37 **** struct v9fs_transport { enum v9fs_transport_status status; - struct semaphore writelock; - struct semaphore readlock; void *priv; --- 33,36 ---- *************** *** 40,43 **** --- 39,43 ---- int (*read) (struct v9fs_transport *, void *, int); void (*close) (struct v9fs_transport *); + unsigned int (*poll)(struct v9fs_transport *, struct poll_table_struct *); }; Index: v9fs.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** v9fs.h 21 Sep 2005 17:43:51 -0000 2.2 --- v9fs.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 58,79 **** /* book keeping */ struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ - struct v9fs_idpool tidpool; /* The TID pool for transactions ids */ - /* transport information */ struct v9fs_transport *transport; int inprogress; /* session in progress => true */ int shutdown; /* session shutting down. no more attaches. */ unsigned char session_hung; ! ! /* mux private data */ ! struct v9fs_fcall *curfcall; ! wait_queue_head_t read_wait; ! struct completion fcread; ! struct completion proccmpl; ! struct task_struct *recvproc; ! ! spinlock_t muxlock; ! struct list_head mux_fcalls; }; --- 58,69 ---- /* book keeping */ struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ struct v9fs_transport *transport; + struct v9fs_mux_data *mux; int inprogress; /* session in progress => true */ int shutdown; /* session shutting down. no more attaches. */ unsigned char session_hung; ! struct dentry *debugfs_dir; }; *************** *** 85,88 **** --- 75,80 ---- }; + extern struct dentry *v9fs_debugfs_root; + int v9fs_session_init(struct v9fs_session_info *, const char *, char *); struct v9fs_session_info *v9fs_inode2v9ses(struct inode *); *************** *** 90,93 **** --- 82,86 ---- int v9fs_get_idpool(struct v9fs_idpool *p); void v9fs_put_idpool(int id, struct v9fs_idpool *p); + int v9fs_check_idpool(int id, struct v9fs_idpool *p); void v9fs_session_cancel(struct v9fs_session_info *v9ses); *************** *** 102,103 **** --- 95,109 ---- #define V9FS_START_FIDS 8192 #define V9FS_START_TIDS 256 + + #include <linux/version.h> + + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) + #define filemap_write_and_wait(x) \ + do{ \ + filemap_fdatawrite(x); \ + filemap_fdatawait(x); \ + } while(0) + #define kzalloc(x,y) kmalloc(x,y) + + #endif + Index: v9fs_vfs.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs_vfs.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** v9fs_vfs.h 21 Sep 2005 17:43:51 -0000 2.2 --- v9fs_vfs.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 40,43 **** --- 40,44 ---- extern struct file_system_type v9fs_fs_type; + extern struct address_space_operations v9fs_addr_operations; extern struct file_operations v9fs_file_operations; extern struct file_operations v9fs_dir_operations; *************** *** 46,53 **** struct inode *v9fs_get_inode(struct super_block *sb, int mode); ino_t v9fs_qid2ino(struct v9fs_qid *qid); ! void v9fs_mistat2inode(struct v9fs_stat *, struct inode *, ! struct super_block *); int v9fs_dir_release(struct inode *inode, struct file *filp); int v9fs_file_open(struct inode *inode, struct file *file); ! void v9fs_inode2mistat(struct inode *inode, struct v9fs_stat *mistat); void v9fs_dentry_release(struct dentry *); --- 47,53 ---- struct inode *v9fs_get_inode(struct super_block *sb, int mode); ino_t v9fs_qid2ino(struct v9fs_qid *qid); ! void v9fs_stat2inode(struct v9fs_stat *, struct inode *, struct super_block *); int v9fs_dir_release(struct inode *inode, struct file *filp); int v9fs_file_open(struct inode *inode, struct file *file); ! void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat); void v9fs_dentry_release(struct dentry *); Index: vfs_inode.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_inode.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** vfs_inode.c 21 Sep 2005 17:43:51 -0000 2.4 --- vfs_inode.c 2 Mar 2006 21:30:17 -0000 2.5 *************** *** 41,45 **** #include "9p.h" #include "v9fs_vfs.h" - #include "conv.h" #include "fid.h" --- 41,44 ---- *************** *** 128,225 **** /** [...1313 lines suppressed...] ! if (!new_valid_dev(rdev)) ! return -EINVAL; + name = __getname(); /* build extension */ if (S_ISBLK(mode)) ! sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); else if (S_ISCHR(mode)) ! sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev)); else if (S_ISFIFO(mode)) ! *name = 0; else { ! __putname(name); ! return -EINVAL; } ! retval = v9fs_vfs_mkspecial(dir, dentry, mode, name); ! __putname(name); return retval; Index: Makefile =================================================================== RCS file: /cvsroot/v9fs/linux-9p/Makefile,v retrieving revision 2.1 retrieving revision 2.2 diff -C2 -d -r2.1 -r2.2 *** Makefile 21 Sep 2005 17:43:51 -0000 2.1 --- Makefile 2 Mar 2006 21:30:17 -0000 2.2 *************** *** 1,22 **** ! KDIR := /lib/modules/$(shell uname -r)/build ! ! obj-$(CONFIG_9P_FS) := 9p2000.o ! 9p2000-objs := \ ! vfs_super.o \ ! vfs_inode.o \ ! vfs_file.o \ ! vfs_dir.o \ ! vfs_dentry.o \ ! idpool.o \ ! error.o \ ! mux.o \ ! trans_sock.o \ ! trans_fd.o \ ! 9p.o \ ! conv.o \ ! v9fs.o \ ! fid.o default: ! CONFIG_9P_FS=m make -C $(KDIR) SUBDIRS=`pwd` modules --- 1,25 ---- ! 9p2000-objs := fid.o vfs_super.o vfs_inode.o vfs_dentry.o vfs_file.o vfs_addr.o vfs_dir.o error.o mux.o trans_fd.o 9p.o conv.o v9fs.o ! ifneq ($(KERNELRELEASE),) ! obj-m := 9p2000.o ! else ! KERNELDIR ?= /lib/modules/$(shell uname -r)/build ! PWD := $(shell pwd) default: ! $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ! endif ! ! EXTRA_CFLAGS += -Wall ! ! install: ! make -C ${KERNEL_SOURCE} SUBDIRS=`pwd` modules_install ! ! clean: ! rm -f *.o kver *~ ! ! mods: v9fs_ ! /sbin/insmod -m > v9fs.map v9fs.ko ! ! rmods: ! -/sbin/rmmod v9fs Index: vfs_dir.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_dir.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_dir.c 21 Sep 2005 17:43:51 -0000 2.3 --- vfs_dir.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 38,43 **** #include "v9fs.h" #include "9p.h" - #include "v9fs_vfs.h" #include "conv.h" #include "fid.h" --- 38,43 ---- #include "v9fs.h" #include "9p.h" #include "conv.h" + #include "v9fs_vfs.h" #include "fid.h" *************** *** 75,82 **** struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); struct v9fs_fid *file = filp->private_data; ! unsigned int i, n; int fid = -1; int ret = 0; ! struct v9fs_stat *mi = NULL; int over = 0; --- 75,82 ---- struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); struct v9fs_fid *file = filp->private_data; ! unsigned int i, n, s; int fid = -1; int ret = 0; ! struct v9fs_stat stat; int over = 0; *************** *** 85,92 **** fid = file->fid; - mi = kmalloc(v9ses->maxdata, GFP_KERNEL); - if (!mi) - return -ENOMEM; - if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) { kfree(file->rdir_fcall); --- 85,88 ---- *************** *** 98,115 **** i = file->rdir_fpos; while (i < n) { ! int s = v9fs_deserialize_stat(v9ses, ! file->rdir_fcall->params.rread.data + i, ! n - i, mi, v9ses->maxdata); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing mistat\n"); ret = -EIO; goto FreeStructs; } ! over = filldir(dirent, mi->name, strlen(mi->name), ! filp->f_pos, v9fs_qid2ino(&mi->qid), ! dt_type(mi)); if (over) { --- 94,111 ---- i = file->rdir_fpos; while (i < n) { ! s = v9fs_deserialize_stat( ! file->rdir_fcall->params.rread.data + i, ! n - i, &stat, v9ses->extended); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing stat\n"); ret = -EIO; goto FreeStructs; } ! over = filldir(dirent, stat.name.str, stat.name.len, ! filp->f_pos, v9fs_qid2ino(&stat.qid), ! dt_type(&stat)); if (over) { *************** *** 131,135 **** while (!over) { ret = v9fs_t_read(v9ses, fid, filp->f_pos, ! v9ses->maxdata-V9FS_IOHDRSZ, &fcall); if (ret < 0) { dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", --- 127,131 ---- while (!over) { ret = v9fs_t_read(v9ses, fid, filp->f_pos, ! v9ses->maxdata-V9FS_IOHDRSZ, &fcall); if (ret < 0) { dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", *************** *** 142,158 **** i = 0; while (i < n) { ! int s = v9fs_deserialize_stat(v9ses, ! fcall->params.rread.data + i, n - i, mi, ! v9ses->maxdata); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing mistat\n"); return -EIO; } ! over = filldir(dirent, mi->name, strlen(mi->name), ! filp->f_pos, v9fs_qid2ino(&mi->qid), ! dt_type(mi)); if (over) { --- 138,153 ---- i = 0; while (i < n) { ! s = v9fs_deserialize_stat(fcall->params.rread.data + i, ! n - i, &stat, v9ses->extended); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing stat\n"); return -EIO; } ! over = filldir(dirent, stat.name.str, stat.name.len, ! filp->f_pos, v9fs_qid2ino(&stat.qid), ! dt_type(&stat)); if (over) { *************** *** 173,177 **** FreeStructs: kfree(fcall); - kfree(mi); return ret; } --- 168,171 ---- *************** *** 194,216 **** fidnum = fid->fid; ! filemap_fdatawrite(inode->i_mapping); ! filemap_fdatawait(inode->i_mapping); if (fidnum >= 0) { - fid->fidopen--; dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, fid->fid); ! if (fid->fidopen == 0) { ! if (v9fs_t_clunk(v9ses, fidnum, NULL)) ! dprintk(DEBUG_ERROR, "clunk failed\n"); ! ! v9fs_put_idpool(fid->fid, &v9ses->fidpool); ! } kfree(fid->rdir_fcall); filp->private_data = NULL; - v9fs_fid_destroy(fid); } --- 188,204 ---- fidnum = fid->fid; ! filemap_write_and_wait(inode->i_mapping); if (fidnum >= 0) { dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, fid->fid); ! if (v9fs_t_clunk(v9ses, fidnum)) ! dprintk(DEBUG_ERROR, "clunk failed\n"); kfree(fid->rdir_fcall); + kfree(fid); filp->private_data = NULL; } Index: TODO =================================================================== RCS file: /cvsroot/v9fs/linux-9p/TODO,v retrieving revision 2.0 retrieving revision 2.1 diff -C2 -d -r2.0 -r2.1 *** TODO 6 Jun 2005 19:26:50 -0000 2.0 --- TODO 2 Mar 2006 21:30:17 -0000 2.1 *************** *** 1,29 **** - Things which need to be done: - - Clean-ness: - * delay module removal for system to quiesce - (need to wait for stuff to shut down before trying to free slabs) - * review mistat allocation (of maxdata) - this seems overzealous - - Peformance: - * remove extra copies in read and write path - * performance tuning - * come up with a cache model - * support multiple walks in t_walk and leverage from VFS - - 9P Correctness: - * revisit transient clunks - * new attach per user in extended mode - * Do a full validation versus Russ Cox's Plan 9 from User Space - - Future: - * locking infrastructure support - * kernel mode server (with Plan 9 srv like infrastructure) - * security/authentication support - - (See sourceforge bug-tracking for known bugs) - - Current batch of linux-kernel/linux-mentors/linux-fsdevel requests: - ------------------------------------------------------ - - (empty?) --- 0 ---- Index: debug.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/debug.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** debug.h 21 Sep 2005 17:43:51 -0000 2.2 --- debug.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 52,65 **** static inline void dump_data(const unsigned char *data, unsigned int datalen) { ! int i, j; ! int len = datalen; ! printk(KERN_DEBUG "data "); ! for (i = 0; i < len; i += 4) { ! for (j = 0; (j < 4) && (i + j < len); j++) ! printk(KERN_DEBUG "%02x", data[i + j]); ! printk(KERN_DEBUG " "); } ! printk(KERN_DEBUG "\n"); } #else /* DEBUG_DUMP_PKT */ --- 52,72 ---- static inline void dump_data(const unsigned char *data, unsigned int datalen) { ! int i, n; ! char buf[5*8]; ! n = 0; ! i = 0; ! while (i < datalen) { ! n += snprintf(buf+n, sizeof(buf)-n, "%02x", data[i++]); ! if (i%4 == 0) ! n += snprintf(buf+n, sizeof(buf)-n, " "); ! ! if (i%16 == 0) { ! dprintk(DEBUG_ERROR, "%s\n", buf); ! n = 0; ! } } ! ! dprintk(DEBUG_ERROR, "%s\n", buf); } #else /* DEBUG_DUMP_PKT */ Index: 9p.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** 9p.h 21 Sep 2005 17:43:51 -0000 2.2 --- 9p.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 4,7 **** --- 4,8 ---- * 9P protocol definitions. * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 101,107 **** --- 102,117 ---- }; + #define V9FS_NOTAG (u16)(~0) + #define V9FS_NOFID (u32)(~0) + #define V9FS_MAXWELEM 16 + /* ample room for Twrite/Rread header (iounit) */ #define V9FS_IOHDRSZ 24 + struct v9fs_str { + u16 len; + char *str; + }; + /* qids are the unique ID for a file (like an inode */ struct v9fs_qid { *************** *** 121,124 **** --- 131,157 ---- u32 mtime; u64 length; + struct v9fs_str name; + struct v9fs_str uid; + struct v9fs_str gid; + struct v9fs_str muid; + struct v9fs_str extension; /* 9p2000.u extensions */ + u32 n_uid; /* 9p2000.u extensions */ + u32 n_gid; /* 9p2000.u extensions */ + u32 n_muid; /* 9p2000.u extensions */ + }; + + /* file metadata (stat) structure used to create Twstat message + The is similar to v9fs_stat, but the strings don't point to + the same memory block and should be freed separately + */ + struct v9fs_wstat { + u16 size; + u16 type; + u32 dev; + struct v9fs_qid qid; + u32 mode; + u32 atime; + u32 mtime; + u64 length; char *name; char *uid; *************** *** 129,133 **** u32 n_gid; /* 9p2000.u extensions */ u32 n_muid; /* 9p2000.u extensions */ - char data[0]; }; --- 162,165 ---- *************** *** 136,151 **** struct Tversion { u32 msize; ! char *version; }; struct Rversion { u32 msize; ! char *version; }; struct Tauth { u32 afid; ! char *uname; ! char *aname; }; --- 168,183 ---- struct Tversion { u32 msize; ! struct v9fs_str version; }; struct Rversion { u32 msize; ! struct v9fs_str version; }; struct Tauth { u32 afid; ! struct v9fs_str uname; ! struct v9fs_str aname; }; *************** *** 155,164 **** struct Rerror { ! char *error; u32 errno; /* 9p2000.u extension */ }; struct Tflush { ! u32 oldtag; }; --- 187,196 ---- struct Rerror { ! struct v9fs_str error; u32 errno; /* 9p2000.u extension */ }; struct Tflush { ! u16 oldtag; }; *************** *** 169,174 **** u32 fid; u32 afid; ! char *uname; ! char *aname; }; --- 201,206 ---- u32 fid; u32 afid; ! struct v9fs_str uname; ! struct v9fs_str aname; }; *************** *** 180,190 **** u32 fid; u32 newfid; ! u32 nwname; ! char **wnames; }; struct Rwalk { ! u32 nwqid; ! struct v9fs_qid *wqids; }; --- 212,222 ---- u32 fid; u32 newfid; ! u16 nwname; ! struct v9fs_str wnames[16]; }; struct Rwalk { ! u16 nwqid; ! struct v9fs_qid wqids[16]; }; *************** *** 201,205 **** struct Tcreate { u32 fid; ! char *name; u32 perm; u8 mode; --- 233,237 ---- struct Tcreate { u32 fid; ! struct v9fs_str name; u32 perm; u8 mode; *************** *** 252,261 **** struct Rstat { ! struct v9fs_stat *stat; }; struct Twstat { u32 fid; ! struct v9fs_stat *stat; }; --- 284,293 ---- struct Rstat { ! struct v9fs_stat stat; }; struct Twstat { u32 fid; ! struct v9fs_stat stat; }; *************** *** 272,275 **** --- 304,308 ---- u8 id; u16 tag; + void *sdata; union { *************** *** 304,308 **** }; ! #define FCALL_ERROR(fcall) (fcall ? fcall->params.rerror.error : "") int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, --- 337,343 ---- }; ! #define PRINT_FCALL_ERROR(s, fcall) dprintk(DEBUG_ERROR, "%s: %.*s\n", s, \ ! fcall?fcall->params.rerror.error.len:0, \ ! fcall?fcall->params.rerror.error.str:""); int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, *************** *** 312,317 **** u32 fid, u32 afid, struct v9fs_fcall **rcall); ! int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **rcall); int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag); --- 347,351 ---- u32 fid, u32 afid, struct v9fs_fcall **rcall); ! int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid); int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag); *************** *** 321,325 **** int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_stat *stat, struct v9... [truncated message content] |