aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/trans_fd.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /net/9p/trans_fd.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'net/9p/trans_fd.c')
-rw-r--r--net/9p/trans_fd.c127
1 files changed, 55 insertions, 72 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 8d934dd7fd54..98ce9bcb0e15 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -38,10 +38,13 @@
38#include <linux/idr.h> 38#include <linux/idr.h>
39#include <linux/file.h> 39#include <linux/file.h>
40#include <linux/parser.h> 40#include <linux/parser.h>
41#include <linux/slab.h>
41#include <net/9p/9p.h> 42#include <net/9p/9p.h>
42#include <net/9p/client.h> 43#include <net/9p/client.h>
43#include <net/9p/transport.h> 44#include <net/9p/transport.h>
44 45
46#include <linux/syscalls.h> /* killme */
47
45#define P9_PORT 564 48#define P9_PORT 564
46#define MAX_SOCK_BUF (64*1024) 49#define MAX_SOCK_BUF (64*1024)
47#define MAXPOLLWADDR 2 50#define MAXPOLLWADDR 2
@@ -633,8 +636,8 @@ static void p9_poll_mux(struct p9_conn *m)
633 if (n & POLLOUT) { 636 if (n & POLLOUT) {
634 set_bit(Wpending, &m->wsched); 637 set_bit(Wpending, &m->wsched);
635 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can write\n", m); 638 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can write\n", m);
636 if ((m->wsize || !list_empty(&m->unsent_req_list)) 639 if ((m->wsize || !list_empty(&m->unsent_req_list)) &&
637 && !test_and_set_bit(Wworksched, &m->wsched)) { 640 !test_and_set_bit(Wworksched, &m->wsched)) {
638 P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m); 641 P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m);
639 queue_work(p9_mux_wq, &m->wq); 642 queue_work(p9_mux_wq, &m->wq);
640 } 643 }
@@ -712,7 +715,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
712 char *p; 715 char *p;
713 substring_t args[MAX_OPT_ARGS]; 716 substring_t args[MAX_OPT_ARGS];
714 int option; 717 int option;
715 char *options; 718 char *options, *tmp_options;
716 int ret; 719 int ret;
717 720
718 opts->port = P9_PORT; 721 opts->port = P9_PORT;
@@ -722,12 +725,13 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
722 if (!params) 725 if (!params)
723 return 0; 726 return 0;
724 727
725 options = kstrdup(params, GFP_KERNEL); 728 tmp_options = kstrdup(params, GFP_KERNEL);
726 if (!options) { 729 if (!tmp_options) {
727 P9_DPRINTK(P9_DEBUG_ERROR, 730 P9_DPRINTK(P9_DEBUG_ERROR,
728 "failed to allocate copy of option string\n"); 731 "failed to allocate copy of option string\n");
729 return -ENOMEM; 732 return -ENOMEM;
730 } 733 }
734 options = tmp_options;
731 735
732 while ((p = strsep(&options, ",")) != NULL) { 736 while ((p = strsep(&options, ",")) != NULL) {
733 int token; 737 int token;
@@ -758,7 +762,8 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
758 continue; 762 continue;
759 } 763 }
760 } 764 }
761 kfree(options); 765
766 kfree(tmp_options);
762 return 0; 767 return 0;
763} 768}
764 769
@@ -788,24 +793,41 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
788 793
789static int p9_socket_open(struct p9_client *client, struct socket *csocket) 794static int p9_socket_open(struct p9_client *client, struct socket *csocket)
790{ 795{
791 int fd, ret; 796 struct p9_trans_fd *p;
797 int ret, fd;
798
799 p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
800 if (!p)
801 return -ENOMEM;
792 802
793 csocket->sk->sk_allocation = GFP_NOIO; 803 csocket->sk->sk_allocation = GFP_NOIO;
794 fd = sock_map_fd(csocket, 0); 804 fd = sock_map_fd(csocket, 0);
795 if (fd < 0) { 805 if (fd < 0) {
796 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); 806 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n");
807 sock_release(csocket);
808 kfree(p);
797 return fd; 809 return fd;
798 } 810 }
799 811
800 ret = p9_fd_open(client, fd, fd); 812 get_file(csocket->file);
801 if (ret < 0) { 813 get_file(csocket->file);
802 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); 814 p->wr = p->rd = csocket->file;
815 client->trans = p;
816 client->status = Connected;
817
818 sys_close(fd); /* still racy */
819
820 p->rd->f_flags |= O_NONBLOCK;
821
822 p->conn = p9_conn_create(client);
823 if (IS_ERR(p->conn)) {
824 ret = PTR_ERR(p->conn);
825 p->conn = NULL;
826 kfree(p);
827 sockfd_put(csocket);
803 sockfd_put(csocket); 828 sockfd_put(csocket);
804 return ret; 829 return ret;
805 } 830 }
806
807 ((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK;
808
809 return 0; 831 return 0;
810} 832}
811 833
@@ -883,7 +905,6 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
883 struct socket *csocket; 905 struct socket *csocket;
884 struct sockaddr_in sin_server; 906 struct sockaddr_in sin_server;
885 struct p9_fd_opts opts; 907 struct p9_fd_opts opts;
886 struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
887 908
888 err = parse_opts(args, &opts); 909 err = parse_opts(args, &opts);
889 if (err < 0) 910 if (err < 0)
@@ -897,12 +918,11 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
897 sin_server.sin_family = AF_INET; 918 sin_server.sin_family = AF_INET;
898 sin_server.sin_addr.s_addr = in_aton(addr); 919 sin_server.sin_addr.s_addr = in_aton(addr);
899 sin_server.sin_port = htons(opts.port); 920 sin_server.sin_port = htons(opts.port);
900 sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); 921 err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
901 922
902 if (!csocket) { 923 if (err) {
903 P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n"); 924 P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n");
904 err = -EIO; 925 return err;
905 goto error;
906 } 926 }
907 927
908 err = csocket->ops->connect(csocket, 928 err = csocket->ops->connect(csocket,
@@ -912,30 +932,11 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
912 P9_EPRINTK(KERN_ERR, 932 P9_EPRINTK(KERN_ERR,
913 "p9_trans_tcp: problem connecting socket to %s\n", 933 "p9_trans_tcp: problem connecting socket to %s\n",
914 addr); 934 addr);
915 goto error;
916 }
917
918 err = p9_socket_open(client, csocket);
919 if (err < 0)
920 goto error;
921
922 p = (struct p9_trans_fd *) client->trans;
923 p->conn = p9_conn_create(client);
924 if (IS_ERR(p->conn)) {
925 err = PTR_ERR(p->conn);
926 p->conn = NULL;
927 goto error;
928 }
929
930 return 0;
931
932error:
933 if (csocket)
934 sock_release(csocket); 935 sock_release(csocket);
936 return err;
937 }
935 938
936 kfree(p); 939 return p9_socket_open(client, csocket);
937
938 return err;
939} 940}
940 941
941static int 942static int
@@ -944,49 +945,33 @@ p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
944 int err; 945 int err;
945 struct socket *csocket; 946 struct socket *csocket;
946 struct sockaddr_un sun_server; 947 struct sockaddr_un sun_server;
947 struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
948 948
949 csocket = NULL; 949 csocket = NULL;
950 950
951 if (strlen(addr) > UNIX_PATH_MAX) { 951 if (strlen(addr) > UNIX_PATH_MAX) {
952 P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", 952 P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
953 addr); 953 addr);
954 err = -ENAMETOOLONG; 954 return -ENAMETOOLONG;
955 goto error;
956 } 955 }
957 956
958 sun_server.sun_family = PF_UNIX; 957 sun_server.sun_family = PF_UNIX;
959 strcpy(sun_server.sun_path, addr); 958 strcpy(sun_server.sun_path, addr);
960 sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); 959 err = sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
960 if (err < 0) {
961 P9_EPRINTK(KERN_ERR, "p9_trans_unix: problem creating socket\n");
962 return err;
963 }
961 err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, 964 err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
962 sizeof(struct sockaddr_un) - 1, 0); 965 sizeof(struct sockaddr_un) - 1, 0);
963 if (err < 0) { 966 if (err < 0) {
964 P9_EPRINTK(KERN_ERR, 967 P9_EPRINTK(KERN_ERR,
965 "p9_trans_unix: problem connecting socket: %s: %d\n", 968 "p9_trans_unix: problem connecting socket: %s: %d\n",
966 addr, err); 969 addr, err);
967 goto error;
968 }
969
970 err = p9_socket_open(client, csocket);
971 if (err < 0)
972 goto error;
973
974 p = (struct p9_trans_fd *) client->trans;
975 p->conn = p9_conn_create(client);
976 if (IS_ERR(p->conn)) {
977 err = PTR_ERR(p->conn);
978 p->conn = NULL;
979 goto error;
980 }
981
982 return 0;
983
984error:
985 if (csocket)
986 sock_release(csocket); 970 sock_release(csocket);
971 return err;
972 }
987 973
988 kfree(p); 974 return p9_socket_open(client, csocket);
989 return err;
990} 975}
991 976
992static int 977static int
@@ -994,7 +979,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
994{ 979{
995 int err; 980 int err;
996 struct p9_fd_opts opts; 981 struct p9_fd_opts opts;
997 struct p9_trans_fd *p = NULL; /* this get allocated in p9_fd_open */ 982 struct p9_trans_fd *p;
998 983
999 parse_opts(args, &opts); 984 parse_opts(args, &opts);
1000 985
@@ -1005,21 +990,19 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
1005 990
1006 err = p9_fd_open(client, opts.rfd, opts.wfd); 991 err = p9_fd_open(client, opts.rfd, opts.wfd);
1007 if (err < 0) 992 if (err < 0)
1008 goto error; 993 return err;
1009 994
1010 p = (struct p9_trans_fd *) client->trans; 995 p = (struct p9_trans_fd *) client->trans;
1011 p->conn = p9_conn_create(client); 996 p->conn = p9_conn_create(client);
1012 if (IS_ERR(p->conn)) { 997 if (IS_ERR(p->conn)) {
1013 err = PTR_ERR(p->conn); 998 err = PTR_ERR(p->conn);
1014 p->conn = NULL; 999 p->conn = NULL;
1015 goto error; 1000 fput(p->rd);
1001 fput(p->wr);
1002 return err;
1016 } 1003 }
1017 1004
1018 return 0; 1005 return 0;
1019
1020error:
1021 kfree(p);
1022 return err;
1023} 1006}
1024 1007
1025static struct p9_trans_module p9_tcp_trans = { 1008static struct p9_trans_module p9_tcp_trans = {