diff options
Diffstat (limited to 'fs/9p')
-rw-r--r-- | fs/9p/9p.h | 9 | ||||
-rw-r--r-- | fs/9p/Makefile | 10 | ||||
-rw-r--r-- | fs/9p/conv.c | 13 | ||||
-rw-r--r-- | fs/9p/conv.h | 8 | ||||
-rw-r--r-- | fs/9p/debug.h | 6 | ||||
-rw-r--r-- | fs/9p/error.c | 5 | ||||
-rw-r--r-- | fs/9p/error.h | 5 | ||||
-rw-r--r-- | fs/9p/fcall.c (renamed from fs/9p/9p.c) | 20 | ||||
-rw-r--r-- | fs/9p/fcprint.c | 346 | ||||
-rw-r--r-- | fs/9p/fid.c | 5 | ||||
-rw-r--r-- | fs/9p/fid.h | 5 | ||||
-rw-r--r-- | fs/9p/mux.c | 32 | ||||
-rw-r--r-- | fs/9p/mux.h | 5 | ||||
-rw-r--r-- | fs/9p/trans_fd.c | 301 | ||||
-rw-r--r-- | fs/9p/trans_sock.c | 334 | ||||
-rw-r--r-- | fs/9p/transport.h | 5 | ||||
-rw-r--r-- | fs/9p/v9fs.c | 15 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 8 | ||||
-rw-r--r-- | fs/9p/v9fs_vfs.h | 5 | ||||
-rw-r--r-- | fs/9p/vfs_addr.c | 5 | ||||
-rw-r--r-- | fs/9p/vfs_dentry.c | 7 | ||||
-rw-r--r-- | fs/9p/vfs_dir.c | 5 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 37 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 56 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 7 |
25 files changed, 676 insertions, 578 deletions
diff --git a/fs/9p/9p.h b/fs/9p/9p.h index 95d72aec1c1a..94e2f92ab2e8 100644 --- a/fs/9p/9p.h +++ b/fs/9p/9p.h @@ -8,9 +8,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -235,6 +234,7 @@ struct Tcreate { struct v9fs_str name; u32 perm; u8 mode; + struct v9fs_str extension; }; struct Rcreate { @@ -364,7 +364,7 @@ int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **rcall); int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, - u32 perm, u8 mode, struct v9fs_fcall **rcall); + u32 perm, u8 mode, char *extension, struct v9fs_fcall **rcall); int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count, struct v9fs_fcall **rcall); @@ -372,3 +372,4 @@ int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count, const char __user * data, struct v9fs_fcall **rcall); +int v9fs_printfcall(char *, int, struct v9fs_fcall *, int); diff --git a/fs/9p/Makefile b/fs/9p/Makefile index 2f4ce43f7b6c..87897f84dfb6 100644 --- a/fs/9p/Makefile +++ b/fs/9p/Makefile @@ -1,10 +1,9 @@ -obj-$(CONFIG_9P_FS) := 9p2000.o +obj-$(CONFIG_9P_FS) := 9p.o -9p2000-objs := \ +9p-objs := \ trans_fd.o \ - trans_sock.o \ mux.o \ - 9p.o \ + fcall.o \ conv.o \ vfs_super.o \ vfs_inode.o \ @@ -14,5 +13,6 @@ obj-$(CONFIG_9P_FS) := 9p2000.o vfs_dentry.o \ error.o \ v9fs.o \ - fid.o + fid.o \ + fcprint.o diff --git a/fs/9p/conv.c b/fs/9p/conv.c index bba817142465..a767e05b60bf 100644 --- a/fs/9p/conv.c +++ b/fs/9p/conv.c @@ -8,9 +8,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -666,7 +665,8 @@ struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode) return fc; } -struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) +struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, + char *extension, int extended) { int size; struct v9fs_fcall *fc; @@ -674,6 +674,9 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) struct cbuf *bufp = &buffer; size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ + if (extended && extension!=NULL) + size += 2 + strlen(extension); /* extension[s] */ + fc = v9fs_create_common(bufp, size, TCREATE); if (IS_ERR(fc)) goto error; @@ -682,6 +685,8 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) v9fs_put_str(bufp, name, &fc->params.tcreate.name); v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); + if (extended) + v9fs_put_str(bufp, extension, &fc->params.tcreate.extension); if (buf_check_overflow(bufp)) { kfree(fc); diff --git a/fs/9p/conv.h b/fs/9p/conv.h index f5896628dae4..dd5b6b1b610f 100644 --- a/fs/9p/conv.h +++ b/fs/9p/conv.h @@ -8,9 +8,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -39,7 +38,8 @@ 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_tcreate(u32 fid, char *name, u32 perm, u8 mode, + char *extension, int extended); 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); diff --git a/fs/9p/debug.h b/fs/9p/debug.h index fe551032788b..4228c0bb3c32 100644 --- a/fs/9p/debug.h +++ b/fs/9p/debug.h @@ -5,9 +5,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -30,6 +29,7 @@ #define DEBUG_MUX (1<<5) #define DEBUG_TRANS (1<<6) #define DEBUG_SLABS (1<<7) +#define DEBUG_FCALL (1<<8) #define DEBUG_DUMP_PKT 0 diff --git a/fs/9p/error.c b/fs/9p/error.c index e4b6f8f38b6f..981fe8ecd780 100644 --- a/fs/9p/error.c +++ b/fs/9p/error.c @@ -11,9 +11,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/error.h b/fs/9p/error.h index a9794e85fe51..5f3ca522b316 100644 --- a/fs/9p/error.h +++ b/fs/9p/error.h @@ -12,9 +12,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/9p.c b/fs/9p/fcall.c index c148e6ba07e5..71742ba150c4 100644 --- a/fs/9p/9p.c +++ b/fs/9p/fcall.c @@ -1,5 +1,5 @@ /* - * linux/fs/9p/9p.c + * linux/fs/9p/fcall.c * * This file contains functions to perform synchronous 9P calls * @@ -8,9 +8,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -152,10 +151,9 @@ v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid) /** * v9fs_v9fs_t_flush - flush a pending transaction * @v9ses: 9P2000 session information - * @tag: tid to release + * @tag: tag to release * */ - int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) { int ret; @@ -172,7 +170,7 @@ int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) return ret; } -#endif /* 0 */ +#endif /** * v9fs_t_stat - read a file's meta-data @@ -334,8 +332,8 @@ v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, */ int -v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, - u32 perm, u8 mode, struct v9fs_fcall **rcp) +v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, u32 perm, + u8 mode, char *extension, struct v9fs_fcall **rcp) { int ret; struct v9fs_fcall *tc; @@ -343,7 +341,9 @@ v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", fid, name, perm, mode); - tc = v9fs_create_tcreate(fid, name, perm, mode); + tc = v9fs_create_tcreate(fid, name, perm, mode, extension, + v9ses->extended); + if (!IS_ERR(tc)) { ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); kfree(tc); diff --git a/fs/9p/fcprint.c b/fs/9p/fcprint.c new file mode 100644 index 000000000000..583e827baebd --- /dev/null +++ b/fs/9p/fcprint.c @@ -0,0 +1,346 @@ +/* + * linux/fs/9p/fcprint.c + * + * Print 9P call. + * + * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/idr.h> + +#include "debug.h" +#include "v9fs.h" +#include "9p.h" +#include "mux.h" + +static int +v9fs_printqid(char *buf, int buflen, struct v9fs_qid *q) +{ + int n; + char b[10]; + + n = 0; + if (q->type & V9FS_QTDIR) + b[n++] = 'd'; + if (q->type & V9FS_QTAPPEND) + b[n++] = 'a'; + if (q->type & V9FS_QTAUTH) + b[n++] = 'A'; + if (q->type & V9FS_QTEXCL) + b[n++] = 'l'; + if (q->type & V9FS_QTTMP) + b[n++] = 't'; + if (q->type & V9FS_QTSYMLINK) + b[n++] = 'L'; + b[n] = '\0'; + + return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path, + q->version, b); +} + +static int +v9fs_printperm(char *buf, int buflen, int perm) +{ + int n; + char b[15]; + + n = 0; + if (perm & V9FS_DMDIR) + b[n++] = 'd'; + if (perm & V9FS_DMAPPEND) + b[n++] = 'a'; + if (perm & V9FS_DMAUTH) + b[n++] = 'A'; + if (perm & V9FS_DMEXCL) + b[n++] = 'l'; + if (perm & V9FS_DMTMP) + b[n++] = 't'; + if (perm & V9FS_DMDEVICE) + b[n++] = 'D'; + if (perm & V9FS_DMSOCKET) + b[n++] = 'S'; + if (perm & V9FS_DMNAMEDPIPE) + b[n++] = 'P'; + if (perm & V9FS_DMSYMLINK) + b[n++] = 'L'; + b[n] = '\0'; + + return scnprintf(buf, buflen, "%s%03o", b, perm&077); +} + +static int +v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) +{ + int n; + + n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len, + st->name.str, st->uid.len, st->uid.str); + if (extended) + n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid); + + n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str); + if (extended) + n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid); + + n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str); + if (extended) + n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); + + n += scnprintf(buf+n, buflen-n, " q "); + n += v9fs_printqid(buf+n, buflen-n, &st->qid); + n += scnprintf(buf+n, buflen-n, " m "); + n += v9fs_printperm(buf+n, buflen-n, st->mode); + n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", + st->atime, st->mtime, (long long int) st->length); + + if (extended) + n += scnprintf(buf+n, buflen-n, " ext '%.*s'", + st->extension.len, st->extension.str); + + return n; +} + +static int +v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) +{ + int i, n; + + i = n = 0; + while (i < datalen) { + n += scnprintf(buf + n, buflen - n, "%02x", data[i]); + if (i%4 == 3) + n += scnprintf(buf + n, buflen - n, " "); + if (i%32 == 31) + n += scnprintf(buf + n, buflen - n, "\n"); + + i++; + } + n += scnprintf(buf + n, buflen - n, "\n"); + + return n; +} + +static int +v9fs_printdata(char *buf, int buflen, u8 *data, int datalen) +{ + return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16); +} + +int +v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) +{ + int i, ret, type, tag; + + if (!fc) + return scnprintf(buf, buflen, "<NULL>"); + + type = fc->id; + tag = fc->tag; + + ret = 0; + switch (type) { + case TVERSION: + ret += scnprintf(buf+ret, buflen-ret, + "Tversion tag %u msize %u version '%.*s'", tag, + fc->params.tversion.msize, fc->params.tversion.version.len, + fc->params.tversion.version.str); + break; + + case RVERSION: + ret += scnprintf(buf+ret, buflen-ret, + "Rversion tag %u msize %u version '%.*s'", tag, + fc->params.rversion.msize, fc->params.rversion.version.len, + fc->params.rversion.version.str); + break; + + case TAUTH: + ret += scnprintf(buf+ret, buflen-ret, + "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, + fc->params.tauth.afid, fc->params.tauth.uname.len, + fc->params.tauth.uname.str, fc->params.tauth.aname.len, + fc->params.tauth.aname.str); + break; + + case RAUTH: + ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); + v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); + break; + + case TATTACH: + ret += scnprintf(buf+ret, buflen-ret, + "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", + tag, fc->params.tattach.fid, fc->params.tattach.afid, + fc->params.tattach.uname.len, fc->params.tattach.uname.str, + fc->params.tattach.aname.len, fc->params.tattach.aname.str); + break; + + case RATTACH: + ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); + v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); + break; + + case RERROR: + ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", + tag, fc->params.rerror.error.len, + fc->params.rerror.error.str); + if (extended) + ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", + fc->params.rerror.errno); + break; + + case TFLUSH: + ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", + tag, fc->params.tflush.oldtag); + break; + + case RFLUSH: + ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); + break; + + case TWALK: + ret += scnprintf(buf+ret, buflen-ret, + "Twalk tag %u fid %d newfid %d nwname %d", tag, + fc->params.twalk.fid, fc->params.twalk.newfid, + fc->params.twalk.nwname); + for(i = 0; i < fc->params.twalk.nwname; i++) + ret += scnprintf(buf+ret, buflen-ret," '%.*s'", + fc->params.twalk.wnames[i].len, + fc->params.twalk.wnames[i].str); + break; + + case RWALK: + ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", + tag, fc->params.rwalk.nwqid); + for(i = 0; i < fc->params.rwalk.nwqid; i++) + ret += v9fs_printqid(buf+ret, buflen-ret, + &fc->params.rwalk.wqids[i]); + break; + + case TOPEN: + ret += scnprintf(buf+ret, buflen-ret, + "Topen tag %u fid %d mode %d", tag, + fc->params.topen.fid, fc->params.topen.mode); + break; + + case ROPEN: + ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); + ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); + ret += scnprintf(buf+ret, buflen-ret," iounit %d", + fc->params.ropen.iounit); + break; + + case TCREATE: + ret += scnprintf(buf+ret, buflen-ret, + "Tcreate tag %u fid %d name '%.*s' perm ", tag, + fc->params.tcreate.fid, fc->params.tcreate.name.len, + fc->params.tcreate.name.str); + + ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm); + ret += scnprintf(buf+ret, buflen-ret, " mode %d", + fc->params.tcreate.mode); + break; + + case RCREATE: + ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); + ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid); + ret += scnprintf(buf+ret, buflen-ret, " iounit %d", + fc->params.rcreate.iounit); + break; + + case TREAD: + ret += scnprintf(buf+ret, buflen-ret, + "Tread tag %u fid %d offset %lld count %u", tag, + fc->params.tread.fid, + (long long int) fc->params.tread.offset, + fc->params.tread.count); + break; + + case RREAD: + ret += scnprintf(buf+ret, buflen-ret, + "Rread tag %u count %u data ", tag, + fc->params.rread.count); + ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, + fc->params.rread.count); + break; + + case TWRITE: + ret += scnprintf(buf+ret, buflen-ret, + "Twrite tag %u fid %d offset %lld count %u data ", + tag, fc->params.twrite.fid, + (long long int) fc->params.twrite.offset, + fc->params.twrite.count); + ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, + fc->params.twrite.count); + break; + + case RWRITE: + ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", + tag, fc->params.rwrite.count); + break; + + case TCLUNK: + ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", + tag, fc->params.tclunk.fid); + break; + + case RCLUNK: + ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); + break; + + case TREMOVE: + ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", + tag, fc->params.tremove.fid); + break; + + case RREMOVE: + ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); + break; + + case TSTAT: + ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", + tag, fc->params.tstat.fid); + break; + + case RSTAT: + ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); + ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, + extended); + break; + + case TWSTAT: + ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", + tag, fc->params.twstat.fid); + ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, + extended); + break; + + case RWSTAT: + ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); + break; + + default: + ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type); + break; + } + + return ret; +} diff --git a/fs/9p/fid.c b/fs/9p/fid.c index c4d13bf904d2..b7608af07ce8 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -4,9 +4,8 @@ * Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 1fc2dd08d75a..aa974d6875c3 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -4,9 +4,8 @@ * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/mux.c b/fs/9p/mux.c index e2ae60adda99..3e5b124a7212 100644 --- a/fs/9p/mux.c +++ b/fs/9p/mux.c @@ -7,9 +7,8 @@ * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -70,7 +69,7 @@ struct v9fs_mux_data { int msize; unsigned char *extended; struct v9fs_transport *trans; - struct v9fs_idpool tidpool; + struct v9fs_idpool tagpool; int err; wait_queue_head_t equeue; struct list_head req_list; @@ -280,8 +279,8 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, m->msize = msize; m->extended = extended; m->trans = trans; - idr_init(&m->tidpool.pool); - init_MUTEX(&m->tidpool.lock); + idr_init(&m->tagpool.pool); + init_MUTEX(&m->tagpool.lock); m->err = 0; init_waitqueue_head(&m->equeue); INIT_LIST_HEAD(&m->req_list); @@ -635,6 +634,14 @@ static void v9fs_read_work(void *a) goto error; } + 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; if (m->rpos > n) { @@ -740,6 +747,13 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, 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; req->rcall = NULL; @@ -965,7 +979,7 @@ static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m) { int tag; - tag = v9fs_get_idpool(&m->tidpool); + tag = v9fs_get_idpool(&m->tagpool); if (tag < 0) return V9FS_NOTAG; else @@ -974,6 +988,6 @@ static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m) 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); + if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool)) + v9fs_put_idpool(tag, &m->tagpool); } diff --git a/fs/9p/mux.h b/fs/9p/mux.h index 17144fdfa11b..e90bfd32ea42 100644 --- a/fs/9p/mux.h +++ b/fs/9p/mux.h @@ -7,9 +7,8 @@ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c index 5b2ce21b10fa..94e0a7fd9fc2 100644 --- a/fs/9p/trans_fd.c +++ b/fs/9p/trans_fd.c @@ -1,15 +1,16 @@ /* * linux/fs/9p/trans_fd.c * - * File Descriptor Transport Layer + * Fd transport layer. Includes deprecated socket layer. * - * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> - * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> + * Copyright (C) 2006 by Russ Cox <rsc@swtch.com> + * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> + * Copyright (C) 2004-2005 by Eric Van Hensbergen <ericvh@gmail.com> + * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -25,6 +26,7 @@ */ #include <linux/config.h> +#include <linux/in.h> #include <linux/module.h> #include <linux/net.h> #include <linux/ipv6.h> @@ -40,89 +42,119 @@ #include "v9fs.h" #include "transport.h" +#define V9FS_PORT 564 + struct v9fs_trans_fd { - struct file *in_file; - struct file *out_file; + struct file *rd; + struct file *wr; }; /** - * v9fs_fd_recv - receive from a socket + * v9fs_fd_read- read from a fd * @v9ses: session information * @v: buffer to receive data into * @len: size of receive buffer * */ - -static int v9fs_fd_recv(struct v9fs_transport *trans, void *v, int len) +static int v9fs_fd_read(struct v9fs_transport *trans, void *v, int len) { - struct v9fs_trans_fd *ts = trans ? trans->priv : NULL; + int ret; + struct v9fs_trans_fd *ts; - if (!trans || trans->status != Connected || !ts) - return -EIO; + if (!trans || trans->status == Disconnected || !(ts = trans->priv)) + return -EREMOTEIO; - return kernel_read(ts->in_file, ts->in_file->f_pos, v, len); + if (!(ts->rd->f_flags & O_NONBLOCK)) + dprintk(DEBUG_ERROR, "blocking read ...\n"); + + ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); + if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) + trans->status = Disconnected; + return ret; } /** - * v9fs_fd_send - send to a socket + * v9fs_fd_write - write to a socket * @v9ses: session information * @v: buffer to send data from * @len: size of send buffer * */ - -static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len) +static int v9fs_fd_write(struct v9fs_transport *trans, void *v, int len) { - struct v9fs_trans_fd *ts = trans ? trans->priv : NULL; - mm_segment_t oldfs = get_fs(); - int ret = 0; + int ret; + mm_segment_t oldfs; + struct v9fs_trans_fd *ts; - if (!trans || trans->status != Connected || !ts) - return -EIO; + if (!trans || trans->status == Disconnected || !(ts = trans->priv)) + return -EREMOTEIO; + + if (!(ts->wr->f_flags & O_NONBLOCK)) + dprintk(DEBUG_ERROR, "blocking write ...\n"); oldfs = get_fs(); 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); + ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); set_fs(oldfs); + if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) + trans->status = Disconnected; return ret; } -/** - * v9fs_fd_init - initialize file descriptor transport - * @v9ses: session information - * @addr: address of server to mount - * @data: mount options - * - */ - -static int -v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data) +static unsigned int +v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) { - struct v9fs_trans_fd *ts = NULL; - struct v9fs_transport *trans = v9ses->transport; + int ret, n; + struct v9fs_trans_fd *ts; + mm_segment_t oldfs; - if((v9ses->wfdno == ~0) || (v9ses->rfdno == ~0)) { - printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); - return -ENOPROTOOPT; - } + if (!trans || trans->status != Connected || !(ts = trans->priv)) + return -EREMOTEIO; - ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL); + if (!ts->rd->f_op || !ts->rd->f_op->poll) + return -EIO; - if (!ts) - return -ENOMEM; + if (!ts->wr->f_op || !ts->wr->f_op->poll) + return -EIO; - ts->in_file = fget( v9ses->rfdno ); - ts->out_file = fget( v9ses->wfdno ); + oldfs = get_fs(); + set_fs(get_ds()); - if (!ts->in_file || !ts->out_file) { - if (ts->in_file) - fput(ts->in_file); + ret = ts->rd->f_op->poll(ts->rd, pt); + if (ret < 0) + goto end; - if (ts->out_file) - fput(ts->out_file); + if (ts->rd != ts->wr) { + n = ts->wr->f_op->poll(ts->wr, pt); + if (n < 0) { + ret = n; + goto end; + } + ret = (ret & ~POLLOUT) | (n & ~POLLIN); + } + end: + set_fs(oldfs); + return ret; +} + +static int v9fs_fd_open(struct v9fs_session_info *v9ses, int rfd, int wfd) +{ + struct v9fs_transport *trans = v9ses->transport; + struct v9fs_trans_fd *ts = kmalloc(sizeof(struct v9fs_trans_fd), + GFP_KERNEL); + if (!ts) + return -ENOMEM; + + ts->rd = fget(rfd); + ts->wr = fget(wfd); + if (!ts->rd || !ts->wr) { + if (ts->rd) + fput(ts->rd); + if (ts->wr) + fput(ts->wr); kfree(ts); return -EIO; } @@ -133,84 +165,145 @@ v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data) return 0; } - -/** - * v9fs_fd_close - shutdown file descriptor - * @trans: private socket structure - * - */ - -static void v9fs_fd_close(struct v9fs_transport *trans) +static int v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, + char *data) { - struct v9fs_trans_fd *ts; - - if (!trans) - return; - - ts = xchg(&trans->priv, NULL); + if (v9ses->rfdno == ~0 || v9ses->wfdno == ~0) { + printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); + return -ENOPROTOOPT; + } - if (!ts) - return; + return v9fs_fd_open(v9ses, v9ses->rfdno, v9ses->wfdno); +} - trans->status = Disconnected; - if (ts->in_file) - fput(ts->in_file); +static int v9fs_socket_open(struct v9fs_session_info *v9ses, + struct socket *csocket) +{ + int fd, ret; + + csocket->sk->sk_allocation = GFP_NOIO; + if ((fd = sock_map_fd(csocket)) < 0) { + eprintk(KERN_ERR, "v9fs_socket_open: failed to map fd\n"); + ret = fd; + release_csocket: + sock_release(csocket); + return ret; + } - if (ts->out_file) - fput(ts->out_file); + 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; + } - kfree(ts); + ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= + O_NONBLOCK; + return 0; } -static unsigned int -v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) +static int v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, + char *data) { - int ret, n; - struct v9fs_trans_fd *ts; - mm_segment_t oldfs; + int ret; + struct socket *csocket = NULL; + struct sockaddr_in sin_server; + + sin_server.sin_family = AF_INET; + sin_server.sin_addr.s_addr = in_aton(addr); + 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; + } - if (!trans) - return -EIO; + ret = csocket->ops->connect(csocket, + (struct sockaddr *)&sin_server, + sizeof(struct sockaddr_in), 0); + if (ret < 0) { + eprintk(KERN_ERR, + "v9fs_trans_tcp: problem connecting socket to %s\n", + addr); + return ret; + } - ts = trans->priv; - if (trans->status != Connected || !ts) - return -EIO; + return v9fs_socket_open(v9ses, csocket); +} - oldfs = get_fs(); - set_fs(get_ds()); +static int +v9fs_unix_init(struct v9fs_session_info *v9ses, const char *addr, char *data) +{ + int ret; + struct socket *csocket; + struct sockaddr_un sun_server; + + if (strlen(addr) > UNIX_PATH_MAX) { + eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n", + addr); + return -ENAMETOOLONG; + } - if (!ts->in_file->f_op || !ts->in_file->f_op->poll) { - ret = -EIO; - goto end; + sun_server.sun_family = PF_UNIX; + 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, + "v9fs_trans_unix: problem connecting socket: %s: %d\n", + addr, ret); + return ret; } - ret = ts->in_file->f_op->poll(ts->in_file, pt); + return v9fs_socket_open(v9ses, csocket); +} - if (ts->out_file != ts->in_file) { - if (!ts->out_file->f_op || !ts->out_file->f_op->poll) { - ret = -EIO; - goto end; - } +/** + * v9fs_sock_close - shutdown socket + * @trans: private socket structure + * + */ +static void v9fs_fd_close(struct v9fs_transport *trans) +{ + struct v9fs_trans_fd *ts; - n = ts->out_file->f_op->poll(ts->out_file, pt); + if (!trans) + return; - ret &= ~POLLOUT; - n &= ~POLLIN; + ts = xchg(&trans->priv, NULL); - ret |= n; - } + if (!ts) + return; -end: - set_fs(oldfs); - return ret; + trans->status = Disconnected; + if (ts->rd) + fput(ts->rd); + if (ts->wr) + fput(ts->wr); + kfree(ts); } - struct v9fs_transport v9fs_trans_fd = { .init = v9fs_fd_init, - .write = v9fs_fd_send, - .read = v9fs_fd_recv, + .write = v9fs_fd_write, + .read = v9fs_fd_read, .close = v9fs_fd_close, .poll = v9fs_fd_poll, }; +struct v9fs_transport v9fs_trans_tcp = { + .init = v9fs_tcp_init, + .write = v9fs_fd_write, + .read = v9fs_fd_read, + .close = v9fs_fd_close, + .poll = v9fs_fd_poll, +}; + +struct v9fs_transport v9fs_trans_unix = { + .init = v9fs_unix_init, + .write = v9fs_fd_write, + .read = v9fs_fd_read, + .close = v9fs_fd_close, + .poll = v9fs_fd_poll, +}; diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c deleted file mode 100644 index 44e830697acb..000000000000 --- a/fs/9p/trans_sock.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * linux/fs/9p/trans_socket.c - * - * Socket Transport Layer - * - * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> - * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> - * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> - * Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to: - * Free Software Foundation - * 51 Franklin Street, Fifth Floor - * Boston, MA 02111-1301 USA - * - */ - -#include <linux/config.h> -#include <linux/in.h> -#include <linux/module.h> -#include <linux/net.h> -#include <linux/ipv6.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/un.h> -#include <asm/uaccess.h> -#include <linux/inet.h> -#include <linux/idr.h> -#include <linux/file.h> - -#include "debug.h" -#include "v9fs.h" -#include "transport.h" - -#define V9FS_PORT 564 - -struct v9fs_trans_sock { - struct socket *s; - struct file *filp; -}; - -/** - * v9fs_sock_recv - receive from a socket - * @v9ses: session information - * @v: buffer to receive data into - * @len: size of receive buffer - * - */ - -static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len) -{ - int ret; - struct v9fs_trans_sock *ts; - - if (!trans || trans->status == Disconnected) { - dprintk(DEBUG_ERROR, "disconnected ...\n"); - return -EREMOTEIO; - } - - ts = trans->priv; - - if (!(ts->filp->f_flags & O_NONBLOCK)) - dprintk(DEBUG_ERROR, "blocking read ...\n"); - - ret = kernel_read(ts->filp, ts->filp->f_pos, v, len); - if (ret <= 0) { - if (ret != -ERESTARTSYS && ret != -EAGAIN) - trans->status = Disconnected; - } - - return ret; -} - -/** - * v9fs_sock_send - send to a socket - * @v9ses: session information - * @v: buffer to send data from - * @len: size of send buffer - * - */ - -static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len) -{ - int ret; - mm_segment_t oldfs; - struct v9fs_trans_sock *ts; - - if (!trans || trans->status == Disconnected) { - dprintk(DEBUG_ERROR, "disconnected ...\n"); - return -EREMOTEIO; - } - - ts = trans->priv; - if (!ts) { - dprintk(DEBUG_ERROR, "no transport ...\n"); - return -EREMOTEIO; - } - - if (!(ts->filp->f_flags & O_NONBLOCK)) - dprintk(DEBUG_ERROR, "blocking write ...\n"); - - oldfs = get_fs(); - set_fs(get_ds()); - ret = vfs_write(ts->filp, (void __user *)v, len, &ts->filp->f_pos); - set_fs(oldfs); - - if (ret < 0) { - if (ret != -ERESTARTSYS) - trans->status = Disconnected; - } - - return ret; -} - -static unsigned int v9fs_sock_poll(struct v9fs_transport *trans, - struct poll_table_struct *pt) { - - int ret; - struct v9fs_trans_sock *ts; - mm_segment_t oldfs; - - if (!trans) { - dprintk(DEBUG_ERROR, "no transport\n"); - return -EIO; - } - - ts = trans->priv; - if (trans->status != Connected || !ts) { - dprintk(DEBUG_ERROR, "transport disconnected: %d\n", trans->status); - return -EIO; - } - - oldfs = get_fs(); - set_fs(get_ds()); - - if (!ts->filp->f_op || !ts->filp->f_op->poll) { - dprintk(DEBUG_ERROR, "no poll operation\n"); - ret = -EIO; - goto end; - } - - ret = ts->filp->f_op->poll(ts->filp, pt); - -end: - set_fs(oldfs); - return ret; -} - - -/** - * v9fs_tcp_init - initialize TCP socket - * @v9ses: session information - * @addr: address of server to mount - * @data: mount options - * - */ - -static int -v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data) -{ - struct socket *csocket = NULL; - struct sockaddr_in sin_server; - int rc = 0; - struct v9fs_trans_sock *ts = NULL; - struct v9fs_transport *trans = v9ses->transport; - int fd; - - trans->status = Disconnected; - - ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL); - - if (!ts) - return -ENOMEM; - - trans->priv = ts; - ts->s = NULL; - ts->filp = NULL; - - if (!addr) - return -EINVAL; - - dprintk(DEBUG_TRANS, "Connecting to %s\n", addr); - - sin_server.sin_family = AF_INET; - sin_server.sin_addr.s_addr = in_aton(addr); - sin_server.sin_port = htons(v9ses->port); - sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); - rc = csocket->ops->connect(csocket, - (struct sockaddr *)&sin_server, - sizeof(struct sockaddr_in), 0); - if (rc < 0) { - eprintk(KERN_ERR, - "v9fs_trans_tcp: problem connecting socket to %s\n", - addr); - return rc; - } - csocket->sk->sk_allocation = GFP_NOIO; - - fd = sock_map_fd(csocket); - if (fd < 0) { - sock_release(csocket); - kfree(ts); - trans->priv = NULL; - return fd; - } - - ts->s = csocket; - ts->filp = fget(fd); - ts->filp->f_flags |= O_NONBLOCK; - trans->status = Connected; - - return 0; -} - -/** - * v9fs_unix_init - initialize UNIX domain socket - * @v9ses: session information - * @dev_name: path to named pipe - * @data: mount options - * - */ - -static int -v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name, - char *data) -{ - int rc, fd; - struct socket *csocket; - struct sockaddr_un sun_server; - struct v9fs_transport *trans; - struct v9fs_trans_sock *ts; - - rc = 0; - csocket = NULL; - trans = v9ses->transport; - - trans->status = Disconnected; - - if (strlen(dev_name) > UNIX_PATH_MAX) { - eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n", - dev_name); - return -ENOMEM; - } - - ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL); - if (!ts) - return -ENOMEM; - - trans->priv = ts; - ts->s = NULL; - ts->filp = NULL; - - sun_server.sun_family = PF_UNIX; - strcpy(sun_server.sun_path, dev_name); - sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); - rc = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, - sizeof(struct sockaddr_un) - 1, 0); /* -1 *is* important */ - if (rc < 0) { - eprintk(KERN_ERR, - "v9fs_trans_unix: problem connecting socket: %s: %d\n", - dev_name, rc); - return rc; - } - csocket->sk->sk_allocation = GFP_NOIO; - - fd = sock_map_fd(csocket); - if (fd < 0) { - sock_release(csocket); - kfree(ts); - trans->priv = NULL; - return fd; - } - - ts->s = csocket; - ts->filp = fget(fd); - ts->filp->f_flags |= O_NONBLOCK; - trans->status = Connected; - - return 0; -} - -/** - * v9fs_sock_close - shutdown socket - * @trans: private socket structure - * - */ - -static void v9fs_sock_close(struct v9fs_transport *trans) -{ - struct v9fs_trans_sock *ts; - - if (!trans) - return; - - ts = trans->priv; - - if ((ts) && (ts->filp)) { - fput(ts->filp); - ts->filp = NULL; - ts->s = NULL; - trans->status = Disconnected; - } - - kfree(ts); - - trans->priv = NULL; -} - -struct v9fs_transport v9fs_trans_tcp = { - .init = v9fs_tcp_init, - .write = v9fs_sock_send, - .read = v9fs_sock_recv, - .close = v9fs_sock_close, - .poll = v9fs_sock_poll, -}; - -struct v9fs_transport v9fs_trans_unix = { - .init = v9fs_unix_init, - .write = v9fs_sock_send, - .read = v9fs_sock_recv, - .close = v9fs_sock_close, - .poll = v9fs_sock_poll, -}; diff --git a/fs/9p/transport.h b/fs/9p/transport.h index 91fcdb94b361..b38a4b8a41ce 100644 --- a/fs/9p/transport.h +++ b/fs/9p/transport.h @@ -7,9 +7,8 @@ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 61352491ba36..d37416eb5791 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -7,9 +7,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -51,7 +50,7 @@ enum { Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug, Opt_rfdno, Opt_wfdno, /* String options */ - Opt_name, Opt_remotename, + Opt_uname, Opt_remotename, /* Options that take no arguments */ Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, /* Error token */ @@ -67,7 +66,7 @@ static match_table_t tokens = { {Opt_rfdno, "rfdno=%u"}, {Opt_wfdno, "wfdno=%u"}, {Opt_debug, "debug=%x"}, - {Opt_name, "name=%s"}, + {Opt_uname, "uname=%s"}, {Opt_remotename, "aname=%s"}, {Opt_unix, "proto=unix"}, {Opt_tcp, "proto=tcp"}, @@ -116,7 +115,7 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) if (!*p) continue; token = match_token(p, tokens, args); - if (token < Opt_name) { + if (token < Opt_uname) { if ((ret = match_int(&args[0], &option)) < 0) { dprintk(DEBUG_ERROR, "integer field, but no integer?\n"); @@ -158,7 +157,7 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) case Opt_fd: v9ses->proto = PROTO_FD; break; - case Opt_name: + case Opt_uname: match_strcpy(v9ses->name, &args[0]); break; case Opt_remotename: @@ -289,7 +288,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses, /* set global debug level */ v9fs_debug_level = v9ses->debug; - /* id pools that are session-dependent: FIDs and TIDs */ + /* id pools that are session-dependent: fids and tags */ idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index f337da7a0eec..c134d104cb28 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -5,9 +5,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -91,6 +90,3 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses); #define V9FS_DEFUSER "nobody" #define V9FS_DEFANAME "" -/* inital pool sizes for fids and tags */ -#define V9FS_START_FIDS 8192 -#define V9FS_START_TIDS 256 diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index a759278acaae..43c9f7de0314 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h @@ -5,9 +5,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 8100fb5171b7..efda46fb64d9 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -7,9 +7,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 12c9cc926b71..062daa6000ab 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -7,9 +7,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -51,7 +50,7 @@ * */ -int v9fs_dentry_delete(struct dentry *dentry) +static int v9fs_dentry_delete(struct dentry *dentry) { dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); return 1; diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index cd5eeb032d64..766f11f1215c 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -7,9 +7,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index de3a129698da..59e744163407 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -7,9 +7,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -69,29 +68,30 @@ int v9fs_file_open(struct inode *inode, struct file *file) fid = v9fs_get_idpool(&v9ses->fidpool); if (fid < 0) { - eprintk(KERN_WARNING, "newfid fails!\n"); - return -ENOSPC; - } + 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"); + 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 */ + /* 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; + goto clunk_fid; + } + + vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); + if (vfid == NULL) { + dprintk(DEBUG_ERROR, "out of memory\n"); + err = -ENOMEM; + goto clunk_fid; } file->private_data = vfid; @@ -106,15 +106,12 @@ int v9fs_file_open(struct inode *inode, struct file *file) 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); + kfree(fcall); return err; } diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 651a9e14d9a9..133db366d306 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -7,9 +7,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -255,8 +254,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) } 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) +v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, + u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) { u32 fid; int err; @@ -271,14 +270,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); if (err < 0) { PRINT_FCALL_ERROR("clone error", fcall); - goto error; + goto put_fid; } kfree(fcall); - err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); + err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall); if (err < 0) { PRINT_FCALL_ERROR("create fails", fcall); - goto error; + goto clunk_fid; } if (iounit) @@ -293,7 +292,11 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, kfree(fcall); return 0; -error: +clunk_fid: + v9fs_t_clunk(v9ses, fid); + fid = V9FS_NOFID; + +put_fid: if (fid >= 0) v9fs_put_idpool(fid, &v9ses->fidpool); @@ -348,7 +351,7 @@ error: return ERR_PTR(err); } -struct inode * +static struct inode * v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, struct super_block *sb) { @@ -474,7 +477,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, flags = O_RDWR; err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, - perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); + perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); if (err) goto error; @@ -550,7 +553,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) perm = unixmode2p9mode(v9ses, mode | S_IFDIR); err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, - perm, V9FS_OREAD, &fid, NULL, NULL); + perm, V9FS_OREAD, NULL, &fid, NULL, NULL); if (err) { dprintk(DEBUG_ERROR, "create error %d\n", err); @@ -1008,11 +1011,13 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) /* copy extension buffer into buffer */ if (fcall->params.rstat.stat.extension.len < buflen) - buflen = fcall->params.rstat.stat.extension.len; + buflen = fcall->params.rstat.stat.extension.len + 1; - memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); + memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); buffer[buflen-1] = 0; + dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len, + fcall->params.rstat.stat.extension.str, buffer); retval = buflen; FreeFcall: @@ -1072,7 +1077,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) if (!link) link = ERR_PTR(-ENOMEM); else { - len = v9fs_readlink(dentry, link, strlen(link)); + len = v9fs_readlink(dentry, link, PATH_MAX); if (len < 0) { __putname(link); @@ -1109,10 +1114,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, 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); @@ -1125,7 +1127,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, } err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, - perm, V9FS_OREAD, &fid, NULL, NULL); + perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); if (err) goto error; @@ -1148,23 +1150,11 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, goto error; } - /* issue a Twstat */ - 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); @@ -1224,7 +1214,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, } name = __getname(); - sprintf(name, "hardlink(%d)\n", oldfid->fid); + sprintf(name, "%d\n", oldfid->fid); retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); __putname(name); @@ -1253,6 +1243,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) return -EINVAL; name = __getname(); + if (!name) + return -ENOMEM; /* build extension */ if (S_ISBLK(mode)) sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index d05318fa684e..b0a0ae509c00 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -8,9 +8,8 @@ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -262,7 +261,7 @@ static struct super_operations v9fs_super_ops = { }; struct file_system_type v9fs_fs_type = { - .name = "9P", + .name = "9p", .get_sb = v9fs_get_sb, .kill_sb = v9fs_kill_super, .owner = THIS_MODULE, |