aboutsummaryrefslogtreecommitdiff
path: root/fs/9p
diff options
context:
space:
mode:
authorLatchesar Ionkov <lucho@ionkov.net>2007-07-10 17:57:28 -0500
committerEric Van Hensbergen <ericvh@ericvh-desktop.austin.ibm.com>2007-07-14 15:13:40 -0500
commitbd238fb431f31989898423c8b6496bc8c4204a86 (patch)
treef85a536383cbf360125ecb0592f6c515e0ecf0ff /fs/9p
parent8d9107e8c50e1c4ff43c91c8841805833f3ecfb9 (diff)
9p: Reorganization of 9p file system code
This patchset moves non-filesystem interfaces of v9fs from fs/9p to net/9p. It moves the transport, packet marshalling and connection layers to net/9p leaving only the VFS related files in fs/9p. This work is being done in preparation for in-kernel 9p servers as well as alternate 9p clients (other than VFS). Signed-off-by: Latchesar Ionkov <lucho@ionkov.net> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/9p.h375
-rw-r--r--fs/9p/Makefile6
-rw-r--r--fs/9p/conv.c845
-rw-r--r--fs/9p/conv.h50
-rw-r--r--fs/9p/debug.h77
-rw-r--r--fs/9p/error.c93
-rw-r--r--fs/9p/error.h177
-rw-r--r--fs/9p/fcall.c427
-rw-r--r--fs/9p/fcprint.c345
-rw-r--r--fs/9p/fid.c168
-rw-r--r--fs/9p/fid.h43
-rw-r--r--fs/9p/mux.c1033
-rw-r--r--fs/9p/mux.h55
-rw-r--r--fs/9p/trans_fd.c308
-rw-r--r--fs/9p/transport.h45
-rw-r--r--fs/9p/v9fs.c288
-rw-r--r--fs/9p/v9fs.h32
-rw-r--r--fs/9p/v9fs_vfs.h6
-rw-r--r--fs/9p/vfs_addr.c57
-rw-r--r--fs/9p/vfs_dentry.c37
-rw-r--r--fs/9p/vfs_dir.c155
-rw-r--r--fs/9p/vfs_file.c160
-rw-r--r--fs/9p/vfs_inode.c753
-rw-r--r--fs/9p/vfs_super.c91
24 files changed, 552 insertions, 5074 deletions
diff --git a/fs/9p/9p.h b/fs/9p/9p.h
deleted file mode 100644
index 94e2f92ab2e..00000000000
--- a/fs/9p/9p.h
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * linux/fs/9p/9p.h
- *
- * 9P protocol definitions.
- *
- * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
- * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
- * 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 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
- *
- */
-
-/* Message Types */
-enum {
- TVERSION = 100,
- RVERSION,
- TAUTH = 102,
- RAUTH,
- TATTACH = 104,
- RATTACH,
- TERROR = 106,
- RERROR,
- TFLUSH = 108,
- RFLUSH,
- TWALK = 110,
- RWALK,
- TOPEN = 112,
- ROPEN,
- TCREATE = 114,
- RCREATE,
- TREAD = 116,
- RREAD,
- TWRITE = 118,
- RWRITE,
- TCLUNK = 120,
- RCLUNK,
- TREMOVE = 122,
- RREMOVE,
- TSTAT = 124,
- RSTAT,
- TWSTAT = 126,
- RWSTAT,
-};
-
-/* modes */
-enum {
- V9FS_OREAD = 0x00,
- V9FS_OWRITE = 0x01,
- V9FS_ORDWR = 0x02,
- V9FS_OEXEC = 0x03,
- V9FS_OEXCL = 0x04,
- V9FS_OTRUNC = 0x10,
- V9FS_OREXEC = 0x20,
- V9FS_ORCLOSE = 0x40,
- V9FS_OAPPEND = 0x80,
-};
-
-/* permissions */
-enum {
- V9FS_DMDIR = 0x80000000,
- V9FS_DMAPPEND = 0x40000000,
- V9FS_DMEXCL = 0x20000000,
- V9FS_DMMOUNT = 0x10000000,
- V9FS_DMAUTH = 0x08000000,
- V9FS_DMTMP = 0x04000000,
- V9FS_DMSYMLINK = 0x02000000,
- V9FS_DMLINK = 0x01000000,
- /* 9P2000.u extensions */
- V9FS_DMDEVICE = 0x00800000,
- V9FS_DMNAMEDPIPE = 0x00200000,
- V9FS_DMSOCKET = 0x00100000,
- V9FS_DMSETUID = 0x00080000,
- V9FS_DMSETGID = 0x00040000,
-};
-
-/* qid.types */
-enum {
- V9FS_QTDIR = 0x80,
- V9FS_QTAPPEND = 0x40,
- V9FS_QTEXCL = 0x20,
- V9FS_QTMOUNT = 0x10,
- V9FS_QTAUTH = 0x08,
- V9FS_QTTMP = 0x04,
- V9FS_QTSYMLINK = 0x02,
- V9FS_QTLINK = 0x01,
- V9FS_QTFILE = 0x00,
-};
-
-#define V9FS_NOTAG (u16)(~0)
-#define V9FS_NOFID (u32)(~0)
-#define V9FS_MAXWELEM 16
-
-/* ample room for Twrite/Rread header (iounit) */
-#define V9FS_IOHDRSZ 24
-
-struct v9fs_str {
- u16 len;
- char *str;
-};
-
-/* qids are the unique ID for a file (like an inode */
-struct v9fs_qid {
- u8 type;
- u32 version;
- u64 path;
-};
-
-/* Plan 9 file metadata (stat) structure */
-struct v9fs_stat {
- u16 size;
- u16 type;
- u32 dev;
- struct v9fs_qid qid;
- u32 mode;
- u32 atime;
- u32 mtime;
- u64 length;
- struct v9fs_str name;
- struct v9fs_str uid;
- struct v9fs_str gid;
- struct v9fs_str muid;
- struct v9fs_str extension; /* 9p2000.u extensions */
- u32 n_uid; /* 9p2000.u extensions */
- u32 n_gid; /* 9p2000.u extensions */
- u32 n_muid; /* 9p2000.u extensions */
-};
-
-/* file metadata (stat) structure used to create Twstat message
- The is similar to v9fs_stat, but the strings don't point to
- the same memory block and should be freed separately
-*/
-struct v9fs_wstat {
- u16 size;
- u16 type;
- u32 dev;
- struct v9fs_qid qid;
- u32 mode;
- u32 atime;
- u32 mtime;
- u64 length;
- char *name;
- char *uid;
- char *gid;
- char *muid;
- char *extension; /* 9p2000.u extensions */
- u32 n_uid; /* 9p2000.u extensions */
- u32 n_gid; /* 9p2000.u extensions */
- u32 n_muid; /* 9p2000.u extensions */
-};
-
-/* Structures for Protocol Operations */
-
-struct Tversion {
- u32 msize;
- struct v9fs_str version;
-};
-
-struct Rversion {
- u32 msize;
- struct v9fs_str version;
-};
-
-struct Tauth {
- u32 afid;
- struct v9fs_str uname;
- struct v9fs_str aname;
-};
-
-struct Rauth {
- struct v9fs_qid qid;
-};
-
-struct Rerror {
- struct v9fs_str error;
- u32 errno; /* 9p2000.u extension */
-};
-
-struct Tflush {
- u16 oldtag;
-};
-
-struct Rflush {
-};
-
-struct Tattach {
- u32 fid;
- u32 afid;
- struct v9fs_str uname;
- struct v9fs_str aname;
-};
-
-struct Rattach {
- struct v9fs_qid qid;
-};
-
-struct Twalk {
- u32 fid;
- u32 newfid;
- u16 nwname;
- struct v9fs_str wnames[16];
-};
-
-struct Rwalk {
- u16 nwqid;
- struct v9fs_qid wqids[16];
-};
-
-struct Topen {
- u32 fid;
- u8 mode;
-};
-
-struct Ropen {
- struct v9fs_qid qid;
- u32 iounit;
-};
-
-struct Tcreate {
- u32 fid;
- struct v9fs_str name;
- u32 perm;
- u8 mode;
- struct v9fs_str extension;
-};
-
-struct Rcreate {
- struct v9fs_qid qid;
- u32 iounit;
-};
-
-struct Tread {
- u32 fid;
- u64 offset;
- u32 count;
-};
-
-struct Rread {
- u32 count;
- u8 *data;
-};
-
-struct Twrite {
- u32 fid;
- u64 offset;
- u32 count;
- u8 *data;
-};
-
-struct Rwrite {
- u32 count;
-};
-
-struct Tclunk {
- u32 fid;
-};
-
-struct Rclunk {
-};
-
-struct Tremove {
- u32 fid;
-};
-
-struct Rremove {
-};
-
-struct Tstat {
- u32 fid;
-};
-
-struct Rstat {
- struct v9fs_stat stat;
-};
-
-struct Twstat {
- u32 fid;
- struct v9fs_stat stat;
-};
-
-struct Rwstat {
-};
-
-/*
- * fcall is the primary packet structure
- *
- */
-
-struct v9fs_fcall {
- u32 size;
- u8 id;
- u16 tag;
- void *sdata;
-
- union {
- struct Tversion tversion;
- struct Rversion rversion;
- struct Tauth tauth;
- struct Rauth rauth;
- struct Rerror rerror;
- struct Tflush tflush;
- struct Rflush rflush;
- struct Tattach tattach;
- struct Rattach rattach;
- struct Twalk twalk;
- struct Rwalk rwalk;
- struct Topen topen;
- struct Ropen ropen;
- struct Tcreate tcreate;
- struct Rcreate rcreate;
- struct Tread tread;
- struct Rread rread;
- struct Twrite twrite;
- struct Rwrite rwrite;
- struct Tclunk tclunk;
- struct Rclunk rclunk;
- struct Tremove tremove;
- struct Rremove rremove;
- struct Tstat tstat;
- struct Rstat rstat;
- struct Twstat twstat;
- struct Rwstat rwstat;
- } params;
-};
-
-#define PRINT_FCALL_ERROR(s, fcall) dprintk(DEBUG_ERROR, "%s: %.*s\n", s, \
- fcall?fcall->params.rerror.error.len:0, \
- fcall?fcall->params.rerror.error.str:"");
-
-int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
- char *version, struct v9fs_fcall **rcall);
-
-int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
- u32 fid, u32 afid, struct v9fs_fcall **rcall);
-
-int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid);
-
-int v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid,
- struct v9fs_fcall **rcall);
-
-int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
- struct v9fs_wstat *wstat, struct v9fs_fcall **rcall);
-
-int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
- char *name, struct v9fs_fcall **rcall);
-
-int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
- struct v9fs_fcall **rcall);
-
-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, 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);
-
-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 87897f84dfb..bc7f0d1551e 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -1,18 +1,12 @@
obj-$(CONFIG_9P_FS) := 9p.o
9p-objs := \
- trans_fd.o \
- mux.o \
- fcall.o \
- conv.o \
vfs_super.o \
vfs_inode.o \
vfs_addr.o \
vfs_file.o \
vfs_dir.o \
vfs_dentry.o \
- error.o \
v9fs.o \
fid.o \
- fcprint.o
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
deleted file mode 100644
index a3ed571eee3..00000000000
--- a/fs/9p/conv.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * linux/fs/9p/conv.c
- *
- * 9P protocol conversion functions
- *
- * Copyright (C) 2004, 2005 by Latchesar Ionkov <lucho@ionkov.net>
- * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
- * 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 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/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/idr.h>
-#include <asm/uaccess.h>
-#include "debug.h"
-#include "v9fs.h"
-#include "9p.h"
-#include "conv.h"
-
-/*
- * Buffer to help with string parsing
- */
-struct cbuf {
- unsigned char *sp;
- unsigned char *p;
- unsigned char *ep;
-};
-
-static inline void buf_init(struct cbuf *buf, void *data, int datalen)
-{
- buf->sp = buf->p = data;
- buf->ep = data + datalen;
-}
-
-static inline int buf_check_overflow(struct cbuf *buf)
-{
- return buf->p > buf->ep;
-}
-
-static int buf_check_size(struct cbuf *buf, int len)
-{
- if (buf->p + len > buf->ep) {
- if (buf->p < buf->ep) {
- eprintk(KERN_ERR, "buffer overflow: want %d has %d\n",
- len, (int)(buf->ep - buf->p));
- dump_stack();
- buf->p = buf->ep + 1;
- }
-
- return 0;
- }
-
- return 1;
-}
-
-static void *buf_alloc(struct cbuf *buf, int len)
-{
- void *ret = NULL;
-
- if (buf_check_size(buf, len)) {
- ret = buf->p;
- buf->p += len;
- }
-
- return ret;
-}
-
-static void buf_put_int8(struct cbuf *buf, u8 val)
-{
- if (buf_check_size(buf, 1)) {
- buf->p[0] = val;
- buf->p++;
- }
-}
-
-static void buf_put_int16(struct cbuf *buf, u16 val)
-{
- if (buf_check_size(buf, 2)) {
- *(__le16 *) buf->p = cpu_to_le16(val);
- buf->p += 2;
- }
-}
-
-static void buf_put_int32(struct cbuf *buf, u32 val)
-{
- if (buf_check_size(buf, 4)) {
- *(__le32 *)buf->p = cpu_to_le32(val);
- buf->p += 4;
- }
-}
-
-static void buf_put_int64(struct cbuf *buf, u64 val)
-{
- if (buf_check_size(buf, 8)) {
- *(__le64 *)buf->p = cpu_to_le64(val);
- buf->p += 8;
- }
-}
-
-static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
-{
- char *ret;
-
- ret = NULL;
- if (buf_check_size(buf, slen + 2)) {
- buf_put_int16(buf, slen);
- ret = buf->p;
- memcpy(buf->p, s, slen);
- buf->p += slen;
- }
-
- return ret;
-}
-
-static inline void buf_put_string(struct cbuf *buf, const char *s)
-{
- buf_put_stringn(buf, s, strlen(s));
-}
-
-static u8 buf_get_int8(struct cbuf *buf)
-{
- u8 ret = 0;
-
- if (buf_check_size(buf, 1)) {
- ret = buf->p[0];
- buf->p++;
- }
-
- return ret;
-}
-
-static u16 buf_get_int16(struct cbuf *buf)
-{
- u16 ret = 0;
-
- if (buf_check_size(buf, 2)) {
- ret = le16_to_cpu(*(__le16 *)buf->p);
- buf->p += 2;
- }
-
- return ret;
-}
-
-static u32 buf_get_int32(struct cbuf *buf)
-{
- u32 ret = 0;
-
- if (buf_check_size(buf, 4)) {
- ret = le32_to_cpu(*(__le32 *)buf->p);
- buf->p += 4;
- }
-
- return ret;
-}
-
-static u64 buf_get_int64(struct cbuf *buf)
-{
- u64 ret = 0;
-
- if (buf_check_size(buf, 8)) {
- ret = le64_to_cpu(*(__le64 *)buf->p);
- buf->p += 8;
- }
-
- return ret;
-}
-
-static void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr)
-{
- vstr->len = buf_get_int16(buf);
- if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) {
- vstr->str = buf->p;
- buf->p += vstr->len;
- } else {
- vstr->len = 0;
- vstr->str = NULL;
- }
-}
-
-static void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid)
-{
- qid->type = buf_get_int8(bufp);
- qid->version = buf_get_int32(bufp);
- qid->path = buf_get_int64(bufp);
-}
-
-/**
- * v9fs_size_wstat - calculate the size of a variable length stat struct
- * @stat: metadata (stat) structure
- * @extended: non-zero if 9P2000.u
- *
- */
-
-static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended)
-{
- int size = 0;
-
- if (wstat == NULL) {
- eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n");
- return 0;
- }
-
- size = /* 2 + *//* size[2] */
- 2 + /* type[2] */
- 4 + /* dev[4] */
- 1 + /* qid.type[1] */
- 4 + /* qid.vers[4] */
- 8 + /* qid.path[8] */
- 4 + /* mode[4] */
- 4 + /* atime[4] */
- 4 + /* mtime[4] */
- 8 + /* length[8] */
- 8; /* minimum sum of string lengths */
-
- if (wstat->name)
- size += strlen(wstat->name);
- if (wstat->uid)
- size += strlen(wstat->uid);
- if (wstat->gid)
- size += strlen(wstat->gid);
- if (wstat->muid)
- size += strlen(wstat->muid);
-
- if (extended) {
- size += 4 + /* n_uid[4] */
- 4 + /* n_gid[4] */
- 4 + /* n_muid[4] */
- 2; /* string length of extension[4] */
- if (wstat->extension)
- size += strlen(wstat->extension);
- }
-
- return size;
-}
-
-/**
- * buf_get_stat - safely decode a recieved metadata (stat) structure
- * @bufp: buffer to deserialize
- * @stat: metadata (stat) structure
- * @extended: non-zero if 9P2000.u
- *
- */
-
-static void
-buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended)
-{
- stat->size = buf_get_int16(bufp);
- stat->type = buf_get_int16(bufp);
- stat->dev = buf_get_int32(bufp);
- stat->qid.type = buf_get_int8(bufp);
- stat->qid.version = buf_get_int32(bufp);
- stat->qid.path = buf_get_int64(bufp);
- stat->mode = buf_get_int32(bufp);
- stat->atime = buf_get_int32(bufp);
- stat->mtime = buf_get_int32(bufp);
- stat->length = buf_get_int64(bufp);
- buf_get_str(bufp, &stat->name);
- buf_get_str(bufp, &stat->uid);
- buf_get_str(bufp, &stat->gid);
- buf_get_str(bufp, &stat->muid);
-
- if (extended) {
- buf_get_str(bufp, &stat->extension);
- stat->n_uid = buf_get_int32(bufp);
- stat->n_gid = buf_get_int32(bufp);
- stat->n_muid = buf_get_int32(bufp);
- }
-}
-
-/**
- * v9fs_deserialize_stat - decode a received metadata structure
- * @buf: buffer to deserialize
- * @buflen: length of received buffer
- * @stat: metadata structure to decode into
- * @extended: non-zero if 9P2000.u
- *
- * Note: stat will point to the buf region.
- */
-
-int
-v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat,
- int extended)
-{
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
- unsigned char *p;
-
- buf_init(bufp, buf, buflen);
- p = bufp->p;
- buf_get_stat(bufp, stat, extended);
-
- if (buf_check_overflow(bufp))
- return 0;
- else
- return bufp->p - p;
-}
-
-/**
- * deserialize_fcall - unmarshal a response
- * @buf: recieved buffer
- * @buflen: length of received buffer
- * @rcall: fcall structure to populate
- * @rcalllen: length of fcall structure to populate
- * @extended: non-zero if 9P2000.u
- *
- */
-
-int
-v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall,
- int extended)
-{
-
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
- int i = 0;
-
- buf_init(bufp, buf, buflen);
-
- rcall->size = buf_get_int32(bufp);
- rcall->id = buf_get_int8(bufp);
- rcall->tag = buf_get_int16(bufp);
-
- dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id,
- rcall->tag);
-
- switch (rcall->id) {
- default:
- eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id);
- return -EPROTO;
- case RVERSION:
- rcall->params.rversion.msize = buf_get_int32(bufp);
- buf_get_str(bufp, &rcall->params.rversion.version);
- break;
- case RFLUSH:
- break;
- case RATTACH:
- rcall->params.rattach.qid.type = buf_get_int8(bufp);
- rcall->params.rattach.qid.version = buf_get_int32(bufp);
- rcall->params.rattach.qid.path = buf_get_int64(bufp);
- break;
- case RWALK:
- rcall->params.rwalk.nwqid = buf_get_int16(bufp);
- if (rcall->params.rwalk.nwqid > V9FS_MAXWELEM) {
- eprintk(KERN_ERR, "Rwalk with more than %d qids: %d\n",
- V9FS_MAXWELEM, rcall->params.rwalk.nwqid);
- return -EPROTO;
- }
-
- for (i = 0; i < rcall->params.rwalk.nwqid; i++)
- buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]);
- break;
- case ROPEN:
- buf_get_qid(bufp, &rcall->params.ropen.qid);
- rcall->params.ropen.iounit = buf_get_int32(bufp);
- break;
- case RCREATE:
- buf_get_qid(bufp, &rcall->params.rcreate.qid);
- rcall->params.rcreate.iounit = buf_get_int32(bufp);
- break;
- case RREAD:
- rcall->params.rread.count = buf_get_int32(bufp);
- rcall->params.rread.data = bufp->p;
- buf_check_size(bufp, rcall->params.rread.count);
- break;
- case RWRITE:
- rcall->params.rwrite.count = buf_get_int32(bufp);
- break;
- case RCLUNK:
- break;
- case RREMOVE:
- break;
- case RSTAT:
- buf_get_int16(bufp);
- buf_get_stat(bufp, &rcall->params.rstat.stat, extended);
- break;
- case RWSTAT:
- break;
- case RERROR:
- buf_get_str(bufp, &rcall->params.rerror.error);
- if (extended)
- rcall->params.rerror.errno = buf_get_int16(bufp);
- break;
- }
-
- if (buf_check_overflow(bufp)) {
- dprintk(DEBUG_ERROR, "buffer overflow\n");
- return -EIO;
- }
-
- return bufp->p - bufp->sp;
-}
-
-static inline void v9fs_put_int8(struct cbuf *bufp, u8 val, u8 * p)
-{
- *p = val;
- buf_put_int8(bufp, val);
-}
-
-static inline void v9fs_put_int16(struct cbuf *bufp, u16 val, u16 * p)
-{
- *p = val;
- buf_put_int16(bufp, val);
-}
-
-static inline void v9fs_put_int32(struct cbuf *bufp, u32 val, u32 * p)
-{
- *p = val;
- buf_put_int32(bufp, val);
-}
-
-static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p)
-{
- *p = val;
- buf_put_int64(bufp, val);
-}
-
-static void
-v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str)
-{
- int len;
- char *s;
-
- if (data)
- len = strlen(data);
- else
- len = 0;
-
- s = buf_put_stringn(bufp, data, len);
- if (str) {
- str->len = len;
- str->str = s;
- }
-}
-
-static int
-v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count,
- unsigned char **pdata)
-{
- *pdata = buf_alloc(bufp, count);
- return copy_from_user(*pdata, data, count);
-}
-
-static void
-v9fs_put_wstat(struct cbuf *bufp, struct v9fs_wstat *wstat,
- struct v9fs_stat *stat, int statsz, int extended)
-{
- v9fs_put_int16(bufp, statsz, &stat->size);
- v9fs_put_int16(bufp, wstat->type, &stat->type);
- v9fs_put_int32(bufp, wstat->dev, &stat->dev);
- v9fs_put_int8(bufp, wstat->qid.type, &stat->qid.type);
- v9fs_put_int32(bufp, wstat->qid.version, &stat->qid.version);
- v9fs_put_int64(bufp, wstat->qid.path, &stat->qid.path);
- v9fs_put_int32(bufp, wstat->mode, &stat->mode);
- v9fs_put_int32(bufp, wstat->atime, &stat->atime);
- v9fs_put_int32(bufp, wstat->mtime, &stat->mtime);
- v9fs_put_int64(bufp, wstat->length, &stat->length);
-
- v9fs_put_str(bufp, wstat->name, &stat->name);
- v9fs_put_str(bufp, wstat->uid, &stat->uid);
- v9fs_put_str(bufp, wstat->gid, &stat->gid);
- v9fs_put_str(bufp, wstat->muid, &stat->muid);
-
- if (extended) {
- v9fs_put_str(bufp, wstat->extension, &stat->extension);
- v9fs_put_int32(bufp, wstat->n_uid, &stat->n_uid);
- v9fs_put_int32(bufp, wstat->n_gid, &stat->n_gid);
- v9fs_put_int32(bufp, wstat->n_muid, &stat->n_muid);
- }
-}
-
-static struct v9fs_fcall *
-v9fs_create_common(struct cbuf *bufp, u32 size, u8 id)
-{
- struct v9fs_fcall *fc;
-
- size += 4 + 1 + 2; /* size[4] id[1] tag[2] */
- fc = kmalloc(sizeof(struct v9fs_fcall) + size, GFP_KERNEL);
- if (!fc)
- return ERR_PTR(-ENOMEM);
-
- fc->sdata = (char *)fc + sizeof(*fc);
-
- buf_init(bufp, (char *)fc->sdata, size);
- v9fs_put_int32(bufp, size, &fc->size);
- v9fs_put_int8(bufp, id, &fc->id);
- v9fs_put_int16(bufp, V9FS_NOTAG, &fc->tag);
-
- return fc;
-}
-
-void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag)
-{
- fc->tag = tag;
- *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag);
-}
-
-struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version)
-{
- int size;
- struct v9fs_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 2 + strlen(version); /* msize[4] version[s] */
- fc = v9fs_create_common(bufp, size, TVERSION);
- if (IS_ERR(fc))
- goto error;
-
- v9fs_put_int32(bufp, msize, &fc->params.tversion.msize);
- v9fs_put_str(bufp, version, &fc->params.tversion.version);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
- error:
- return fc;
-}
-
-#if 0
-struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname)
-{
- int size;
- struct v9fs_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 2 + strlen(uname) + 2 + strlen(aname); /* afid[4] uname[s] aname[s] */
- fc = v9fs_create_common(bufp, size, TAUTH);
- if (IS_ERR(fc))
- goto error;
-
- v9fs_put_int32(bufp, afid, &fc->params.tauth.afid);
- v9fs_put_str(bufp, uname, &fc->params.tauth.uname);
- v9fs_put_str(bufp, aname, &fc->params.tauth.aname);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
- error:
- return fc;
-}
-#endif /* 0 */
-
-struct v9fs_fcall *
-v9fs_create_tattach(u32 fid, u32 afid, char *uname, char *aname)
-{
- int size;
- struct v9fs_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); /* fid[4] afid[4] uname[s] aname[s] */
- fc = v9fs_create_common(bufp, size, TATTACH);
- if (IS_ERR(fc))
- goto error;
-
- v9fs_put_int32(bufp, fid, &fc->params.tattach.fid);
- v9fs_put_int32(bufp, afid, &fc->params.tattach.afid);
- v9fs_put_str(bufp, uname, &fc->params.tattach.uname);
- v9fs_put_str(bufp, aname, &fc->params.tattach.aname);
-
- error:
- return fc;
-}
-
-struct v9fs_fcall *v9fs_create_tflush(u16 oldtag)
-{
- int size;
- struct v9fs_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 2; /* oldtag[2] */
- fc = v9fs_create_common(bufp, size, TFLUSH);
- if (IS_ERR(fc))
- goto error;
-
- v9fs_put_int16(bufp, oldtag, &fc->params.tflush.oldtag);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
- error:
- return fc;
-}
-
-struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
- char **wnames)
-{
- int i, size;
- struct v9fs_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- if (nwname > V9FS_MAXWELEM) {
- dprintk(DEBUG_ERROR, "nwname > %d\n", V9FS_MAXWELEM);
- return NULL;
- }
-
- size = 4 + 4 + 2; /* fid[4] newfid[4] nwname[2] ... */
- for (i = 0; i < nwname; i++) {
- size += 2 + strlen(wnames[i]); /* wname[s] */
- }
-
- fc = v9fs_create_common(bufp, size, TWALK);
- if (IS_ERR(fc))
- goto error;
-
- v9fs_put_int32(bufp, fid, &fc->params.twalk.fid);
- v9fs_put_int32(bufp, newfid, &fc->params.twalk.newfid);
- v9fs_put_int16(bufp, nwname, &fc->params.twalk.nwname);
- for (i = 0; i < nwname; i++) {
- v9fs_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]);
- }
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
- error:
- return fc;
-}
-
-struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode)
-{
- int size;
- struct v9fs_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 1; /* fid[4] mode[1] */
- fc = v9fs_create_common(bufp, size, TOPEN);
- if (IS_ERR(fc))
- goto error;
-
- v9fs_put_int32(bufp, fid, &fc->params.topen.fid);
- v9fs_put_int8(bufp, mode, &fc->params.topen.mode);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
- error:
- return fc;
-}
-
-struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
- char *extension, int extended)
-{
- int size;
- struct v9fs_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */
- if (extended) {
- size += 2 + /* extension[s] */
- (extension == NULL ? 0 : strlen(extension));
- }
-
- fc = v9fs_create_common(bufp, size, TCREATE);
- if (IS_ERR(fc))
- goto error;
-
- v9fs_put_int32(bufp, fid, &fc->params.tcreate.fid);
- 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);