|
@@ -42,6 +42,8 @@
|
|
|
#include <net/9p/client.h>
|
|
|
#include <net/9p/transport.h>
|
|
|
|
|
|
+#include <linux/syscalls.h> /* killme */
|
|
|
+
|
|
|
#define P9_PORT 564
|
|
|
#define MAX_SOCK_BUF (64*1024)
|
|
|
#define MAXPOLLWADDR 2
|
|
@@ -788,24 +790,41 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
|
|
|
|
|
|
static int p9_socket_open(struct p9_client *client, struct socket *csocket)
|
|
|
{
|
|
|
- int fd, ret;
|
|
|
+ struct p9_trans_fd *p;
|
|
|
+ int ret, fd;
|
|
|
+
|
|
|
+ p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
|
|
|
+ if (!p)
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
csocket->sk->sk_allocation = GFP_NOIO;
|
|
|
fd = sock_map_fd(csocket, 0);
|
|
|
if (fd < 0) {
|
|
|
P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n");
|
|
|
+ sock_release(csocket);
|
|
|
+ kfree(p);
|
|
|
return fd;
|
|
|
}
|
|
|
|
|
|
- ret = p9_fd_open(client, fd, fd);
|
|
|
- if (ret < 0) {
|
|
|
- P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n");
|
|
|
+ get_file(csocket->file);
|
|
|
+ get_file(csocket->file);
|
|
|
+ p->wr = p->rd = csocket->file;
|
|
|
+ client->trans = p;
|
|
|
+ client->status = Connected;
|
|
|
+
|
|
|
+ sys_close(fd); /* still racy */
|
|
|
+
|
|
|
+ p->rd->f_flags |= O_NONBLOCK;
|
|
|
+
|
|
|
+ p->conn = p9_conn_create(client);
|
|
|
+ if (IS_ERR(p->conn)) {
|
|
|
+ ret = PTR_ERR(p->conn);
|
|
|
+ p->conn = NULL;
|
|
|
+ kfree(p);
|
|
|
+ sockfd_put(csocket);
|
|
|
sockfd_put(csocket);
|
|
|
return ret;
|
|
|
}
|
|
|
-
|
|
|
- ((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -883,7 +902,6 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
|
|
|
struct socket *csocket;
|
|
|
struct sockaddr_in sin_server;
|
|
|
struct p9_fd_opts opts;
|
|
|
- struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
|
|
|
|
|
|
err = parse_opts(args, &opts);
|
|
|
if (err < 0)
|
|
@@ -897,12 +915,11 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
|
|
|
sin_server.sin_family = AF_INET;
|
|
|
sin_server.sin_addr.s_addr = in_aton(addr);
|
|
|
sin_server.sin_port = htons(opts.port);
|
|
|
- sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
|
|
|
+ err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
|
|
|
|
|
|
- if (!csocket) {
|
|
|
+ if (err) {
|
|
|
P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n");
|
|
|
- err = -EIO;
|
|
|
- goto error;
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
err = csocket->ops->connect(csocket,
|
|
@@ -912,30 +929,11 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
|
|
|
P9_EPRINTK(KERN_ERR,
|
|
|
"p9_trans_tcp: problem connecting socket to %s\n",
|
|
|
addr);
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- err = p9_socket_open(client, csocket);
|
|
|
- if (err < 0)
|
|
|
- goto error;
|
|
|
-
|
|
|
- p = (struct p9_trans_fd *) client->trans;
|
|
|
- p->conn = p9_conn_create(client);
|
|
|
- if (IS_ERR(p->conn)) {
|
|
|
- err = PTR_ERR(p->conn);
|
|
|
- p->conn = NULL;
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-
|
|
|
-error:
|
|
|
- if (csocket)
|
|
|
sock_release(csocket);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
|
|
|
- kfree(p);
|
|
|
-
|
|
|
- return err;
|
|
|
+ return p9_socket_open(client, csocket);
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -944,49 +942,33 @@ p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
|
|
|
int err;
|
|
|
struct socket *csocket;
|
|
|
struct sockaddr_un sun_server;
|
|
|
- struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
|
|
|
|
|
|
csocket = NULL;
|
|
|
|
|
|
if (strlen(addr) > UNIX_PATH_MAX) {
|
|
|
P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
|
|
|
addr);
|
|
|
- err = -ENAMETOOLONG;
|
|
|
- goto error;
|
|
|
+ return -ENAMETOOLONG;
|
|
|
}
|
|
|
|
|
|
sun_server.sun_family = PF_UNIX;
|
|
|
strcpy(sun_server.sun_path, addr);
|
|
|
- sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
|
|
|
+ err = sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
|
|
|
+ if (err < 0) {
|
|
|
+ P9_EPRINTK(KERN_ERR, "p9_trans_unix: problem creating socket\n");
|
|
|
+ return err;
|
|
|
+ }
|
|
|
err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
|
|
|
sizeof(struct sockaddr_un) - 1, 0);
|
|
|
if (err < 0) {
|
|
|
P9_EPRINTK(KERN_ERR,
|
|
|
"p9_trans_unix: problem connecting socket: %s: %d\n",
|
|
|
addr, err);
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- err = p9_socket_open(client, csocket);
|
|
|
- if (err < 0)
|
|
|
- goto error;
|
|
|
-
|
|
|
- p = (struct p9_trans_fd *) client->trans;
|
|
|
- p->conn = p9_conn_create(client);
|
|
|
- if (IS_ERR(p->conn)) {
|
|
|
- err = PTR_ERR(p->conn);
|
|
|
- p->conn = NULL;
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-
|
|
|
-error:
|
|
|
- if (csocket)
|
|
|
sock_release(csocket);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
|
|
|
- kfree(p);
|
|
|
- return err;
|
|
|
+ return p9_socket_open(client, csocket);
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -994,7 +976,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
|
|
|
{
|
|
|
int err;
|
|
|
struct p9_fd_opts opts;
|
|
|
- struct p9_trans_fd *p = NULL; /* this get allocated in p9_fd_open */
|
|
|
+ struct p9_trans_fd *p;
|
|
|
|
|
|
parse_opts(args, &opts);
|
|
|
|
|
@@ -1005,21 +987,19 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
|
|
|
|
|
|
err = p9_fd_open(client, opts.rfd, opts.wfd);
|
|
|
if (err < 0)
|
|
|
- goto error;
|
|
|
+ return err;
|
|
|
|
|
|
p = (struct p9_trans_fd *) client->trans;
|
|
|
p->conn = p9_conn_create(client);
|
|
|
if (IS_ERR(p->conn)) {
|
|
|
err = PTR_ERR(p->conn);
|
|
|
p->conn = NULL;
|
|
|
- goto error;
|
|
|
+ fput(p->rd);
|
|
|
+ fput(p->wr);
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
-
|
|
|
-error:
|
|
|
- kfree(p);
|
|
|
- return err;
|
|
|
}
|
|
|
|
|
|
static struct p9_trans_module p9_tcp_trans = {
|