dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname,
aname, fid, afid);
- ret = -ENOMEM;
tc = v9fs_create_tattach(fid, afid, uname, aname);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
dprintk(DEBUG_9P, "fid %d\n", fid);
- ret = -ENOMEM;
rc = NULL;
tc = v9fs_create_tclunk(fid);
if (!IS_ERR(tc))
dprintk(DEBUG_9P, "oldtag %d\n", oldtag);
- ret = -ENOMEM;
tc = v9fs_create_tflush(oldtag);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, NULL);
dprintk(DEBUG_9P, "fid %d\n", fid);
- ret = -ENOMEM;
tc = v9fs_create_twstat(fid, wstat, v9ses->extended);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
else
nwname = 0;
- ret = -ENOMEM;
tc = v9fs_create_twalk(fid, newfid, nwname, &name);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode);
- ret = -ENOMEM;
tc = v9fs_create_topen(fid, mode);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
dprintk(DEBUG_9P, "fid %d\n", fid);
- ret = -ENOMEM;
tc = v9fs_create_tremove(fid);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n",
fid, name, perm, mode);
- ret = -ENOMEM;
tc = v9fs_create_tcreate(fid, name, perm, mode);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid,
(long long unsigned) offset, count);
- ret = -ENOMEM;
tc = v9fs_create_tread(fid, offset, count);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid,
(long long unsigned) offset, count);
- ret = -ENOMEM;
tc = v9fs_create_twrite(fid, offset, count, data);
if (!IS_ERR(tc)) {
ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
fcall?fcall->params.rerror.error.len:0, \
fcall?fcall->params.rerror.error.str:"");
-char *v9fs_str_copy(char *buf, int buflen, struct v9fs_str *str);
-int v9fs_str_compare(char *buf, struct v9fs_str *str);
-
int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
char *version, struct v9fs_fcall **rcall);
unsigned char *ep;
};
-char *v9fs_str_copy(char *buf, int buflen, struct v9fs_str *str)
-{
- int n;
-
- if (buflen < str->len)
- n = buflen;
- else
- n = str->len;
-
- memmove(buf, str->str, n - 1);
-
- return buf;
-}
-
-int v9fs_str_compare(char *buf, struct v9fs_str *str)
-{
- int n, ret;
-
- ret = strncmp(buf, str->str, str->len);
-
- if (!ret) {
- n = strlen(buf);
- if (n < str->len)
- ret = -1;
- else if (n > str->len)
- ret = 1;
- }
-
- return ret;
-}
-
static inline void buf_init(struct cbuf *buf, void *data, int datalen)
{
buf->sp = buf->p = data;
static inline int buf_check_size(struct cbuf *buf, int len)
{
- if (buf->p + len > buf->ep && 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;
+ 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;
}
void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag)
{
+ fc->tag = tag;
*(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag);
}
};
extern int v9fs_error_init(void);
-extern int v9fs_errstr2errno(char *errstr, int len);
wait_queue_head_t wqueue;
};
-extern int v9fs_errstr2errno(char *str, int len);
-
static int v9fs_poll_proc(void *);
static void v9fs_read_work(void *);
static void v9fs_write_work(void *);
static int v9fs_mux_poll_task_num;
static struct v9fs_mux_poll_task v9fs_mux_poll_tasks[100];
-void v9fs_mux_global_init(void)
+int v9fs_mux_global_init(void)
{
int i;
v9fs_mux_poll_tasks[i].task = NULL;
v9fs_mux_wq = create_workqueue("v9fs");
+ if (!v9fs_mux_wq)
+ return -ENOMEM;
+
+ return 0;
}
void v9fs_mux_global_exit(void)
return n;
}
-static void v9fs_mux_poll_start(struct v9fs_mux_data *m)
+static int v9fs_mux_poll_start(struct v9fs_mux_data *m)
{
int i, n;
struct v9fs_mux_poll_task *vpt, *vptlast;
+ struct task_struct *pproc;
dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num,
v9fs_mux_poll_task_num);
if (v9fs_mux_poll_tasks[i].task == NULL) {
vpt = &v9fs_mux_poll_tasks[i];
dprintk(DEBUG_MUX, "create proc %p\n", vpt);
- vpt->task =
- kthread_create(v9fs_poll_proc, vpt,
+ pproc = kthread_create(v9fs_poll_proc, vpt,
"v9fs-poll");
- INIT_LIST_HEAD(&vpt->mux_list);
- vpt->muxnum = 0;
- v9fs_mux_poll_task_num++;
- wake_up_process(vpt->task);
+
+ if (!IS_ERR(pproc)) {
+ vpt->task = pproc;
+ INIT_LIST_HEAD(&vpt->mux_list);
+ vpt->muxnum = 0;
+ v9fs_mux_poll_task_num++;
+ wake_up_process(vpt->task);
+ }
break;
}
}
}
if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) {
+ if (vptlast == NULL)
+ return -ENOMEM;
+
dprintk(DEBUG_MUX, "put in proc %d\n", i);
list_add(&m->mux_list, &vptlast->mux_list);
vptlast->muxnum++;
- m->poll_task = vpt;
+ m->poll_task = vptlast;
memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
init_poll_funcptr(&m->pt, v9fs_pollwait);
}
v9fs_mux_num++;
down(&v9fs_mux_task_lock);
+
+ return 0;
}
static void v9fs_mux_poll_stop(struct v9fs_mux_data *m)
INIT_WORK(&m->wq, v9fs_write_work, m);
m->wsched = 0;
memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
- v9fs_mux_poll_start(m);
+ m->poll_task = NULL;
+ n = v9fs_mux_poll_start(m);
+ if (n)
+ return ERR_PTR(n);
n = trans->poll(trans, &m->pt);
if (n & POLLIN) {
typedef void (*v9fs_mux_req_callback)(void *a, struct v9fs_fcall *tc,
struct v9fs_fcall *rc, int err);
-void v9fs_mux_global_init(void);
+int v9fs_mux_global_init(void);
void v9fs_mux_global_exit(void);
struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize,
void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush);
void v9fs_mux_cancel(struct v9fs_mux_data *m, int err);
+int v9fs_errstr2errno(char *errstr, int len);
int n = 0;
int newfid = -1;
int retval = -EINVAL;
+ struct v9fs_str *version;
v9ses->name = __getname();
if (!v9ses->name)
goto FreeFcall;
}
- /* Really should check for 9P1 and report error */
- if (!v9fs_str_compare("9P2000.u", &fcall->params.rversion.version)) {
+ version = &fcall->params.rversion.version;
+ if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) {
dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n");
v9ses->extended = 1;
- } else {
+ } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) {
dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n");
v9ses->extended = 0;
+ } else {
+ retval = -EREMOTEIO;
+ goto FreeFcall;
}
n = fcall->params.rversion.msize;
static int __init init_v9fs(void)
{
+ int ret;
+
v9fs_error_init();
printk(KERN_INFO "Installing v9fs 9P2000 file system support\n");
- v9fs_mux_global_init();
- return register_filesystem(&v9fs_fs_type);
+ ret = v9fs_mux_global_init();
+ if (!ret)
+ ret = register_filesystem(&v9fs_fs_type);
+
+ return ret;
}
/**
v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode,
struct super_block *sb)
{
+ int n;
char ext[32];
struct v9fs_session_info *v9ses = sb->s_fs_info;
int major = -1;
int minor = -1;
- v9fs_str_copy(ext, sizeof(ext), &stat->extension);
+ n = stat->extension.len;
+ if (n > sizeof(ext)-1)
+ n = sizeof(ext)-1;
+ memmove(ext, stat->extension.str, n);
+ ext[n] = 0;
sscanf(ext, "%c %u %u", &type, &major, &minor);
switch (type) {
case 'c':
dprintk(DEBUG_VFS, " \n");
- v9ses = kmalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
+ v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
if (!v9ses)
return ERR_PTR(-ENOMEM);
- memset(v9ses, 0, sizeof(struct v9fs_session_info));
if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
dprintk(DEBUG_ERROR, "problem initiating session\n");
kfree(v9ses);