diff options
Diffstat (limited to 'fs/9p/v9fs.c')
| -rw-r--r-- | fs/9p/v9fs.c | 57 | 
1 files changed, 44 insertions, 13 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 9b0f0222e8bb..047c791427aa 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c  | |||
| @@ -71,19 +71,19 @@ static match_table_t tokens = { | |||
| 71 | 71 | ||
| 72 | /** | 72 | /** | 
| 73 | * v9fs_parse_options - parse mount options into session structure | 73 | * v9fs_parse_options - parse mount options into session structure | 
| 74 | * @options: options string passed from mount | ||
| 75 | * @v9ses: existing v9fs session information | 74 | * @v9ses: existing v9fs session information | 
| 76 | * | 75 | * | 
| 76 | * Return 0 upon success, -ERRNO upon failure. | ||
| 77 | */ | 77 | */ | 
| 78 | 78 | ||
| 79 | static void v9fs_parse_options(struct v9fs_session_info *v9ses) | 79 | static int v9fs_parse_options(struct v9fs_session_info *v9ses) | 
| 80 | { | 80 | { | 
| 81 | char *options; | 81 | char *options; | 
| 82 | substring_t args[MAX_OPT_ARGS]; | 82 | substring_t args[MAX_OPT_ARGS]; | 
| 83 | char *p; | 83 | char *p; | 
| 84 | int option = 0; | 84 | int option = 0; | 
| 85 | char *s, *e; | 85 | char *s, *e; | 
| 86 | int ret; | 86 | int ret = 0; | 
| 87 | 87 | ||
| 88 | /* setup defaults */ | 88 | /* setup defaults */ | 
| 89 | v9ses->afid = ~0; | 89 | v9ses->afid = ~0; | 
| @@ -91,19 +91,26 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
| 91 | v9ses->cache = 0; | 91 | v9ses->cache = 0; | 
| 92 | 92 | ||
| 93 | if (!v9ses->options) | 93 | if (!v9ses->options) | 
| 94 | return; | 94 | return 0; | 
| 95 | 95 | ||
| 96 | options = kstrdup(v9ses->options, GFP_KERNEL); | 96 | options = kstrdup(v9ses->options, GFP_KERNEL); | 
| 97 | if (!options) { | ||
| 98 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 99 | "failed to allocate copy of option string\n"); | ||
| 100 | return -ENOMEM; | ||
| 101 | } | ||
| 102 | |||
| 97 | while ((p = strsep(&options, ",")) != NULL) { | 103 | while ((p = strsep(&options, ",")) != NULL) { | 
| 98 | int token; | 104 | int token; | 
| 99 | if (!*p) | 105 | if (!*p) | 
| 100 | continue; | 106 | continue; | 
| 101 | token = match_token(p, tokens, args); | 107 | token = match_token(p, tokens, args); | 
| 102 | if (token < Opt_uname) { | 108 | if (token < Opt_uname) { | 
| 103 | ret = match_int(&args[0], &option); | 109 | int r = match_int(&args[0], &option); | 
| 104 | if (ret < 0) { | 110 | if (r < 0) { | 
| 105 | P9_DPRINTK(P9_DEBUG_ERROR, | 111 | P9_DPRINTK(P9_DEBUG_ERROR, | 
| 106 | "integer field, but no integer?\n"); | 112 | "integer field, but no integer?\n"); | 
| 113 | ret = r; | ||
| 107 | continue; | 114 | continue; | 
| 108 | } | 115 | } | 
| 109 | } | 116 | } | 
| @@ -125,10 +132,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
| 125 | v9ses->afid = option; | 132 | v9ses->afid = option; | 
| 126 | break; | 133 | break; | 
| 127 | case Opt_uname: | 134 | case Opt_uname: | 
| 128 | match_strcpy(v9ses->uname, &args[0]); | 135 | match_strlcpy(v9ses->uname, &args[0], PATH_MAX); | 
| 129 | break; | 136 | break; | 
| 130 | case Opt_remotename: | 137 | case Opt_remotename: | 
| 131 | match_strcpy(v9ses->aname, &args[0]); | 138 | match_strlcpy(v9ses->aname, &args[0], PATH_MAX); | 
| 132 | break; | 139 | break; | 
| 133 | case Opt_nodevmap: | 140 | case Opt_nodevmap: | 
| 134 | v9ses->nodev = 1; | 141 | v9ses->nodev = 1; | 
| @@ -139,6 +146,13 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
| 139 | 146 | ||
| 140 | case Opt_access: | 147 | case Opt_access: | 
| 141 | s = match_strdup(&args[0]); | 148 | s = match_strdup(&args[0]); | 
| 149 | if (!s) { | ||
| 150 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 151 | "failed to allocate copy" | ||
| 152 | " of option argument\n"); | ||
| 153 | ret = -ENOMEM; | ||
| 154 | break; | ||
| 155 | } | ||
| 142 | v9ses->flags &= ~V9FS_ACCESS_MASK; | 156 | v9ses->flags &= ~V9FS_ACCESS_MASK; | 
| 143 | if (strcmp(s, "user") == 0) | 157 | if (strcmp(s, "user") == 0) | 
| 144 | v9ses->flags |= V9FS_ACCESS_USER; | 158 | v9ses->flags |= V9FS_ACCESS_USER; | 
| @@ -158,6 +172,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
| 158 | } | 172 | } | 
| 159 | } | 173 | } | 
| 160 | kfree(options); | 174 | kfree(options); | 
| 175 | return ret; | ||
| 161 | } | 176 | } | 
| 162 | 177 | ||
| 163 | /** | 178 | /** | 
| @@ -173,6 +188,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
| 173 | { | 188 | { | 
| 174 | int retval = -EINVAL; | 189 | int retval = -EINVAL; | 
| 175 | struct p9_fid *fid; | 190 | struct p9_fid *fid; | 
| 191 | int rc; | ||
| 176 | 192 | ||
| 177 | v9ses->uname = __getname(); | 193 | v9ses->uname = __getname(); | 
| 178 | if (!v9ses->uname) | 194 | if (!v9ses->uname) | 
| @@ -190,8 +206,21 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
| 190 | v9ses->uid = ~0; | 206 | v9ses->uid = ~0; | 
| 191 | v9ses->dfltuid = V9FS_DEFUID; | 207 | v9ses->dfltuid = V9FS_DEFUID; | 
| 192 | v9ses->dfltgid = V9FS_DEFGID; | 208 | v9ses->dfltgid = V9FS_DEFGID; | 
| 193 | v9ses->options = kstrdup(data, GFP_KERNEL); | 209 | if (data) { | 
| 194 | v9fs_parse_options(v9ses); | 210 | v9ses->options = kstrdup(data, GFP_KERNEL); | 
| 211 | if (!v9ses->options) { | ||
| 212 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 213 | "failed to allocate copy of option string\n"); | ||
| 214 | retval = -ENOMEM; | ||
| 215 | goto error; | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | rc = v9fs_parse_options(v9ses); | ||
| 220 | if (rc < 0) { | ||
| 221 | retval = rc; | ||
| 222 | goto error; | ||
| 223 | } | ||
| 195 | 224 | ||
| 196 | v9ses->clnt = p9_client_create(dev_name, v9ses->options); | 225 | v9ses->clnt = p9_client_create(dev_name, v9ses->options); | 
| 197 | 226 | ||
| @@ -233,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
| 233 | return fid; | 262 | return fid; | 
| 234 | 263 | ||
| 235 | error: | 264 | error: | 
| 236 | v9fs_session_close(v9ses); | ||
| 237 | return ERR_PTR(retval); | 265 | return ERR_PTR(retval); | 
| 238 | } | 266 | } | 
| 239 | 267 | ||
| @@ -256,9 +284,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
| 256 | } | 284 | } | 
| 257 | 285 | ||
| 258 | /** | 286 | /** | 
| 259 | * v9fs_session_cancel - mark transport as disconnected | 287 | * v9fs_session_cancel - terminate a session | 
| 260 | * and cancel all pending requests. | 288 | * @v9ses: session to terminate | 
| 289 | * | ||
| 290 | * mark transport as disconnected and cancel all pending requests. | ||
| 261 | */ | 291 | */ | 
| 292 | |||
| 262 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | 293 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | 
| 263 | P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); | 294 | P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); | 
| 264 | p9_client_disconnect(v9ses->clnt); | 295 | p9_client_disconnect(v9ses->clnt); | 
