diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-09 14:19:06 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-09 14:19:06 -0500 |
| commit | 3af9cf11b6efb82aa7a1a24e2382b75d43631c4e (patch) | |
| tree | 506a491c1f46f20a07da2ff16603259427bec79d /net | |
| parent | deb0c98c7f6035d47a247e548384517a955314a5 (diff) | |
| parent | 8781ff9495578dbb74065fae55305110d9f81cb9 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
9p: fix p9_client_destroy unconditional calling v9fs_put_trans
9p: fix memory leak in v9fs_parse_options()
9p: Fix the kernel crash on a failed mount
9p: fix option parsing
9p: Include fsync support for 9p client
net/9p: fix statsize inside twstat
net/9p: fail when user specifies a transport which we can't find
net/9p: fix virtio transport to correctly update status on connect
Diffstat (limited to 'net')
| -rw-r--r-- | net/9p/client.c | 53 | ||||
| -rw-r--r-- | net/9p/trans_fd.c | 10 | ||||
| -rw-r--r-- | net/9p/trans_rdma.c | 9 | ||||
| -rw-r--r-- | net/9p/trans_virtio.c | 4 |
4 files changed, 49 insertions, 27 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 8af95b2dddd6..09d4f1e2e4a8 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -69,7 +69,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); | |||
| 69 | 69 | ||
| 70 | static int parse_opts(char *opts, struct p9_client *clnt) | 70 | static int parse_opts(char *opts, struct p9_client *clnt) |
| 71 | { | 71 | { |
| 72 | char *options; | 72 | char *options, *tmp_options; |
| 73 | char *p; | 73 | char *p; |
| 74 | substring_t args[MAX_OPT_ARGS]; | 74 | substring_t args[MAX_OPT_ARGS]; |
| 75 | int option; | 75 | int option; |
| @@ -81,12 +81,13 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
| 81 | if (!opts) | 81 | if (!opts) |
| 82 | return 0; | 82 | return 0; |
| 83 | 83 | ||
| 84 | options = kstrdup(opts, GFP_KERNEL); | 84 | tmp_options = kstrdup(opts, GFP_KERNEL); |
| 85 | if (!options) { | 85 | if (!tmp_options) { |
| 86 | P9_DPRINTK(P9_DEBUG_ERROR, | 86 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 87 | "failed to allocate copy of option string\n"); | 87 | "failed to allocate copy of option string\n"); |
| 88 | return -ENOMEM; | 88 | return -ENOMEM; |
| 89 | } | 89 | } |
| 90 | options = tmp_options; | ||
| 90 | 91 | ||
| 91 | while ((p = strsep(&options, ",")) != NULL) { | 92 | while ((p = strsep(&options, ",")) != NULL) { |
| 92 | int token; | 93 | int token; |
| @@ -108,6 +109,13 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
| 108 | break; | 109 | break; |
| 109 | case Opt_trans: | 110 | case Opt_trans: |
| 110 | clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); | 111 | clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); |
| 112 | if(clnt->trans_mod == NULL) { | ||
| 113 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 114 | "Could not find request transport: %s\n", | ||
| 115 | (char *) &args[0]); | ||
| 116 | ret = -EINVAL; | ||
| 117 | goto free_and_return; | ||
| 118 | } | ||
| 111 | break; | 119 | break; |
| 112 | case Opt_legacy: | 120 | case Opt_legacy: |
| 113 | clnt->dotu = 0; | 121 | clnt->dotu = 0; |
| @@ -117,7 +125,8 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
| 117 | } | 125 | } |
| 118 | } | 126 | } |
| 119 | 127 | ||
| 120 | kfree(options); | 128 | free_and_return: |
| 129 | kfree(tmp_options); | ||
| 121 | return ret; | 130 | return ret; |
| 122 | } | 131 | } |
| 123 | 132 | ||
| @@ -667,18 +676,12 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | |||
| 667 | clnt->trans = NULL; | 676 | clnt->trans = NULL; |
| 668 | spin_lock_init(&clnt->lock); | 677 | spin_lock_init(&clnt->lock); |
| 669 | INIT_LIST_HEAD(&clnt->fidlist); | 678 | INIT_LIST_HEAD(&clnt->fidlist); |
| 670 | clnt->fidpool = p9_idpool_create(); | ||
| 671 | if (IS_ERR(clnt->fidpool)) { | ||
| 672 | err = PTR_ERR(clnt->fidpool); | ||
| 673 | clnt->fidpool = NULL; | ||
| 674 | goto error; | ||
| 675 | } | ||
| 676 | 679 | ||
| 677 | p9_tag_init(clnt); | 680 | p9_tag_init(clnt); |
| 678 | 681 | ||
| 679 | err = parse_opts(options, clnt); | 682 | err = parse_opts(options, clnt); |
| 680 | if (err < 0) | 683 | if (err < 0) |
| 681 | goto error; | 684 | goto free_client; |
| 682 | 685 | ||
| 683 | if (!clnt->trans_mod) | 686 | if (!clnt->trans_mod) |
| 684 | clnt->trans_mod = v9fs_get_default_trans(); | 687 | clnt->trans_mod = v9fs_get_default_trans(); |
| @@ -687,7 +690,14 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | |||
| 687 | err = -EPROTONOSUPPORT; | 690 | err = -EPROTONOSUPPORT; |
| 688 | P9_DPRINTK(P9_DEBUG_ERROR, | 691 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 689 | "No transport defined or default transport\n"); | 692 | "No transport defined or default transport\n"); |
| 690 | goto error; | 693 | goto free_client; |
| 694 | } | ||
| 695 | |||
| 696 | clnt->fidpool = p9_idpool_create(); | ||
| 697 | if (IS_ERR(clnt->fidpool)) { | ||
| 698 | err = PTR_ERR(clnt->fidpool); | ||
| 699 | clnt->fidpool = NULL; | ||
| 700 | goto put_trans; | ||
| 691 | } | 701 | } |
| 692 | 702 | ||
| 693 | P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n", | 703 | P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n", |
| @@ -695,19 +705,25 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | |||
| 695 | 705 | ||
| 696 | err = clnt->trans_mod->create(clnt, dev_name, options); | 706 | err = clnt->trans_mod->create(clnt, dev_name, options); |
| 697 | if (err) | 707 | if (err) |
| 698 | goto error; | 708 | goto destroy_fidpool; |
| 699 | 709 | ||
| 700 | if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) | 710 | if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) |
| 701 | clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; | 711 | clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; |
| 702 | 712 | ||
| 703 | err = p9_client_version(clnt); | 713 | err = p9_client_version(clnt); |
| 704 | if (err) | 714 | if (err) |
| 705 | goto error; | 715 | goto close_trans; |
| 706 | 716 | ||
| 707 | return clnt; | 717 | return clnt; |
| 708 | 718 | ||
| 709 | error: | 719 | close_trans: |
| 710 | p9_client_destroy(clnt); | 720 | clnt->trans_mod->close(clnt); |
| 721 | destroy_fidpool: | ||
| 722 | p9_idpool_destroy(clnt->fidpool); | ||
| 723 | put_trans: | ||
| 724 | v9fs_put_trans(clnt->trans_mod); | ||
| 725 | free_client: | ||
| 726 | kfree(clnt); | ||
| 711 | return ERR_PTR(err); | 727 | return ERR_PTR(err); |
| 712 | } | 728 | } |
| 713 | EXPORT_SYMBOL(p9_client_create); | 729 | EXPORT_SYMBOL(p9_client_create); |
| @@ -1214,10 +1230,11 @@ static int p9_client_statsize(struct p9_wstat *wst, int optional) | |||
| 1214 | { | 1230 | { |
| 1215 | int ret; | 1231 | int ret; |
| 1216 | 1232 | ||
| 1233 | /* NOTE: size shouldn't include its own length */ | ||
| 1217 | /* size[2] type[2] dev[4] qid[13] */ | 1234 | /* size[2] type[2] dev[4] qid[13] */ |
| 1218 | /* mode[4] atime[4] mtime[4] length[8]*/ | 1235 | /* mode[4] atime[4] mtime[4] length[8]*/ |
| 1219 | /* name[s] uid[s] gid[s] muid[s] */ | 1236 | /* name[s] uid[s] gid[s] muid[s] */ |
| 1220 | ret = 2+2+4+13+4+4+4+8+2+2+2+2; | 1237 | ret = 2+4+13+4+4+4+8+2+2+2+2; |
| 1221 | 1238 | ||
| 1222 | if (wst->name) | 1239 | if (wst->name) |
| 1223 | ret += strlen(wst->name); | 1240 | ret += strlen(wst->name); |
| @@ -1258,7 +1275,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | |||
| 1258 | wst->name, wst->uid, wst->gid, wst->muid, wst->extension, | 1275 | wst->name, wst->uid, wst->gid, wst->muid, wst->extension, |
| 1259 | wst->n_uid, wst->n_gid, wst->n_muid); | 1276 | wst->n_uid, wst->n_gid, wst->n_muid); |
| 1260 | 1277 | ||
| 1261 | req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size, wst); | 1278 | req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst); |
| 1262 | if (IS_ERR(req)) { | 1279 | if (IS_ERR(req)) { |
| 1263 | err = PTR_ERR(req); | 1280 | err = PTR_ERR(req); |
| 1264 | goto error; | 1281 | goto error; |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index be1cb909d8c0..31d0b05582a9 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
| @@ -714,7 +714,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
| 714 | char *p; | 714 | char *p; |
| 715 | substring_t args[MAX_OPT_ARGS]; | 715 | substring_t args[MAX_OPT_ARGS]; |
| 716 | int option; | 716 | int option; |
| 717 | char *options; | 717 | char *options, *tmp_options; |
| 718 | int ret; | 718 | int ret; |
| 719 | 719 | ||
| 720 | opts->port = P9_PORT; | 720 | opts->port = P9_PORT; |
| @@ -724,12 +724,13 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
| 724 | if (!params) | 724 | if (!params) |
| 725 | return 0; | 725 | return 0; |
| 726 | 726 | ||
| 727 | options = kstrdup(params, GFP_KERNEL); | 727 | tmp_options = kstrdup(params, GFP_KERNEL); |
| 728 | if (!options) { | 728 | if (!tmp_options) { |
| 729 | P9_DPRINTK(P9_DEBUG_ERROR, | 729 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 730 | "failed to allocate copy of option string\n"); | 730 | "failed to allocate copy of option string\n"); |
| 731 | return -ENOMEM; | 731 | return -ENOMEM; |
| 732 | } | 732 | } |
| 733 | options = tmp_options; | ||
| 733 | 734 | ||
| 734 | while ((p = strsep(&options, ",")) != NULL) { | 735 | while ((p = strsep(&options, ",")) != NULL) { |
| 735 | int token; | 736 | int token; |
| @@ -760,7 +761,8 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
| 760 | continue; | 761 | continue; |
| 761 | } | 762 | } |
| 762 | } | 763 | } |
| 763 | kfree(options); | 764 | |
| 765 | kfree(tmp_options); | ||
| 764 | return 0; | 766 | return 0; |
| 765 | } | 767 | } |
| 766 | 768 | ||
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 65cb29db03f8..2c95a89c0f46 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
| @@ -166,7 +166,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 166 | char *p; | 166 | char *p; |
| 167 | substring_t args[MAX_OPT_ARGS]; | 167 | substring_t args[MAX_OPT_ARGS]; |
| 168 | int option; | 168 | int option; |
| 169 | char *options; | 169 | char *options, *tmp_options; |
| 170 | int ret; | 170 | int ret; |
| 171 | 171 | ||
| 172 | opts->port = P9_PORT; | 172 | opts->port = P9_PORT; |
| @@ -177,12 +177,13 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 177 | if (!params) | 177 | if (!params) |
| 178 | return 0; | 178 | return 0; |
| 179 | 179 | ||
| 180 | options = kstrdup(params, GFP_KERNEL); | 180 | tmp_options = kstrdup(params, GFP_KERNEL); |
| 181 | if (!options) { | 181 | if (!tmp_options) { |
| 182 | P9_DPRINTK(P9_DEBUG_ERROR, | 182 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 183 | "failed to allocate copy of option string\n"); | 183 | "failed to allocate copy of option string\n"); |
| 184 | return -ENOMEM; | 184 | return -ENOMEM; |
| 185 | } | 185 | } |
| 186 | options = tmp_options; | ||
| 186 | 187 | ||
| 187 | while ((p = strsep(&options, ",")) != NULL) { | 188 | while ((p = strsep(&options, ",")) != NULL) { |
| 188 | int token; | 189 | int token; |
| @@ -216,7 +217,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 216 | } | 217 | } |
| 217 | /* RQ must be at least as large as the SQ */ | 218 | /* RQ must be at least as large as the SQ */ |
| 218 | opts->rq_depth = max(opts->rq_depth, opts->sq_depth); | 219 | opts->rq_depth = max(opts->rq_depth, opts->sq_depth); |
| 219 | kfree(options); | 220 | kfree(tmp_options); |
| 220 | return 0; | 221 | return 0; |
| 221 | } | 222 | } |
| 222 | 223 | ||
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index ea1e3daabefe..cb50f4ae5eef 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -102,7 +102,8 @@ static void p9_virtio_close(struct p9_client *client) | |||
| 102 | struct virtio_chan *chan = client->trans; | 102 | struct virtio_chan *chan = client->trans; |
| 103 | 103 | ||
| 104 | mutex_lock(&virtio_9p_lock); | 104 | mutex_lock(&virtio_9p_lock); |
| 105 | chan->inuse = false; | 105 | if (chan) |
| 106 | chan->inuse = false; | ||
| 106 | mutex_unlock(&virtio_9p_lock); | 107 | mutex_unlock(&virtio_9p_lock); |
| 107 | } | 108 | } |
| 108 | 109 | ||
| @@ -311,6 +312,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) | |||
| 311 | } | 312 | } |
| 312 | 313 | ||
| 313 | client->trans = (void *)chan; | 314 | client->trans = (void *)chan; |
| 315 | client->status = Connected; | ||
| 314 | chan->client = client; | 316 | chan->client = client; |
| 315 | 317 | ||
| 316 | return 0; | 318 | return 0; |
