From: Eric V. H. <er...@us...> - 2006-03-12 20:18:59
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13980 Modified Files: 9p.c 9p.h Makefile debug.h fid.c fid.h mux.c trans_fd.c v9fs.c v9fs.h v9fs_vfs.h vfs_dentry.c vfs_file.c vfs_inode.c vfs_super.c Log Message: Updating snapshot that works on ubuntu to debug pwd problem. Index: vfs_file.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_file.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** vfs_file.c 2 Mar 2006 21:30:17 -0000 2.4 --- vfs_file.c 12 Mar 2006 20:18:53 -0000 2.5 *************** *** 54,145 **** { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *v9fid, *fid; struct v9fs_fcall *fcall = NULL; ! int open_mode = 0; ! unsigned int iounit = 0; ! int newfid = -1; ! 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); ! if (newfid < 0) { eprintk(KERN_WARNING, "newfid fails!\n"); return -ENOSPC; } ! result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL); ! ! if (result < 0) { ! v9fs_put_idpool(newfid, &v9ses->fidpool); dprintk(DEBUG_ERROR, "rewalk didn't work\n"); ! return -EBADF; } - fid->fid = newfid; - v9fid = fid; /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ ! open_mode = file->f_flags & 0x3; ! if (file->f_flags & O_EXCL) ! open_mode |= V9FS_OEXCL; ! if (v9ses->extended) { ! if (file->f_flags & O_TRUNC) ! open_mode |= V9FS_OTRUNC; ! if (file->f_flags & O_APPEND) ! open_mode |= V9FS_OAPPEND; ! } ! result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); ! if (result < 0) { ! PRINT_FCALL_ERROR("open failed", fcall); ! kfree(fcall); ! return result; ! } ! iounit = fcall->params.ropen.iounit; kfree(fcall); - } else { - /* create case */ - newfid = v9fid->fid; - iounit = v9fid->iounit; - v9fid->fidcreate = 0; - } - - file->private_data = v9fid; ! v9fid->rdir_pos = 0; ! v9fid->rdir_fcall = NULL; ! v9fid->fidopen = 1; ! v9fid->filp = file; ! v9fid->iounit = iounit; ! ! return 0; } --- 54,121 ---- { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *vfid; struct v9fs_fcall *fcall = NULL; ! int omode; ! int fid = V9FS_NOFID; ! int err; dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); ! vfid = v9fs_fid_lookup(file->f_dentry); ! if (!vfid) { dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); return -EBADF; } ! fid = v9fs_get_idpool(&v9ses->fidpool); ! if (fid < 0) { eprintk(KERN_WARNING, "newfid fails!\n"); return -ENOSPC; } ! err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); ! if (err < 0) { dprintk(DEBUG_ERROR, "rewalk didn't work\n"); ! goto put_fid; ! } ! ! vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); ! if (vfid == NULL) { ! dprintk(DEBUG_ERROR, "out of memory\n"); ! goto clunk_fid; } /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ ! omode = v9fs_uflags2omode(file->f_flags); ! err = v9fs_t_open(v9ses, fid, omode, &fcall); ! if (err < 0) { ! PRINT_FCALL_ERROR("open failed", fcall); ! goto destroy_vfid; ! } ! file->private_data = vfid; ! vfid->fid = fid; ! vfid->fidopen = 1; ! vfid->fidclunked = 0; ! vfid->iounit = fcall->params.ropen.iounit; ! vfid->rdir_pos = 0; ! vfid->rdir_fcall = NULL; ! vfid->filp = file; ! kfree(fcall); ! return 0; ! destroy_vfid: ! v9fs_fid_destroy(vfid); ! clunk_fid: ! v9fs_t_clunk(v9ses, fid); ! put_fid: ! v9fs_put_idpool(fid, &v9ses->fidpool); kfree(fcall); ! return err; } *************** *** 290,296 **** } while (count); - if(inode->i_mapping->nrpages) invalidate_inode_pages2(inode->i_mapping); - return total; } --- 266,270 ---- Index: mux.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/mux.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** mux.c 2 Mar 2006 21:30:17 -0000 2.4 --- mux.c 12 Mar 2006 20:18:53 -0000 2.5 *************** *** 70,74 **** unsigned char *extended; struct v9fs_transport *trans; ! struct v9fs_idpool tidpool; int err; wait_queue_head_t equeue; --- 70,74 ---- unsigned char *extended; struct v9fs_transport *trans; ! struct v9fs_idpool tagpool; int err; wait_queue_head_t equeue; *************** *** 280,285 **** m->extended = extended; m->trans = trans; ! idr_init(&m->tidpool.pool); ! init_MUTEX(&m->tidpool.lock); m->err = 0; init_waitqueue_head(&m->equeue); --- 280,285 ---- m->extended = extended; m->trans = trans; ! idr_init(&m->tagpool.pool); ! init_MUTEX(&m->tagpool.lock); m->err = 0; init_waitqueue_head(&m->equeue); *************** *** 635,638 **** --- 635,646 ---- } + if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { + char buf[150]; + + v9fs_printfcall(buf, sizeof(buf), m->rcall, + *m->extended); + printk(KERN_NOTICE ">>> %p %s\n", m, buf); + } + rcall = m->rcall; rbuf = m->rbuf; *************** *** 740,743 **** --- 748,758 ---- v9fs_set_tag(tc, n); + if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { + char buf[150]; + + v9fs_printfcall(buf, sizeof(buf), tc, *m->extended); + printk(KERN_NOTICE "<<< %p %s\n", m, buf); + } + req->tag = n; req->tcall = tc; *************** *** 964,968 **** int tag; ! tag = v9fs_get_idpool(&m->tidpool); if (tag < 0) return V9FS_NOTAG; --- 979,983 ---- int tag; ! tag = v9fs_get_idpool(&m->tagpool); if (tag < 0) return V9FS_NOTAG; *************** *** 973,977 **** 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); } --- 988,992 ---- static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) { ! if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool)) ! v9fs_put_idpool(tag, &m->tagpool); } Index: trans_fd.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/trans_fd.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** trans_fd.c 2 Mar 2006 21:32:34 -0000 1.2 --- trans_fd.c 12 Mar 2006 20:18:53 -0000 1.3 *************** *** 97,102 **** set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ! ret = vfs_write(ts->wr, (void __user *)v, len, ! &ts->wr->f_pos); set_fs(oldfs); --- 97,101 ---- set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ! ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); set_fs(oldfs); *************** *** 109,113 **** v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) { - int ret, n; struct v9fs_trans_fd *ts; --- 108,111 ---- *************** *** 147,152 **** { struct v9fs_transport *trans = v9ses->transport; ! struct v9fs_trans_fd *ts =kmalloc(sizeof(struct v9fs_trans_fd), ! GFP_KERNEL); if (!ts) return -ENOMEM; --- 145,150 ---- { struct v9fs_transport *trans = v9ses->transport; ! struct v9fs_trans_fd *ts = kmalloc(sizeof(struct v9fs_trans_fd), ! GFP_KERNEL); if (!ts) return -ENOMEM; *************** *** 195,204 **** if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) { ! //TODO: sock_unmap_fd(fd); eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n"); goto release_csocket; } ! ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= O_NONBLOCK; return 0; } --- 193,203 ---- if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) { ! sockfd_put(csocket); eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n"); goto release_csocket; } ! ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= ! O_NONBLOCK; return 0; } *************** *** 215,220 **** sin_server.sin_port = htons(v9ses->port); sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); ! ! if(!csocket) { eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n"); return -1; --- 214,219 ---- sin_server.sin_port = htons(v9ses->port); sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); ! ! if (!csocket) { eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n"); return -1; *************** *** 250,254 **** strcpy(sun_server.sun_path, addr); sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); ! ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, sizeof(struct sockaddr_un) - 1, 0); /* -1 *is* important */ if (ret < 0) { eprintk(KERN_ERR, --- 249,254 ---- strcpy(sun_server.sun_path, addr); sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); ! ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, ! sizeof(struct sockaddr_un) - 1, 0); if (ret < 0) { eprintk(KERN_ERR, *************** *** 273,277 **** return; ! ts = xchg(&trans->priv, NULL); /* do we really need xchg? */ if (!ts) --- 273,277 ---- return; ! ts = xchg(&trans->priv, NULL); if (!ts) Index: vfs_super.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_super.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_super.c 2 Mar 2006 21:30:17 -0000 2.3 --- vfs_super.c 12 Mar 2006 20:18:54 -0000 2.4 *************** *** 147,151 **** root = d_alloc_root(inode); - if (!root) { retval = -ENOMEM; --- 147,150 ---- *************** *** 158,166 **** 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; --- 157,165 ---- if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); + kfree(fcall); v9fs_t_clunk(v9ses, newfid); } else { /* Setup the Root Inode */ ! root_fid = v9fs_fid_create(v9ses, newfid); if (root_fid == NULL) { retval = -ENOMEM; *************** *** 168,171 **** --- 167,176 ---- } + retval = v9fs_fid_insert(root_fid, root); + if (retval < 0) { + kfree(fcall); + goto put_back_sb; + } + root_fid->qid = fcall->params.rstat.stat.qid; root->d_inode->i_ino = Index: 9p.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** 9p.c 2 Mar 2006 21:30:17 -0000 2.3 --- 9p.c 12 Mar 2006 20:18:47 -0000 2.4 *************** *** 153,157 **** * v9fs_v9fs_t_flush - flush a pending transaction * @v9ses: 9P2000 session information ! * @tag: tid to release * */ --- 153,157 ---- * v9fs_v9fs_t_flush - flush a pending transaction * @v9ses: 9P2000 session information ! * @tag: tag to release * */ Index: v9fs.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** v9fs.c 2 Mar 2006 21:30:17 -0000 2.4 --- v9fs.c 12 Mar 2006 20:18:53 -0000 2.5 *************** *** 290,294 **** v9fs_debug_level = v9ses->debug; ! /* id pools that are session-dependent: FIDs and TIDs */ idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); --- 290,294 ---- v9fs_debug_level = v9ses->debug; ! /* id pools that are session-dependent: fids and tags */ idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); *************** *** 398,401 **** --- 398,402 ---- if (v9ses->afid != ~0) { + dprintk(DEBUG_ERROR, "afid not equal to ~0\n"); if (v9fs_t_clunk(v9ses, v9ses->afid)) dprintk(DEBUG_ERROR, "clunk failed\n"); Index: v9fs.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** v9fs.h 2 Mar 2006 21:30:17 -0000 2.3 --- v9fs.h 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 92,109 **** #define V9FS_DEFANAME "" - /* inital pool sizes for fids and tags */ - #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 --- 92,104 ---- #define V9FS_DEFANAME "" #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.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** v9fs_vfs.h 2 Mar 2006 21:30:17 -0000 2.3 --- v9fs_vfs.h 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 52,53 **** --- 52,54 ---- void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat); void v9fs_dentry_release(struct dentry *); + int v9fs_uflags2omode(int uflags); Index: vfs_inode.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_inode.c,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -d -r2.5 -r2.6 *** vfs_inode.c 2 Mar 2006 21:30:17 -0000 2.5 --- vfs_inode.c 12 Mar 2006 20:18:53 -0000 2.6 *************** *** 126,129 **** --- 126,161 ---- } + int v9fs_uflags2omode(int uflags) + { + int ret; + + ret = 0; + switch (uflags & 3) { + default: + case O_RDONLY: + ret = V9FS_OREAD; + break; + + case O_WRONLY: + ret = V9FS_OWRITE; + break; + + case O_RDWR: + ret = V9FS_ORDWR; + break; + } + + if (uflags & O_EXCL) + ret |= V9FS_OEXCL; + + if (uflags & O_TRUNC) + ret |= V9FS_OTRUNC; + + if (uflags & O_APPEND) + ret |= V9FS_OAPPEND; + + return ret; + } + /** * v9fs_blank_wstat - helper function to setup a 9P stat structure *************** *** 133,138 **** */ ! static void ! v9fs_blank_wstat(struct v9fs_wstat *wstat) { wstat->type = ~0; --- 165,169 ---- */ ! static void v9fs_blank_wstat(struct v9fs_wstat *wstat) { wstat->type = ~0; *************** *** 164,168 **** struct inode *v9fs_get_inode(struct super_block *sb, int mode) { ! struct inode *inode = NULL; struct v9fs_session_info *v9ses = sb->s_fs_info; --- 195,199 ---- struct inode *v9fs_get_inode(struct super_block *sb, int mode) { ! struct inode *inode; struct v9fs_session_info *v9ses = sb->s_fs_info; *************** *** 185,194 **** case S_IFCHR: case S_IFSOCK: ! if(!v9ses->extended) { ! dprintk(DEBUG_ERROR, "special files without extended mode\n"); return ERR_PTR(-EINVAL); } ! init_special_inode(inode, inode->i_mode, ! inode->i_rdev); break; case S_IFREG: --- 216,225 ---- case S_IFCHR: case S_IFSOCK: ! if (!v9ses->extended) { ! dprintk(DEBUG_ERROR, ! "special files without extended mode\n"); return ERR_PTR(-EINVAL); } ! init_special_inode(inode, inode->i_mode, inode->i_rdev); break; case S_IFREG: *************** *** 197,202 **** break; case S_IFLNK: ! if(!v9ses->extended) { ! dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n"); return ERR_PTR(-EINVAL); } --- 228,234 ---- break; case S_IFLNK: ! if (!v9ses->extended) { ! dprintk(DEBUG_ERROR, ! "extended modes used w/o 9P2000.u\n"); return ERR_PTR(-EINVAL); } *************** *** 205,209 **** case S_IFDIR: inode->i_nlink++; ! if(v9ses->extended) inode->i_op = &v9fs_dir_inode_operations_ext; else --- 237,241 ---- case S_IFDIR: inode->i_nlink++; ! if (v9ses->extended) inode->i_op = &v9fs_dir_inode_operations_ext; else *************** *** 223,391 **** } - /** - * v9fs_create - helper function to create files and directories - * @dir: directory inode file is being created in - * @file_dentry: dentry file is being created in - * @perm: permissions file is being created with - * @open_mode: resulting open mode for file - * - */ - static int ! v9fs_create(struct inode *dir, ! struct dentry *file_dentry, ! unsigned int perm, unsigned int open_mode) { ! struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); ! struct super_block *sb = dir->i_sb; ! struct v9fs_fid *dirfid = ! v9fs_fid_lookup(file_dentry->d_parent); ! struct v9fs_fid *fid = NULL; ! struct inode *file_inode = NULL; ! struct v9fs_fcall *fcall = NULL; ! struct v9fs_qid qid; ! int dirfidnum = -1; ! long newfid = -1; ! int result = 0; ! unsigned int iounit = 0; ! int wfidno = -1; int err; ! perm = unixmode2p9mode(v9ses, perm); ! ! dprintk(DEBUG_VFS, "dir: %p dentry: %p perm: %o mode: %o\n", dir, ! file_dentry, perm, open_mode); ! ! if (!dirfid) ! return -EBADF; ! ! dirfidnum = dirfid->fid; ! if (dirfidnum < 0) { ! dprintk(DEBUG_ERROR, "No fid for the directory #%lu\n", ! dir->i_ino); ! return -EBADF; ! } ! ! if (file_dentry->d_inode) { ! dprintk(DEBUG_ERROR, ! "Odd. There is an inode for dir %lu, name :%s:\n", ! dir->i_ino, file_dentry->d_name.name); ! return -EEXIST; ! } ! ! newfid = v9fs_get_idpool(&v9ses->fidpool); ! if (newfid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! return -ENOSPC; } ! result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall); ! if (result < 0) { PRINT_FCALL_ERROR("clone error", fcall); ! v9fs_put_idpool(newfid, &v9ses->fidpool); ! newfid = -1; ! goto CleanUpFid; } - kfree(fcall); - fcall = NULL; ! result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name, ! perm, open_mode, &fcall); ! if (result < 0) { PRINT_FCALL_ERROR("create fails", fcall); ! goto CleanUpFid; } ! iounit = fcall->params.rcreate.iounit; ! qid = fcall->params.rcreate.qid; kfree(fcall); ! fcall = NULL; ! if (!(perm&V9FS_DMDIR)) { ! fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1); ! dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate); ! if (!fid) { ! result = -ENOMEM; ! goto CleanUpFid; ! } ! fid->qid = qid; ! fid->iounit = iounit; ! } else { ! err = v9fs_t_clunk(v9ses, newfid); ! newfid = -1; ! if (err < 0) ! dprintk(DEBUG_ERROR, "clunk for mkdir failed: %d\n", err); ! } ! /* walk to the newly created file and put the fid in the dentry */ ! wfidno = v9fs_get_idpool(&v9ses->fidpool); ! if (wfidno < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! return -ENOSPC; } ! result = v9fs_t_walk(v9ses, dirfidnum, wfidno, ! (char *) file_dentry->d_name.name, &fcall); ! if (result < 0) { ! PRINT_FCALL_ERROR("clone error", fcall); ! v9fs_put_idpool(wfidno, &v9ses->fidpool); ! wfidno = -1; ! goto CleanUpFid; } kfree(fcall); fcall = NULL; ! if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) { ! v9fs_put_idpool(wfidno, &v9ses->fidpool); ! ! goto CleanUpFid; } ! if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) || ! (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) || ! (perm & V9FS_DMDEVICE)) ! return 0; ! result = v9fs_t_stat(v9ses, wfidno, &fcall); ! if (result < 0) { ! PRINT_FCALL_ERROR("stat error", fcall); ! goto CleanUpFid; ! } ! file_inode = v9fs_get_inode(sb, ! p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode)); ! if ((!file_inode) || IS_ERR(file_inode)) { ! dprintk(DEBUG_ERROR, "create inode failed\n"); ! result = -EBADF; ! goto CleanUpFid; } ! v9fs_stat2inode(&fcall->params.rstat.stat, file_inode, sb); ! kfree(fcall); ! fcall = NULL; ! file_dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(file_dentry, file_inode); ! return 0; ! CleanUpFid: kfree(fcall); ! fcall = NULL; ! if (newfid >= 0) { ! err = v9fs_t_clunk(v9ses, newfid); ! if (err < 0) ! dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); ! } ! if (wfidno >= 0) { ! err = v9fs_t_clunk(v9ses, wfidno); ! if (err < 0) ! dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); ! } ! return result; } --- 255,386 ---- } static int ! v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, ! u32 perm, u8 mode, u32 * fidp, struct v9fs_qid *qid, u32 * iounit) { ! u32 fid; int err; + struct v9fs_fcall *fcall; ! fid = v9fs_get_idpool(&v9ses->fidpool); ! if (fid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! err = -ENOSPC; ! goto error; } ! err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); ! if (err < 0) { PRINT_FCALL_ERROR("clone error", fcall); ! goto error; } kfree(fcall); ! err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); ! if (err < 0) { PRINT_FCALL_ERROR("create fails", fcall); ! goto error; } ! if (iounit) ! *iounit = fcall->params.rcreate.iounit; ! ! if (qid) ! *qid = fcall->params.rcreate.qid; ! ! if (fidp) ! *fidp = fid; ! kfree(fcall); ! return 0; ! error: ! if (fid >= 0) ! v9fs_put_idpool(fid, &v9ses->fidpool); ! kfree(fcall); ! return err; ! } ! static struct v9fs_fid *v9fs_clone_walk(struct v9fs_session_info *v9ses, ! u32 fid, struct dentry *dentry) ! { ! int err; ! u32 nfid; ! struct v9fs_fid *ret; ! struct v9fs_fcall *fcall; ! ! nfid = v9fs_get_idpool(&v9ses->fidpool); ! if (nfid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! err = -ENOSPC; ! goto error; } ! err = v9fs_t_walk(v9ses, fid, nfid, (char *)dentry->d_name.name, ! &fcall); ! ! if (err < 0) { ! PRINT_FCALL_ERROR("walk error", fcall); ! v9fs_put_idpool(nfid, &v9ses->fidpool); ! goto error; } + kfree(fcall); fcall = NULL; + ret = v9fs_fid_create(v9ses, nfid); + if (!ret) { + err = -ENOMEM; + goto clunk_fid; + } ! err = v9fs_fid_insert(ret, dentry); ! if (err < 0) { ! v9fs_fid_destroy(ret); ! goto clunk_fid; } ! return ret; ! clunk_fid: ! v9fs_t_clunk(v9ses, nfid); + error: + kfree(fcall); + return ERR_PTR(err); + } ! struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, ! struct super_block *sb) ! { ! int err, umode; ! struct inode *ret; ! struct v9fs_fcall *fcall; ! ret = NULL; ! err = v9fs_t_stat(v9ses, fid, &fcall); ! if (err) { ! PRINT_FCALL_ERROR("stat error", fcall); ! goto error; } ! umode = p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode); ! ret = v9fs_get_inode(sb, umode); ! if (IS_ERR(ret)) { ! err = PTR_ERR(ret); ! ret = NULL; ! goto error; ! } ! v9fs_stat2inode(&fcall->params.rstat.stat, ret, sb); ! kfree(fcall); ! return ret; ! error: kfree(fcall); ! if (ret) ! iput(ret); ! return ERR_PTR(err); } *************** *** 417,422 **** if (!v9fid) { ! dprintk(DEBUG_ERROR, ! "no v9fs_fid\n"); return -EBADF; } --- 412,416 ---- if (!v9fid) { ! dprintk(DEBUG_ERROR, "no v9fs_fid\n"); return -EBADF; } *************** *** 441,449 **** } /** * v9fs_vfs_create - VFS hook to create files * @inode: directory inode that is being deleted * @dentry: dentry that is being deleted ! * @perm: create permissions * @nd: path information * --- 435,450 ---- } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + static int v9fs_open_created(struct inode *inode, struct file *file) + { + return 0; + } + #endif + /** * v9fs_vfs_create - VFS hook to create files * @inode: directory inode that is being deleted * @dentry: dentry that is being deleted ! * @mode: create permissions * @nd: path information * *************** *** 451,458 **** static int ! v9fs_vfs_create(struct inode *inode, struct dentry *dentry, int perm, struct nameidata *nd) { ! return v9fs_create(inode, dentry, perm, O_RDWR); } --- 452,536 ---- static int ! v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ! int err; ! u32 fid, perm, iounit; ! int flags; ! struct v9fs_session_info *v9ses; ! struct v9fs_fid *dfid, *vfid; ! struct inode *inode; ! struct v9fs_qid qid; ! ! inode = NULL; ! vfid = NULL; ! v9ses = v9fs_inode2v9ses(dir); ! dfid = v9fs_fid_lookup(dentry->d_parent); ! perm = unixmode2p9mode(v9ses, mode); ! ! if (nd && nd->flags & LOOKUP_OPEN) ! flags = nd->intent.open.flags - 1; ! else ! flags = O_RDWR; ! ! err = v9fs_create(v9ses, dfid->fid, (char *)dentry->d_name.name, ! perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); ! ! if (err) ! goto error; ! ! vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); ! if (IS_ERR(vfid)) { ! err = PTR_ERR(vfid); ! vfid = NULL; ! goto error; ! } ! ! inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); ! if (IS_ERR(inode)) { ! err = PTR_ERR(inode); ! inode = NULL; ! goto error; ! } ! ! dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(dentry, inode); ! ! if (nd && nd->flags & LOOKUP_OPEN) { ! #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) ! return -ENOTSUPP; ! #else ! struct v9fs_fid *ffid; ! struct file *filp; ! ! ffid = v9fs_fid_create(v9ses, fid); ! if (!ffid) ! return -ENOMEM; ! ! filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); ! if (IS_ERR(filp)) { ! v9fs_fid_destroy(ffid); ! return PTR_ERR(filp); ! } ! ! ffid->rdir_pos = 0; ! ffid->rdir_fcall = NULL; ! ffid->fidopen = 1; ! ffid->iounit = iounit; ! ffid->filp = filp; ! filp->private_data = ffid; ! #endif ! } ! ! return 0; ! ! error: ! if (vfid) ! v9fs_fid_destroy(vfid); ! ! if (inode) ! iput(inode); ! ! return err; } *************** *** 465,471 **** */ ! static int v9fs_vfs_mkdir(struct inode *inode, struct dentry *dentry, int mode) { ! return v9fs_create(inode, dentry, mode | S_IFDIR, O_RDONLY); } --- 543,597 ---- */ ! static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { ! int err; ! u32 fid, perm; ! struct v9fs_session_info *v9ses; ! struct v9fs_fid *dfid, *vfid; ! struct inode *inode; ! ! inode = NULL; ! vfid = NULL; ! v9ses = v9fs_inode2v9ses(dir); ! dfid = v9fs_fid_lookup(dentry->d_parent); ! perm = unixmode2p9mode(v9ses, mode | S_IFDIR); ! ! err = v9fs_create(v9ses, dfid->fid, (char *)dentry->d_name.name, ! perm, V9FS_OREAD, &fid, NULL, NULL); ! ! if (err) { ! dprintk(DEBUG_ERROR, "create error %d\n", err); ! goto error; ! } ! ! err = v9fs_t_clunk(v9ses, fid); ! if (err) { ! dprintk(DEBUG_ERROR, "clunk error %d\n", err); ! goto error; ! } ! ! vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); ! if (IS_ERR(vfid)) { ! err = PTR_ERR(vfid); ! vfid = NULL; ! goto error; ! } ! ! inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); ! if (IS_ERR(inode)) { ! err = PTR_ERR(inode); ! inode = NULL; ! goto error; ! } ! ! dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(dentry, inode); ! return 0; ! ! error: ! if (vfid) ! v9fs_fid_destroy(vfid); ! ! return err; } *************** *** 517,523 **** } ! result = ! v9fs_t_walk(v9ses, dirfidnum, newfid, (char *)dentry->d_name.name, ! NULL); if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); --- 643,648 ---- } ! result = v9fs_t_walk(v9ses, dirfidnum, newfid, ! (char *)dentry->d_name.name, NULL); if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); *************** *** 540,544 **** inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses, ! fcall->params.rstat.stat.mode)); if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { --- 665,670 ---- inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses, ! fcall->params.rstat.stat. ! mode)); if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { *************** *** 552,556 **** inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); ! fid = v9fs_fid_create(dentry, v9ses, newfid, 0); if (fid == NULL) { dprintk(DEBUG_ERROR, "couldn't insert\n"); --- 678,682 ---- inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); ! fid = v9fs_fid_create(v9ses, newfid); if (fid == NULL) { dprintk(DEBUG_ERROR, "couldn't insert\n"); *************** *** 559,562 **** --- 685,692 ---- } + result = v9fs_fid_insert(fid, dentry); + if (result < 0) + goto FreeFcall; + fid->qid = fcall->params.rstat.stat.qid; *************** *** 614,621 **** struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); ! struct v9fs_fid *olddirfid = ! v9fs_fid_lookup(old_dentry->d_parent); ! struct v9fs_fid *newdirfid = ! v9fs_fid_lookup(new_dentry->d_parent); struct v9fs_wstat wstat; struct v9fs_fcall *fcall = NULL; --- 744,749 ---- struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); ! struct v9fs_fid *olddirfid = v9fs_fid_lookup(old_dentry->d_parent); ! struct v9fs_fid *newdirfid = v9fs_fid_lookup(new_dentry->d_parent); struct v9fs_wstat wstat; struct v9fs_fcall *fcall = NULL; *************** *** 652,656 **** v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.name = (char *) new_dentry->d_name.name; retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); --- 780,784 ---- v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.name = (char *)new_dentry->d_name.name; retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); *************** *** 694,698 **** else { v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode, ! dentry->d_inode->i_sb); generic_fillattr(dentry->d_inode, stat); } --- 822,826 ---- else { v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode, ! dentry->d_inode->i_sb); generic_fillattr(dentry->d_inode, stat); } *************** *** 768,772 **** void v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, ! struct super_block *sb) { int n; --- 896,900 ---- void v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, ! struct super_block *sb) { int n; *************** *** 795,800 **** n = stat->extension.len; ! if (n > sizeof(ext)-1) ! n = sizeof(ext)-1; memmove(ext, stat->extension.str, n); ext[n] = 0; --- 923,928 ---- n = stat->extension.len; ! if (n > sizeof(ext) - 1) ! n = sizeof(ext) - 1; memmove(ext, stat->extension.str, n); ext[n] = 0; *************** *** 887,895 **** /* copy extension buffer into buffer */ ! if (fcall->params.rstat.stat.extension.len+1 < buflen) ! buflen = fcall->params.rstat.stat.extension.len + 1; memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); ! buffer[buflen-1] = 0; retval = buflen; --- 1015,1023 ---- /* copy extension buffer into buffer */ ! if (fcall->params.rstat.stat.extension.len < buflen) ! buflen = fcall->params.rstat.stat.extension.len; memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); ! buffer[buflen - 1] = 0; retval = buflen; *************** *** 935,939 **** } - /** * v9fs_vfs_follow_link - follow a symlink path --- 1063,1066 ---- *************** *** 954,958 **** else { len = v9fs_readlink(dentry, link, PATH_MAX); - if (len < 0) { __putname(link); --- 1081,1084 ---- *************** *** 976,980 **** link = ERR_PTR(-ENOMEM); else { ! len = v9fs_readlink(dentry, link, PATH_MAX); if (len < 0) { --- 1102,1106 ---- link = ERR_PTR(-ENOMEM); else { ! len = v9fs_readlink(dentry, link, strlen(link)); if (len < 0) { *************** *** 1010,1039 **** static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ! int mode, const char *extension) { ! int err, retval; struct v9fs_session_info *v9ses; struct v9fs_fcall *fcall; - struct v9fs_fid *fid; struct v9fs_wstat wstat; - v9ses = v9fs_inode2v9ses(dir); - retval = -EPERM; fcall = NULL; if (!v9ses->extended) { dprintk(DEBUG_ERROR, "not extended\n"); ! goto free_mem; } ! /* issue a create */ ! retval = v9fs_create(dir, dentry, mode, 0); ! if (retval != 0) ! goto free_mem; ! fid = v9fs_fid_get_created(dentry); ! if (!fid) { ! dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n"); ! goto free_mem; } --- 1136,1183 ---- static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ! int mode, const char *extension) { ! int err; ! u32 fid, perm; struct v9fs_session_info *v9ses; + struct v9fs_fid *dfid, *vfid; + struct inode *inode; struct v9fs_fcall *fcall; struct v9fs_wstat wstat; fcall = NULL; + inode = NULL; + vfid = NULL; + v9ses = v9fs_inode2v9ses(dir); + dfid = v9fs_fid_lookup(dentry->d_parent); + perm = unixmode2p9mode(v9ses, mode); if (!v9ses->extended) { dprintk(DEBUG_ERROR, "not extended\n"); ! return -EPERM; } ! err = v9fs_create(v9ses, dfid->fid, (char *)dentry->d_name.name, ! perm, V9FS_OREAD, &fid, NULL, NULL); ! if (err) ! goto error; ! ! err = v9fs_t_clunk(v9ses, fid); ! if (err) ! goto error; ! ! vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); ! if (IS_ERR(vfid)) { ! err = PTR_ERR(vfid); ! vfid = NULL; ! goto error; ! } ! ! inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); ! if (IS_ERR(inode)) { ! err = PTR_ERR(inode); ! inode = NULL; ! goto error; } *************** *** 1041,1062 **** v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.extension = (char *) extension; ! retval = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall); ! if (retval < 0) { ! PRINT_FCALL_ERROR("wstat error", fcall); ! goto free_mem; ! } ! ! err = v9fs_t_clunk(v9ses, fid->fid); if (err < 0) { ! dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); ! goto free_mem; } ! d_drop(dentry); /* FID - will this also clunk? */ ! free_mem: kfree(fcall); ! return retval; } --- 1185,1210 ---- v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.extension = (char *)extension; ! err = v9fs_t_wstat(v9ses, vfid->fid, &wstat, &fcall); if (err < 0) { ! PRINT_FCALL_ERROR("wstat error", fcall); ! goto error; } ! kfree(fcall); ! dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(dentry, inode); ! return 0; ! error: kfree(fcall); ! if (vfid) ! v9fs_fid_destroy(vfid); ! ! if (inode) ! iput(inode); ! ! return err; ! } Index: Makefile =================================================================== RCS file: /cvsroot/v9fs/linux-9p/Makefile,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** Makefile 2 Mar 2006 21:30:17 -0000 2.2 --- Makefile 12 Mar 2006 20:18:51 -0000 2.3 *************** *** 1,3 **** ! 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),) --- 1,3 ---- ! 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 fcprint.o ifneq ($(KERNELRELEASE),) Index: debug.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/debug.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** debug.h 2 Mar 2006 21:30:17 -0000 2.3 --- debug.h 12 Mar 2006 20:18:52 -0000 2.4 *************** *** 31,34 **** --- 31,35 ---- #define DEBUG_TRANS (1<<6) #define DEBUG_SLABS (1<<7) + #define DEBUG_FCALL (1<<8) #define DEBUG_DUMP_PKT 0 Index: 9p.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** 9p.h 2 Mar 2006 21:30:17 -0000 2.3 --- 9p.h 12 Mar 2006 20:18:50 -0000 2.4 *************** *** 375,376 **** --- 375,379 ---- u32 count, const char __user * data, struct v9fs_fcall **rcall); + int v9fs_printfcall(char *, int, struct v9fs_fcall *, int); + int v9fs_dumpdata(char *, int, u8 *, int); + int v9fs_printstat(char *, int, struct v9fs_stat *, int); Index: fid.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/fid.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** fid.c 2 Mar 2006 21:30:17 -0000 2.3 --- fid.c 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 2,6 **** * V9FS FID Management * ! * Copyright (C) 2005 by Eric Van Hensbergen <er...@gm...> * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * V9FS FID Management * ! * Copyright (C) 2005, 2006 by Eric Van Hensbergen <er...@gm...> * * This program is free software; you can redistribute it and/or modify *************** *** 41,45 **** */ ! static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; --- 41,45 ---- */ ! int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; *************** *** 58,62 **** fid->uid = current->uid; - fid->pid = current->pid; list_add(&fid->list, fid_list); return 0; --- 58,61 ---- *************** *** 69,80 **** */ ! struct v9fs_fid *v9fs_fid_create(struct dentry *dentry, ! struct v9fs_session_info *v9ses, int fid, int create) { struct v9fs_fid *new; ! dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n", ! dentry, fid, create); ! new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); if (new == NULL) { --- 68,76 ---- */ ! struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) { struct v9fs_fid *new; ! dprintk(DEBUG_9P, "fid create fid %d\n", fid); new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); if (new == NULL) { *************** *** 86,102 **** new->v9ses = v9ses; new->fidopen = 0; - new->fidcreate = create; new->fidclunked = 0; new->iounit = 0; new->rdir_pos = 0; new->rdir_fcall = NULL; ! if (v9fs_fid_insert(new, dentry) == 0) ! return new; ! else { ! dprintk(DEBUG_ERROR, "Problems inserting to dentry\n"); ! kfree(new); ! return NULL; ! } } --- 82,92 ---- new->v9ses = v9ses; new->fidopen = 0; new->fidclunked = 0; new->iounit = 0; new->rdir_pos = 0; new->rdir_fcall = NULL; + INIT_LIST_HEAD(&new->list); ! return new; } *************** *** 114,177 **** /** - * v9fs_fid_walk_up - walks from the process current directory - * up to the specified dentry. - */ - static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) - { - int fidnum, cfidnum, err; - struct v9fs_fid *cfid; - struct dentry *cde; - struct v9fs_session_info *v9ses; - - v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode); - cfid = v9fs_fid_lookup(current->fs->pwd); - if (cfid == NULL) { - dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n"); - return ERR_PTR(-ENOENT); - } - - cfidnum = cfid->fid; - cde = current->fs->pwd; - /* TODO: take advantage of multiwalk */ - - fidnum = v9fs_get_idpool(&v9ses->fidpool); - if (fidnum < 0) { - dprintk(DEBUG_ERROR, "could not get a new fid num\n"); - err = -ENOENT; - goto clunk_fid; - } - - while (cde != dentry) { - if (cde == cde->d_parent) { - dprintk(DEBUG_ERROR, "can't find dentry\n"); - err = -ENOENT; - goto clunk_fid; - } - - err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL); - if (err < 0) { - dprintk(DEBUG_ERROR, "problem walking to parent\n"); - goto clunk_fid; - } - - cfidnum = fidnum; - cde = cde->d_parent; - } - - return v9fs_fid_create(dentry, v9ses, fidnum, 0); - - clunk_fid: - v9fs_t_clunk(v9ses, fidnum); - return ERR_PTR(err); - } - - /** * v9fs_fid_lookup - retrieve the right fid from a particular dentry * @dentry: dentry to look for fid in * @type: intent of lookup (operation or traversal) * ! * search list of fids associated with a dentry for a fid with a matching ! * thread id or uid. If that fails, look up the dentry's parents to see if you ! * can find a matching fid. * */ --- 104,114 ---- /** * v9fs_fid_lookup - retrieve the right fid from a particular dentry * @dentry: dentry to look for fid in * @type: intent of lookup (operation or traversal) * ! * find a fid in the dentry ! * ! * TODO: only match fids that have the same uid as current user * */ *************** *** 180,252 **** { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; - struct v9fs_fid *current_fid = NULL; - struct v9fs_fid *temp = NULL; struct v9fs_fid *return_fid = NULL; dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); ! if (fid_list) { ! list_for_each_entry_safe(current_fid, temp, fid_list, list) { ! if (!current_fid->fidcreate) { ! return_fid = current_fid; ! break; ! } ! } ! ! if (!return_fid) ! return_fid = current_fid; ! } ! ! /* we are at the root but didn't match */ ! if ((!return_fid) && (dentry->d_parent == dentry)) { ! /* TODO: clone attach with new uid */ ! return_fid = current_fid; ! } if (!return_fid) { ! struct dentry *par = current->fs->pwd->d_parent; ! int count = 1; ! while (par != NULL) { ! if (par == dentry) ! break; ! count++; ! if (par == par->d_parent) { ! dprintk(DEBUG_ERROR, ! "got to root without finding dentry\n"); ! break; ! } ! par = par->d_parent; ! } ! ! /* XXX - there may be some duplication we can get rid of */ ! if (par == dentry) { ! return_fid = v9fs_fid_walk_up(dentry); ! if (IS_ERR(return_fid)) ! return_fid = NULL; ! } } return return_fid; } - - struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry) - { - struct list_head *fid_list; - struct v9fs_fid *fid, *ftmp, *ret; - - dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); - fid_list = (struct list_head *)dentry->d_fsdata; - ret = NULL; - if (fid_list) { - list_for_each_entry_safe(fid, ftmp, fid_list, list) { - if (fid->fidcreate && fid->pid == current->pid) { - list_del(&fid->list); - ret = fid; - break; - } - } - } - - dprintk(DEBUG_9P, "return %p\n", ret); - return ret; - } --- 117,131 ---- { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; struct v9fs_fid *return_fid = NULL; dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); ! if (fid_list) ! return_fid = list_entry(fid_list->next, struct v9fs_fid, list); if (!return_fid) { ! dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); } return return_fid; } Index: fid.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/fid.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** fid.h 2 Mar 2006 21:30:17 -0000 2.3 --- fid.h 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 34,38 **** u32 fid; unsigned char fidopen; /* set when fid is opened */ - unsigned char fidcreate; /* set when fid was just created */ unsigned char fidclunked; /* set when fid has already been clunked */ --- 34,37 ---- *************** *** 46,50 **** /* management stuff */ - pid_t pid; /* thread associated with this fid */ uid_t uid; /* user associated with this fid */ --- 45,48 ---- *************** *** 57,60 **** struct v9fs_fid *v9fs_fid_get_created(struct dentry *); void v9fs_fid_destroy(struct v9fs_fid *fid); ! struct v9fs_fid *v9fs_fid_create(struct dentry *, ! struct v9fs_session_info *v9ses, int fid, int create); --- 55,58 ---- struct v9fs_fid *v9fs_fid_get_created(struct dentry *); void v9fs_fid_destroy(struct v9fs_fid *fid); ! struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); ! int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); Index: vfs_dentry.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_dentry.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_dentry.c 2 Mar 2006 21:30:17 -0000 2.3 --- vfs_dentry.c 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 44,88 **** /** ! * v9fs_dentry_validate - VFS dcache hook to validate cache ! * @dentry: dentry that is being validated ! * @nd: path data ! * ! * dcache really shouldn't be used for 9P2000 as at all due to ! * potential attached semantics to directory traversal (walk). * ! * FUTURE: look into how to use dcache to allow multi-stage ! * walks in Plan 9 & potential for better dcache operation which ! * would remain valid for Plan 9 semantics. Older versions ! * had validation via stat for those interested. However, since ! * stat has the same approximate overhead as walk there really ! * is no difference. The only improvement would be from a ! * time-decay cache like NFS has and that undermines the ! * synchronous nature of 9P2000. * */ ! static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd) { ! struct dentry *dc = current->fs->pwd; ! ! dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry); ! if (v9fs_fid_lookup(dentry)) { ! dprintk(DEBUG_VFS, "VALID\n"); ! return 1; ! } ! ! while (dc != NULL) { ! if (dc == dentry) { ! dprintk(DEBUG_VFS, "VALID\n"); ! return 1; ! } ! if (dc == dc->d_parent) ! break; ! ! dc = dc->d_parent; ! } ! ! dprintk(DEBUG_VFS, "INVALID\n"); ! return 0; } --- 44,59 ---- /** ! * v9fs_dentry_delete - called when dentry refcount equals 0 ! * @dentry: dentry in question * ! * By returning 1 here we should remove cacheing of unused ! * dentry components. * */ ! int v9fs_dentry_delete(struct dentry *dentry) { ! dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); ! return 1; } *************** *** 119,123 **** struct dentry_operations v9fs_dentry_operations = { ! .d_revalidate = v9fs_dentry_validate, .d_release = v9fs_dentry_release, }; --- 90,94 ---- struct dentry_operations v9fs_dentry_operations = { ! .d_delete = v9fs_dentry_delete, .d_release = v9fs_dentry_release, }; |