From: Eric Van Hensbergen Signed-off-by: Latchesar Ionkov Signed-off-by: Eric Van Hensbegren Signed-off-by: Andrew Morton --- fs/9p/trans_fd.c | 42 +++++++++++++++++++++++++++++++++++++++--- fs/9p/v9fs.c | 5 ----- 2 files changed, 39 insertions(+), 8 deletions(-) diff -puN fs/9p/trans_fd.c~v9fs-transport-modules-cleanup-fd-transport fs/9p/trans_fd.c --- devel/fs/9p/trans_fd.c~v9fs-transport-modules-cleanup-fd-transport 2005-08-31 17:19:41.000000000 -0700 +++ devel-akpm/fs/9p/trans_fd.c 2005-08-31 17:19:41.000000000 -0700 @@ -56,6 +56,9 @@ static int v9fs_fd_recv(struct v9fs_tran { struct v9fs_trans_fd *ts = trans ? trans->priv : NULL; + if (!trans || trans->status != Connected || !ts) + return -EIO; + return kernel_read(ts->in_file, ts->in_file->f_pos, v, len); } @@ -73,6 +76,9 @@ static int v9fs_fd_send(struct v9fs_tran mm_segment_t oldfs = get_fs(); int ret = 0; + if (!trans || trans->status != Connected || !ts) + return -EIO; + set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos); @@ -95,6 +101,11 @@ v9fs_fd_init(struct v9fs_session_info *v struct v9fs_trans_fd *ts = NULL; struct v9fs_transport *trans = v9ses->transport; + if((v9ses->wfdno == ~0) || (v9ses->rfdno == ~0)) { + printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); + return -ENOPROTOOPT; + } + sema_init(&trans->writelock, 1); sema_init(&trans->readlock, 1); @@ -103,11 +114,21 @@ v9fs_fd_init(struct v9fs_session_info *v if (!ts) return -ENOMEM; - trans->priv = ts; - ts->in_file = fget( v9ses->rfdno ); ts->out_file = fget( v9ses->wfdno ); + if (!ts->in_file || !ts->out_file) { + if (ts->in_file) + fput(ts->in_file); + + if (ts->out_file) + fput(ts->out_file); + + kfree(ts); + return -EIO; + } + + trans->priv = ts; trans->status = Connected; return 0; @@ -122,7 +143,22 @@ v9fs_fd_init(struct v9fs_session_info *v static void v9fs_fd_close(struct v9fs_transport *trans) { - struct v9fs_trans_fd *ts = trans ? trans->priv : NULL; + struct v9fs_trans_fd *ts; + + if (!trans) + return; + + trans->status = Disconnected; + ts = trans->priv; + + if (!ts) + return; + + if (ts->in_file) + fput(ts->in_file); + + if (ts->out_file) + fput(ts->out_file); kfree(ts); } diff -puN fs/9p/v9fs.c~v9fs-transport-modules-cleanup-fd-transport fs/9p/v9fs.c --- devel/fs/9p/v9fs.c~v9fs-transport-modules-cleanup-fd-transport 2005-08-31 17:19:41.000000000 -0700 +++ devel-akpm/fs/9p/v9fs.c 2005-08-31 17:19:41.000000000 -0700 @@ -296,11 +296,6 @@ v9fs_session_init(struct v9fs_session_in case PROTO_FD: trans_proto = &v9fs_trans_fd; *v9ses->remotename = 0; - if((v9ses->wfdno == ~0) || (v9ses->rfdno == ~0)) { - printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); - retval = -ENOPROTOOPT; - goto SessCleanUp; - } break; default: printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); _