diff options
| -rw-r--r-- | fs/9p/v9fs.c | 33 | ||||
| -rw-r--r-- | fs/9p/v9fs_vfs.h | 1 | ||||
| -rw-r--r-- | fs/9p/vfs_file.c | 19 | ||||
| -rw-r--r-- | fs/9p/vfs_inode.c | 2 | ||||
| -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 | 
8 files changed, 91 insertions, 40 deletions
| diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index cf62b05e296a..7d6c2139891d 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -84,7 +84,7 @@ static const match_table_t tokens = {  static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)  { -	char *options; +	char *options, *tmp_options;  	substring_t args[MAX_OPT_ARGS];  	char *p;  	int option = 0; @@ -102,9 +102,12 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)  	if (!opts)  		return 0; -	options = kstrdup(opts, GFP_KERNEL); -	if (!options) +	tmp_options = kstrdup(opts, GFP_KERNEL); +	if (!tmp_options) { +		ret = -ENOMEM;  		goto fail_option_alloc; +	} +	options = tmp_options;  	while ((p = strsep(&options, ",")) != NULL) {  		int token; @@ -159,8 +162,12 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)  			break;  		case Opt_cache:  			s = match_strdup(&args[0]); -			if (!s) -				goto fail_option_alloc; +			if (!s) { +				ret = -ENOMEM; +				P9_DPRINTK(P9_DEBUG_ERROR, +				  "problem allocating copy of cache arg\n"); +				goto free_and_return; +			}  			if (strcmp(s, "loose") == 0)  				v9ses->cache = CACHE_LOOSE; @@ -173,8 +180,12 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)  		case Opt_access:  			s = match_strdup(&args[0]); -			if (!s) -				goto fail_option_alloc; +			if (!s) { +				ret = -ENOMEM; +				P9_DPRINTK(P9_DEBUG_ERROR, +				  "problem allocating copy of access arg\n"); +				goto free_and_return; +			}  			v9ses->flags &= ~V9FS_ACCESS_MASK;  			if (strcmp(s, "user") == 0) @@ -194,13 +205,11 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)  			continue;  		}  	} -	kfree(options); -	return ret; +free_and_return: +	kfree(tmp_options);  fail_option_alloc: -	P9_DPRINTK(P9_DEBUG_ERROR, -		   "failed to allocate copy of option argument\n"); -	return -ENOMEM; +	return ret;  }  /** diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 3a7560e35865..ed835836e0dc 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h @@ -60,3 +60,4 @@ void v9fs_dentry_release(struct dentry *);  int v9fs_uflags2omode(int uflags, int extended);  ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64); +void v9fs_blank_wstat(struct p9_wstat *wstat); diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 3902bf43a088..74a0461a9ac0 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -257,6 +257,23 @@ v9fs_file_write(struct file *filp, const char __user * data,  	return total;  } +static int v9fs_file_fsync(struct file *filp, struct dentry *dentry, +					int datasync) +{ +	struct p9_fid *fid; +	struct p9_wstat wstat; +	int retval; + +	P9_DPRINTK(P9_DEBUG_VFS, "filp %p dentry %p datasync %x\n", filp, +						dentry, datasync); + +	fid = filp->private_data; +	v9fs_blank_wstat(&wstat); + +	retval = p9_client_wstat(fid, &wstat); +	return retval; +} +  static const struct file_operations v9fs_cached_file_operations = {  	.llseek = generic_file_llseek,  	.read = do_sync_read, @@ -266,6 +283,7 @@ static const struct file_operations v9fs_cached_file_operations = {  	.release = v9fs_dir_release,  	.lock = v9fs_file_lock,  	.mmap = generic_file_readonly_mmap, +	.fsync = v9fs_file_fsync,  };  const struct file_operations v9fs_file_operations = { @@ -276,4 +294,5 @@ const struct file_operations v9fs_file_operations = {  	.release = v9fs_dir_release,  	.lock = v9fs_file_lock,  	.mmap = generic_file_readonly_mmap, +	.fsync = v9fs_file_fsync,  }; diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 9d03d1ebca6f..a407fa3388c0 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -176,7 +176,7 @@ int v9fs_uflags2omode(int uflags, int extended)   *   */ -static void +void  v9fs_blank_wstat(struct p9_wstat *wstat)  {  	wstat->type = ~0; 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, ...);  static int parse_opts(char *opts, struct p9_client *clnt)  { -	char *options; +	char *options, *tmp_options;  	char *p;  	substring_t args[MAX_OPT_ARGS];  	int option; @@ -81,12 +81,13 @@ static int parse_opts(char *opts, struct p9_client *clnt)  	if (!opts)  		return 0; -	options = kstrdup(opts, GFP_KERNEL); -	if (!options) { +	tmp_options = kstrdup(opts, GFP_KERNEL); +	if (!tmp_options) {  		P9_DPRINTK(P9_DEBUG_ERROR,  				"failed to allocate copy of option string\n");  		return -ENOMEM;  	} +	options = tmp_options;  	while ((p = strsep(&options, ",")) != NULL) {  		int token; @@ -108,6 +109,13 @@ static int parse_opts(char *opts, struct p9_client *clnt)  			break;  		case Opt_trans:  			clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); +			if(clnt->trans_mod == NULL) { +				P9_DPRINTK(P9_DEBUG_ERROR, +				   "Could not find request transport: %s\n", +				   (char *) &args[0]); +				ret = -EINVAL; +				goto free_and_return; +			}  			break;  		case Opt_legacy:  			clnt->dotu = 0; @@ -117,7 +125,8 @@ static int parse_opts(char *opts, struct p9_client *clnt)  		}  	} -	kfree(options); +free_and_return: +	kfree(tmp_options);  	return ret;  } @@ -667,18 +676,12 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)  	clnt->trans = NULL;  	spin_lock_init(&clnt->lock);  	INIT_LIST_HEAD(&clnt->fidlist); -	clnt->fidpool = p9_idpool_create(); -	if (IS_ERR(clnt->fidpool)) { -		err = PTR_ERR(clnt->fidpool); -		clnt->fidpool = NULL; -		goto error; -	}  	p9_tag_init(clnt);  	err = parse_opts(options, clnt);  	if (err < 0) -		goto error; +		goto free_client;  	if (!clnt->trans_mod)  		clnt->trans_mod = v9fs_get_default_trans(); @@ -687,7 +690,14 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)  		err = -EPROTONOSUPPORT;  		P9_DPRINTK(P9_DEBUG_ERROR,  				"No transport defined or default transport\n"); -		goto error; +		goto free_client; +	} + +	clnt->fidpool = p9_idpool_create(); +	if (IS_ERR(clnt->fidpool)) { +		err = PTR_ERR(clnt->fidpool); +		clnt->fidpool = NULL; +		goto put_trans;  	}  	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)  	err = clnt->trans_mod->create(clnt, dev_name, options);  	if (err) -		goto error; +		goto destroy_fidpool;  	if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)  		clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;  	err = p9_client_version(clnt);  	if (err) -		goto error; +		goto close_trans;  	return clnt; -error: -	p9_client_destroy(clnt); +close_trans: +	clnt->trans_mod->close(clnt); +destroy_fidpool: +	p9_idpool_destroy(clnt->fidpool); +put_trans: +	v9fs_put_trans(clnt->trans_mod); +free_client: +	kfree(clnt);  	return ERR_PTR(err);  }  EXPORT_SYMBOL(p9_client_create); @@ -1214,10 +1230,11 @@ static int p9_client_statsize(struct p9_wstat *wst, int optional)  {  	int ret; +	/* NOTE: size shouldn't include its own length */  	/* size[2] type[2] dev[4] qid[13] */  	/* mode[4] atime[4] mtime[4] length[8]*/  	/* name[s] uid[s] gid[s] muid[s] */ -	ret = 2+2+4+13+4+4+4+8+2+2+2+2; +	ret = 2+4+13+4+4+4+8+2+2+2+2;  	if (wst->name)  		ret += strlen(wst->name); @@ -1258,7 +1275,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)  		wst->name, wst->uid, wst->gid, wst->muid, wst->extension,  		wst->n_uid, wst->n_gid, wst->n_muid); -	req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size, wst); +	req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);  	if (IS_ERR(req)) {  		err = PTR_ERR(req);  		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)  	char *p;  	substring_t args[MAX_OPT_ARGS];  	int option; -	char *options; +	char *options, *tmp_options;  	int ret;  	opts->port = P9_PORT; @@ -724,12 +724,13 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)  	if (!params)  		return 0; -	options = kstrdup(params, GFP_KERNEL); -	if (!options) { +	tmp_options = kstrdup(params, GFP_KERNEL); +	if (!tmp_options) {  		P9_DPRINTK(P9_DEBUG_ERROR,  				"failed to allocate copy of option string\n");  		return -ENOMEM;  	} +	options = tmp_options;  	while ((p = strsep(&options, ",")) != NULL) {  		int token; @@ -760,7 +761,8 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)  			continue;  		}  	} -	kfree(options); + +	kfree(tmp_options);  	return 0;  } 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)  	char *p;  	substring_t args[MAX_OPT_ARGS];  	int option; -	char *options; +	char *options, *tmp_options;  	int ret;  	opts->port = P9_PORT; @@ -177,12 +177,13 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)  	if (!params)  		return 0; -	options = kstrdup(params, GFP_KERNEL); -	if (!options) { +	tmp_options = kstrdup(params, GFP_KERNEL); +	if (!tmp_options) {  		P9_DPRINTK(P9_DEBUG_ERROR,  			   "failed to allocate copy of option string\n");  		return -ENOMEM;  	} +	options = tmp_options;  	while ((p = strsep(&options, ",")) != NULL) {  		int token; @@ -216,7 +217,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)  	}  	/* RQ must be at least as large as the SQ */  	opts->rq_depth = max(opts->rq_depth, opts->sq_depth); -	kfree(options); +	kfree(tmp_options);  	return 0;  } 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)  	struct virtio_chan *chan = client->trans;  	mutex_lock(&virtio_9p_lock); -	chan->inuse = false; +	if (chan) +		chan->inuse = false;  	mutex_unlock(&virtio_9p_lock);  } @@ -311,6 +312,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)  	}  	client->trans = (void *)chan; +	client->status = Connected;  	chan->client = client;  	return 0; | 
