diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-11 14:36:25 +0100 | 
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-11 14:36:25 +0100 | 
| commit | a8931ef380c92d121ae74ecfb03b2d63f72eea6f (patch) | |
| tree | 980fb6b019e11e6cb1ece55b7faff184721a8053 /fs/9p/v9fs.c | |
| parent | 90574d0a4d4b73308ae54a2a57a4f3f1fa98e984 (diff) | |
| parent | e5a5816f7875207cb0a0a7032e39a4686c5e10a4 (diff) | |
| download | olio-linux-3.10-a8931ef380c92d121ae74ecfb03b2d63f72eea6f.tar.xz olio-linux-3.10-a8931ef380c92d121ae74ecfb03b2d63f72eea6f.zip  | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
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 9b0f0222e8b..047c791427a 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -71,19 +71,19 @@ static match_table_t tokens = {  /**   * v9fs_parse_options - parse mount options into session structure - * @options: options string passed from mount   * @v9ses: existing v9fs session information   * + * Return 0 upon success, -ERRNO upon failure.   */ -static void v9fs_parse_options(struct v9fs_session_info *v9ses) +static int v9fs_parse_options(struct v9fs_session_info *v9ses)  {  	char *options;  	substring_t args[MAX_OPT_ARGS];  	char *p;  	int option = 0;  	char *s, *e; -	int ret; +	int ret = 0;  	/* setup defaults */  	v9ses->afid = ~0; @@ -91,19 +91,26 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)  	v9ses->cache = 0;  	if (!v9ses->options) -		return; +		return 0;  	options = kstrdup(v9ses->options, GFP_KERNEL); +	if (!options) { +		P9_DPRINTK(P9_DEBUG_ERROR, +			   "failed to allocate copy of option string\n"); +		return -ENOMEM; +	} +  	while ((p = strsep(&options, ",")) != NULL) {  		int token;  		if (!*p)  			continue;  		token = match_token(p, tokens, args);  		if (token < Opt_uname) { -			ret = match_int(&args[0], &option); -			if (ret < 0) { +			int r = match_int(&args[0], &option); +			if (r < 0) {  				P9_DPRINTK(P9_DEBUG_ERROR,  					"integer field, but no integer?\n"); +				ret = r;  				continue;  			}  		} @@ -125,10 +132,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)  			v9ses->afid = option;  			break;  		case Opt_uname: -			match_strcpy(v9ses->uname, &args[0]); +			match_strlcpy(v9ses->uname, &args[0], PATH_MAX);  			break;  		case Opt_remotename: -			match_strcpy(v9ses->aname, &args[0]); +			match_strlcpy(v9ses->aname, &args[0], PATH_MAX);  			break;  		case Opt_nodevmap:  			v9ses->nodev = 1; @@ -139,6 +146,13 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)  		case Opt_access:  			s = match_strdup(&args[0]); +			if (!s) { +				P9_DPRINTK(P9_DEBUG_ERROR, +					   "failed to allocate copy" +					   " of option argument\n"); +				ret = -ENOMEM; +				break; +			}  			v9ses->flags &= ~V9FS_ACCESS_MASK;  			if (strcmp(s, "user") == 0)  				v9ses->flags |= V9FS_ACCESS_USER; @@ -158,6 +172,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)  		}  	}  	kfree(options); +	return ret;  }  /** @@ -173,6 +188,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,  {  	int retval = -EINVAL;  	struct p9_fid *fid; +	int rc;  	v9ses->uname = __getname();  	if (!v9ses->uname) @@ -190,8 +206,21 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,  	v9ses->uid = ~0;  	v9ses->dfltuid = V9FS_DEFUID;  	v9ses->dfltgid = V9FS_DEFGID; -	v9ses->options = kstrdup(data, GFP_KERNEL); -	v9fs_parse_options(v9ses); +	if (data) { +		v9ses->options = kstrdup(data, GFP_KERNEL); +		if (!v9ses->options) { +			P9_DPRINTK(P9_DEBUG_ERROR, +			   "failed to allocate copy of option string\n"); +			retval = -ENOMEM; +			goto error; +		} +	} + +	rc = v9fs_parse_options(v9ses); +	if (rc < 0) { +		retval = rc; +		goto error; +	}  	v9ses->clnt = p9_client_create(dev_name, v9ses->options); @@ -233,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,  	return fid;  error: -	v9fs_session_close(v9ses);  	return ERR_PTR(retval);  } @@ -256,9 +284,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)  }  /** - * v9fs_session_cancel - mark transport as disconnected - * 	and cancel all pending requests. + * v9fs_session_cancel - terminate a session + * @v9ses: session to terminate + * + * mark transport as disconnected and cancel all pending requests.   */ +  void v9fs_session_cancel(struct v9fs_session_info *v9ses) {  	P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);  	p9_client_disconnect(v9ses->clnt);  |