aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/cache.c20
-rw-r--r--fs/9p/cache.h9
-rw-r--r--fs/9p/v9fs.c45
-rw-r--r--fs/9p/v9fs.h29
-rw-r--r--fs/9p/vfs_inode.c118
-rw-r--r--fs/9p/vfs_inode_dotl.c67
-rw-r--r--include/net/9p/9p.h193
-rw-r--r--include/net/9p/client.h12
-rw-r--r--include/net/9p/transport.h2
-rw-r--r--net/9p/client.c155
-rw-r--r--net/9p/mod.c4
-rw-r--r--net/9p/protocol.c44
-rw-r--r--net/9p/trans_virtio.c4
13 files changed, 370 insertions, 332 deletions
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index 5b335c5086a1..945aa5f02f9b 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -108,11 +108,10 @@ static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data,
108 void *buffer, uint16_t bufmax) 108 void *buffer, uint16_t bufmax)
109{ 109{
110 const struct v9fs_inode *v9inode = cookie_netfs_data; 110 const struct v9fs_inode *v9inode = cookie_netfs_data;
111 memcpy(buffer, &v9inode->fscache_key->path, 111 memcpy(buffer, &v9inode->qid.path, sizeof(v9inode->qid.path));
112 sizeof(v9inode->fscache_key->path));
113 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get key %llu", &v9inode->vfs_inode, 112 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get key %llu", &v9inode->vfs_inode,
114 v9inode->fscache_key->path); 113 v9inode->qid.path);
115 return sizeof(v9inode->fscache_key->path); 114 return sizeof(v9inode->qid.path);
116} 115}
117 116
118static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data, 117static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
@@ -129,11 +128,10 @@ static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data,
129 void *buffer, uint16_t buflen) 128 void *buffer, uint16_t buflen)
130{ 129{
131 const struct v9fs_inode *v9inode = cookie_netfs_data; 130 const struct v9fs_inode *v9inode = cookie_netfs_data;
132 memcpy(buffer, &v9inode->fscache_key->version, 131 memcpy(buffer, &v9inode->qid.version, sizeof(v9inode->qid.version));
133 sizeof(v9inode->fscache_key->version));
134 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get aux %u", &v9inode->vfs_inode, 132 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get aux %u", &v9inode->vfs_inode,
135 v9inode->fscache_key->version); 133 v9inode->qid.version);
136 return sizeof(v9inode->fscache_key->version); 134 return sizeof(v9inode->qid.version);
137} 135}
138 136
139static enum 137static enum
@@ -143,11 +141,11 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
143{ 141{
144 const struct v9fs_inode *v9inode = cookie_netfs_data; 142 const struct v9fs_inode *v9inode = cookie_netfs_data;
145 143
146 if (buflen != sizeof(v9inode->fscache_key->version)) 144 if (buflen != sizeof(v9inode->qid.version))
147 return FSCACHE_CHECKAUX_OBSOLETE; 145 return FSCACHE_CHECKAUX_OBSOLETE;
148 146
149 if (memcmp(buffer, &v9inode->fscache_key->version, 147 if (memcmp(buffer, &v9inode->qid.version,
150 sizeof(v9inode->fscache_key->version))) 148 sizeof(v9inode->qid.version)))
151 return FSCACHE_CHECKAUX_OBSOLETE; 149 return FSCACHE_CHECKAUX_OBSOLETE;
152 150
153 return FSCACHE_CHECKAUX_OKAY; 151 return FSCACHE_CHECKAUX_OKAY;
diff --git a/fs/9p/cache.h b/fs/9p/cache.h
index 049507a5b01c..40cc54ced5d9 100644
--- a/fs/9p/cache.h
+++ b/fs/9p/cache.h
@@ -93,15 +93,6 @@ static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
93 BUG_ON(PageFsCache(page)); 93 BUG_ON(PageFsCache(page));
94} 94}
95 95
96static inline void v9fs_fscache_set_key(struct inode *inode,
97 struct p9_qid *qid)
98{
99 struct v9fs_inode *v9inode = V9FS_I(inode);
100 spin_lock(&v9inode->fscache_lock);
101 v9inode->fscache_key = qid;
102 spin_unlock(&v9inode->fscache_lock);
103}
104
105static inline void v9fs_fscache_wait_on_page_write(struct inode *inode, 96static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
106 struct page *page) 97 struct page *page)
107{ 98{
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index c82b017f51f3..ef9661886112 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -78,6 +78,25 @@ static const match_table_t tokens = {
78 {Opt_err, NULL} 78 {Opt_err, NULL}
79}; 79};
80 80
81/* Interpret mount options for cache mode */
82static int get_cache_mode(char *s)
83{
84 int version = -EINVAL;
85
86 if (!strcmp(s, "loose")) {
87 version = CACHE_LOOSE;
88 P9_DPRINTK(P9_DEBUG_9P, "Cache mode: loose\n");
89 } else if (!strcmp(s, "fscache")) {
90 version = CACHE_FSCACHE;
91 P9_DPRINTK(P9_DEBUG_9P, "Cache mode: fscache\n");
92 } else if (!strcmp(s, "none")) {
93 version = CACHE_NONE;
94 P9_DPRINTK(P9_DEBUG_9P, "Cache mode: none\n");
95 } else
96 printk(KERN_INFO "9p: Unknown Cache mode %s.\n", s);
97 return version;
98}
99
81/** 100/**
82 * v9fs_parse_options - parse mount options into session structure 101 * v9fs_parse_options - parse mount options into session structure
83 * @v9ses: existing v9fs session information 102 * @v9ses: existing v9fs session information
@@ -97,7 +116,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
97 /* setup defaults */ 116 /* setup defaults */
98 v9ses->afid = ~0; 117 v9ses->afid = ~0;
99 v9ses->debug = 0; 118 v9ses->debug = 0;
100 v9ses->cache = 0; 119 v9ses->cache = CACHE_NONE;
101#ifdef CONFIG_9P_FSCACHE 120#ifdef CONFIG_9P_FSCACHE
102 v9ses->cachetag = NULL; 121 v9ses->cachetag = NULL;
103#endif 122#endif
@@ -171,13 +190,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
171 "problem allocating copy of cache arg\n"); 190 "problem allocating copy of cache arg\n");
172 goto free_and_return; 191 goto free_and_return;
173 } 192 }
193 ret = get_cache_mode(s);
194 if (ret == -EINVAL) {
195 kfree(s);
196 goto free_and_return;
197 }
174 198
175 if (strcmp(s, "loose") == 0) 199 v9ses->cache = ret;
176 v9ses->cache = CACHE_LOOSE;
177 else if (strcmp(s, "fscache") == 0)
178 v9ses->cache = CACHE_FSCACHE;
179 else
180 v9ses->cache = CACHE_NONE;
181 kfree(s); 200 kfree(s);
182 break; 201 break;
183 202
@@ -200,9 +219,15 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
200 } else { 219 } else {
201 v9ses->flags |= V9FS_ACCESS_SINGLE; 220 v9ses->flags |= V9FS_ACCESS_SINGLE;
202 v9ses->uid = simple_strtoul(s, &e, 10); 221 v9ses->uid = simple_strtoul(s, &e, 10);
203 if (*e != '\0') 222 if (*e != '\0') {
204 v9ses->uid = ~0; 223 ret = -EINVAL;
224 printk(KERN_INFO "9p: Unknown access "
225 "argument %s.\n", s);
226 kfree(s);
227 goto free_and_return;
228 }
205 } 229 }
230
206 kfree(s); 231 kfree(s);
207 break; 232 break;
208 233
@@ -487,8 +512,8 @@ static void v9fs_inode_init_once(void *foo)
487 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo; 512 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
488#ifdef CONFIG_9P_FSCACHE 513#ifdef CONFIG_9P_FSCACHE
489 v9inode->fscache = NULL; 514 v9inode->fscache = NULL;
490 v9inode->fscache_key = NULL;
491#endif 515#endif
516 memset(&v9inode->qid, 0, sizeof(v9inode->qid));
492 inode_init_once(&v9inode->vfs_inode); 517 inode_init_once(&v9inode->vfs_inode);
493} 518}
494 519
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index e5ebedfc5ed8..e78956cbd702 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -125,8 +125,8 @@ struct v9fs_inode {
125#ifdef CONFIG_9P_FSCACHE 125#ifdef CONFIG_9P_FSCACHE
126 spinlock_t fscache_lock; 126 spinlock_t fscache_lock;
127 struct fscache_cookie *fscache; 127 struct fscache_cookie *fscache;
128 struct p9_qid *fscache_key;
129#endif 128#endif
129 struct p9_qid qid;
130 unsigned int cache_validity; 130 unsigned int cache_validity;
131 struct p9_fid *writeback_fid; 131 struct p9_fid *writeback_fid;
132 struct mutex v_mutex; 132 struct mutex v_mutex;
@@ -153,13 +153,13 @@ extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd,
153 void *p); 153 void *p);
154extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, 154extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
155 struct p9_fid *fid, 155 struct p9_fid *fid,
156 struct super_block *sb); 156 struct super_block *sb, int new);
157extern const struct inode_operations v9fs_dir_inode_operations_dotl; 157extern const struct inode_operations v9fs_dir_inode_operations_dotl;
158extern const struct inode_operations v9fs_file_inode_operations_dotl; 158extern const struct inode_operations v9fs_file_inode_operations_dotl;
159extern const struct inode_operations v9fs_symlink_inode_operations_dotl; 159extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
160extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, 160extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
161 struct p9_fid *fid, 161 struct p9_fid *fid,
162 struct super_block *sb); 162 struct super_block *sb, int new);
163 163
164/* other default globals */ 164/* other default globals */
165#define V9FS_PORT 564 165#define V9FS_PORT 564
@@ -201,8 +201,27 @@ v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
201 struct super_block *sb) 201 struct super_block *sb)
202{ 202{
203 if (v9fs_proto_dotl(v9ses)) 203 if (v9fs_proto_dotl(v9ses))
204 return v9fs_inode_from_fid_dotl(v9ses, fid, sb); 204 return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
205 else 205 else
206 return v9fs_inode_from_fid(v9ses, fid, sb); 206 return v9fs_inode_from_fid(v9ses, fid, sb, 0);
207} 207}
208
209/**
210 * v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
211 * issuing a attribute request
212 * @v9ses: session information
213 * @fid: fid to issue attribute request for
214 * @sb: superblock on which to create inode
215 *
216 */
217static inline struct inode *
218v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
219 struct super_block *sb)
220{
221 if (v9fs_proto_dotl(v9ses))
222 return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
223 else
224 return v9fs_inode_from_fid(v9ses, fid, sb, 1);
225}
226
208#endif 227#endif
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 7f9976a866e9..8bb5507e822f 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -216,7 +216,6 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
216 return NULL; 216 return NULL;
217#ifdef CONFIG_9P_FSCACHE 217#ifdef CONFIG_9P_FSCACHE
218 v9inode->fscache = NULL; 218 v9inode->fscache = NULL;
219 v9inode->fscache_key = NULL;
220 spin_lock_init(&v9inode->fscache_lock); 219 spin_lock_init(&v9inode->fscache_lock);
221#endif 220#endif
222 v9inode->writeback_fid = NULL; 221 v9inode->writeback_fid = NULL;
@@ -433,17 +432,60 @@ void v9fs_evict_inode(struct inode *inode)
433 } 432 }
434} 433}
435 434
435static int v9fs_test_inode(struct inode *inode, void *data)
436{
437 int umode;
438 struct v9fs_inode *v9inode = V9FS_I(inode);
439 struct p9_wstat *st = (struct p9_wstat *)data;
440 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
441
442 umode = p9mode2unixmode(v9ses, st->mode);
443 /* don't match inode of different type */
444 if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
445 return 0;
446
447 /* compare qid details */
448 if (memcmp(&v9inode->qid.version,
449 &st->qid.version, sizeof(v9inode->qid.version)))
450 return 0;
451
452 if (v9inode->qid.type != st->qid.type)
453 return 0;
454 return 1;
455}
456
457static int v9fs_test_new_inode(struct inode *inode, void *data)
458{
459 return 0;
460}
461
462static int v9fs_set_inode(struct inode *inode, void *data)
463{
464 struct v9fs_inode *v9inode = V9FS_I(inode);
465 struct p9_wstat *st = (struct p9_wstat *)data;
466
467 memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
468 return 0;
469}
470
436static struct inode *v9fs_qid_iget(struct super_block *sb, 471static struct inode *v9fs_qid_iget(struct super_block *sb,
437 struct p9_qid *qid, 472 struct p9_qid *qid,
438 struct p9_wstat *st) 473 struct p9_wstat *st,
474 int new)
439{ 475{
440 int retval, umode; 476 int retval, umode;
441 unsigned long i_ino; 477 unsigned long i_ino;
442 struct inode *inode; 478 struct inode *inode;
443 struct v9fs_session_info *v9ses = sb->s_fs_info; 479 struct v9fs_session_info *v9ses = sb->s_fs_info;
480 int (*test)(struct inode *, void *);
481
482 if (new)
483 test = v9fs_test_new_inode;
484 else
485 test = v9fs_test_inode;
444 486
445 i_ino = v9fs_qid2ino(qid); 487 i_ino = v9fs_qid2ino(qid);
446 inode = iget_locked(sb, i_ino); 488 inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st);
447 if (!inode) 489 if (!inode)
448 return ERR_PTR(-ENOMEM); 490 return ERR_PTR(-ENOMEM);
449 if (!(inode->i_state & I_NEW)) 491 if (!(inode->i_state & I_NEW))
@@ -453,6 +495,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
453 * FIXME!! we may need support for stale inodes 495 * FIXME!! we may need support for stale inodes
454 * later. 496 * later.
455 */ 497 */
498 inode->i_ino = i_ino;
456 umode = p9mode2unixmode(v9ses, st->mode); 499 umode = p9mode2unixmode(v9ses, st->mode);
457 retval = v9fs_init_inode(v9ses, inode, umode); 500 retval = v9fs_init_inode(v9ses, inode, umode);
458 if (retval) 501 if (retval)
@@ -460,7 +503,6 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
460 503
461 v9fs_stat2inode(st, inode, sb); 504 v9fs_stat2inode(st, inode, sb);
462#ifdef CONFIG_9P_FSCACHE 505#ifdef CONFIG_9P_FSCACHE
463 v9fs_fscache_set_key(inode, &st->qid);
464 v9fs_cache_inode_get_cookie(inode); 506 v9fs_cache_inode_get_cookie(inode);
465#endif 507#endif
466 unlock_new_inode(inode); 508 unlock_new_inode(inode);
@@ -474,7 +516,7 @@ error:
474 516
475struct inode * 517struct inode *
476v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 518v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
477 struct super_block *sb) 519 struct super_block *sb, int new)
478{ 520{
479 struct p9_wstat *st; 521 struct p9_wstat *st;
480 struct inode *inode = NULL; 522 struct inode *inode = NULL;
@@ -483,7 +525,7 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
483 if (IS_ERR(st)) 525 if (IS_ERR(st))
484 return ERR_CAST(st); 526 return ERR_CAST(st);
485 527
486 inode = v9fs_qid_iget(sb, &st->qid, st); 528 inode = v9fs_qid_iget(sb, &st->qid, st, new);
487 p9stat_free(st); 529 p9stat_free(st);
488 kfree(st); 530 kfree(st);
489 return inode; 531 return inode;
@@ -492,38 +534,50 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
492/** 534/**
493 * v9fs_remove - helper function to remove files and directories 535 * v9fs_remove - helper function to remove files and directories
494 * @dir: directory inode that is being deleted 536 * @dir: directory inode that is being deleted
495 * @file: dentry that is being deleted 537 * @dentry: dentry that is being deleted
496 * @rmdir: removing a directory 538 * @rmdir: removing a directory
497 * 539 *
498 */ 540 */
499 541
500static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) 542static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
501{ 543{
502 int retval; 544 struct inode *inode;
503 struct p9_fid *v9fid; 545 int retval = -EOPNOTSUPP;
504 struct inode *file_inode; 546 struct p9_fid *v9fid, *dfid;
505 547 struct v9fs_session_info *v9ses;
506 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file,
507 rmdir);
508 548
509 file_inode = file->d_inode; 549 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n",
510 v9fid = v9fs_fid_clone(file); 550 dir, dentry, flags);
511 if (IS_ERR(v9fid))
512 return PTR_ERR(v9fid);
513 551
514 retval = p9_client_remove(v9fid); 552 v9ses = v9fs_inode2v9ses(dir);
553 inode = dentry->d_inode;
554 dfid = v9fs_fid_lookup(dentry->d_parent);
555 if (IS_ERR(dfid)) {
556 retval = PTR_ERR(dfid);
557 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", retval);
558 return retval;
559 }
560 if (v9fs_proto_dotl(v9ses))
561 retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags);
562 if (retval == -EOPNOTSUPP) {
563 /* Try the one based on path */
564 v9fid = v9fs_fid_clone(dentry);
565 if (IS_ERR(v9fid))
566 return PTR_ERR(v9fid);
567 retval = p9_client_remove(v9fid);
568 }
515 if (!retval) { 569 if (!retval) {
516 /* 570 /*
517 * directories on unlink should have zero 571 * directories on unlink should have zero
518 * link count 572 * link count
519 */ 573 */
520 if (rmdir) { 574 if (flags & AT_REMOVEDIR) {
521 clear_nlink(file_inode); 575 clear_nlink(inode);
522 drop_nlink(dir); 576 drop_nlink(dir);
523 } else 577 } else
524 drop_nlink(file_inode); 578 drop_nlink(inode);
525 579
526 v9fs_invalidate_inode_attr(file_inode); 580 v9fs_invalidate_inode_attr(inode);
527 v9fs_invalidate_inode_attr(dir); 581 v9fs_invalidate_inode_attr(dir);
528 } 582 }
529 return retval; 583 return retval;
@@ -585,7 +639,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
585 } 639 }
586 640
587 /* instantiate inode and assign the unopened fid to the dentry */ 641 /* instantiate inode and assign the unopened fid to the dentry */
588 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 642 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
589 if (IS_ERR(inode)) { 643 if (IS_ERR(inode)) {
590 err = PTR_ERR(inode); 644 err = PTR_ERR(inode);
591 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 645 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -814,7 +868,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
814 868
815int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) 869int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
816{ 870{
817 return v9fs_remove(i, d, 1); 871 return v9fs_remove(i, d, AT_REMOVEDIR);
818} 872}
819 873
820/** 874/**
@@ -862,9 +916,12 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
862 916
863 down_write(&v9ses->rename_sem); 917 down_write(&v9ses->rename_sem);
864 if (v9fs_proto_dotl(v9ses)) { 918 if (v9fs_proto_dotl(v9ses)) {
865 retval = p9_client_rename(oldfid, newdirfid, 919 retval = p9_client_renameat(olddirfid, old_dentry->d_name.name,
866 (char *) new_dentry->d_name.name); 920 newdirfid, new_dentry->d_name.name);
867 if (retval != -ENOSYS) 921 if (retval == -EOPNOTSUPP)
922 retval = p9_client_rename(oldfid, newdirfid,
923 new_dentry->d_name.name);
924 if (retval != -EOPNOTSUPP)
868 goto clunk_newdir; 925 goto clunk_newdir;
869 } 926 }
870 if (old_dentry->d_parent != new_dentry->d_parent) { 927 if (old_dentry->d_parent != new_dentry->d_parent) {
@@ -889,11 +946,6 @@ clunk_newdir:
889 clear_nlink(new_inode); 946 clear_nlink(new_inode);
890 else 947 else
891 drop_nlink(new_inode); 948 drop_nlink(new_inode);
892 /*
893 * Work around vfs rename rehash bug with
894 * FS_RENAME_DOES_D_MOVE
895 */
896 v9fs_invalidate_inode_attr(new_inode);
897 } 949 }
898 if (S_ISDIR(old_inode->i_mode)) { 950 if (S_ISDIR(old_inode->i_mode)) {
899 if (!new_inode) 951 if (!new_inode)
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 32bbbe5aa689..276f4a69ecd4 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -86,18 +86,63 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
86 return dentry; 86 return dentry;
87} 87}
88 88
89static int v9fs_test_inode_dotl(struct inode *inode, void *data)
90{
91 struct v9fs_inode *v9inode = V9FS_I(inode);
92 struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
93
94 /* don't match inode of different type */
95 if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
96 return 0;
97
98 if (inode->i_generation != st->st_gen)
99 return 0;
100
101 /* compare qid details */
102 if (memcmp(&v9inode->qid.version,
103 &st->qid.version, sizeof(v9inode->qid.version)))
104 return 0;
105
106 if (v9inode->qid.type != st->qid.type)
107 return 0;
108 return 1;
109}
110
111/* Always get a new inode */
112static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
113{
114 return 0;
115}
116
117static int v9fs_set_inode_dotl(struct inode *inode, void *data)
118{
119 struct v9fs_inode *v9inode = V9FS_I(inode);
120 struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
121
122 memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
123 inode->i_generation = st->st_gen;
124 return 0;
125}
126
89static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, 127static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
90 struct p9_qid *qid, 128 struct p9_qid *qid,
91 struct p9_fid *fid, 129 struct p9_fid *fid,
92 struct p9_stat_dotl *st) 130 struct p9_stat_dotl *st,
131 int new)
93{ 132{
94 int retval; 133 int retval;
95 unsigned long i_ino; 134 unsigned long i_ino;
96 struct inode *inode; 135 struct inode *inode;
97 struct v9fs_session_info *v9ses = sb->s_fs_info; 136 struct v9fs_session_info *v9ses = sb->s_fs_info;
137 int (*test)(struct inode *, void *);
138
139 if (new)
140 test = v9fs_test_new_inode_dotl;
141 else
142 test = v9fs_test_inode_dotl;
98 143
99 i_ino = v9fs_qid2ino(qid); 144 i_ino = v9fs_qid2ino(qid);
100 inode = iget_locked(sb, i_ino); 145 inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
101 if (!inode) 146 if (!inode)
102 return ERR_PTR(-ENOMEM); 147 return ERR_PTR(-ENOMEM);
103 if (!(inode->i_state & I_NEW)) 148 if (!(inode->i_state & I_NEW))
@@ -107,13 +152,13 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
107 * FIXME!! we may need support for stale inodes 152 * FIXME!! we may need support for stale inodes
108 * later. 153 * later.
109 */ 154 */
155 inode->i_ino = i_ino;
110 retval = v9fs_init_inode(v9ses, inode, st->st_mode); 156 retval = v9fs_init_inode(v9ses, inode, st->st_mode);
111 if (retval) 157 if (retval)
112 goto error; 158 goto error;
113 159
114 v9fs_stat2inode_dotl(st, inode); 160 v9fs_stat2inode_dotl(st, inode);
115#ifdef CONFIG_9P_FSCACHE 161#ifdef CONFIG_9P_FSCACHE
116 v9fs_fscache_set_key(inode, &st->qid);
117 v9fs_cache_inode_get_cookie(inode); 162 v9fs_cache_inode_get_cookie(inode);
118#endif 163#endif
119 retval = v9fs_get_acl(inode, fid); 164 retval = v9fs_get_acl(inode, fid);
@@ -131,16 +176,16 @@ error:
131 176
132struct inode * 177struct inode *
133v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 178v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
134 struct super_block *sb) 179 struct super_block *sb, int new)
135{ 180{
136 struct p9_stat_dotl *st; 181 struct p9_stat_dotl *st;
137 struct inode *inode = NULL; 182 struct inode *inode = NULL;
138 183
139 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 184 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
140 if (IS_ERR(st)) 185 if (IS_ERR(st))
141 return ERR_CAST(st); 186 return ERR_CAST(st);
142 187
143 inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st); 188 inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
144 kfree(st); 189 kfree(st);
145 return inode; 190 return inode;
146} 191}
@@ -230,7 +275,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
230 fid = NULL; 275 fid = NULL;
231 goto error; 276 goto error;
232 } 277 }
233 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 278 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
234 if (IS_ERR(inode)) { 279 if (IS_ERR(inode)) {
235 err = PTR_ERR(inode); 280 err = PTR_ERR(inode);
236 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 281 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -350,7 +395,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
350 goto error; 395 goto error;
351 } 396 }
352 397
353 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 398 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
354 if (IS_ERR(inode)) { 399 if (IS_ERR(inode)) {
355 err = PTR_ERR(inode); 400 err = PTR_ERR(inode);
356 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 401 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -547,7 +592,7 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
547 inode->i_blocks = stat->st_blocks; 592 inode->i_blocks = stat->st_blocks;
548 } 593 }
549 if (stat->st_result_mask & P9_STATS_GEN) 594 if (stat->st_result_mask & P9_STATS_GEN)
550 inode->i_generation = stat->st_gen; 595 inode->i_generation = stat->st_gen;
551 596
552 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 597 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
553 * because the inode structure does not have fields for them. 598 * because the inode structure does not have fields for them.
@@ -603,7 +648,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
603 } 648 }
604 649
605 /* instantiate inode and assign the unopened fid to dentry */ 650 /* instantiate inode and assign the unopened fid to dentry */
606 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 651 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
607 if (IS_ERR(inode)) { 652 if (IS_ERR(inode)) {
608 err = PTR_ERR(inode); 653 err = PTR_ERR(inode);
609 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 654 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -756,7 +801,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
756 goto error; 801 goto error;
757 } 802 }
758 803
759 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 804 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
760 if (IS_ERR(inode)) { 805 if (IS_ERR(inode)) {
761 err = PTR_ERR(inode); 806 err = PTR_ERR(inode);
762 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 807 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 008711e8e78f..342dcf13d039 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -40,6 +40,7 @@
40 * @P9_DEBUG_FID: fid allocation/deallocation tracking 40 * @P9_DEBUG_FID: fid allocation/deallocation tracking
41 * @P9_DEBUG_PKT: packet marshalling/unmarshalling 41 * @P9_DEBUG_PKT: packet marshalling/unmarshalling
42 * @P9_DEBUG_FSC: FS-cache tracing 42 * @P9_DEBUG_FSC: FS-cache tracing
43 * @P9_DEBUG_VPKT: Verbose packet debugging (full packet dump)
43 * 44 *
44 * These flags are passed at mount time to turn on various levels of 45 * These flags are passed at mount time to turn on various levels of
45 * verbosity and tracing which will be output to the system logs. 46 * verbosity and tracing which will be output to the system logs.
@@ -57,6 +58,7 @@ enum p9_debug_flags {
57 P9_DEBUG_FID = (1<<9), 58 P9_DEBUG_FID = (1<<9),
58 P9_DEBUG_PKT = (1<<10), 59 P9_DEBUG_PKT = (1<<10),
59 P9_DEBUG_FSC = (1<<11), 60 P9_DEBUG_FSC = (1<<11),
61 P9_DEBUG_VPKT = (1<<12),
60}; 62};
61 63
62#ifdef CONFIG_NET_9P_DEBUG 64#ifdef CONFIG_NET_9P_DEBUG
@@ -74,10 +76,14 @@ do { \
74 } \ 76 } \
75} while (0) 77} while (0)
76 78
79#define P9_DUMP_PKT(way, pdu) p9pdu_dump(way, pdu)
80
77#else 81#else
78#define P9_DPRINTK(level, format, arg...) do { } while (0) 82#define P9_DPRINTK(level, format, arg...) do { } while (0)
83#define P9_DUMP_PKT(way, pdu) do { } while (0)
79#endif 84#endif
80 85
86
81#define P9_EPRINTK(level, format, arg...) \ 87#define P9_EPRINTK(level, format, arg...) \
82do { \ 88do { \
83 printk(level "9p: %s (%d): " \ 89 printk(level "9p: %s (%d): " \
@@ -175,6 +181,10 @@ enum p9_msg_t {
175 P9_RLINK, 181 P9_RLINK,
176 P9_TMKDIR = 72, 182 P9_TMKDIR = 72,
177 P9_RMKDIR, 183 P9_RMKDIR,
184 P9_TRENAMEAT = 74,
185 P9_RRENAMEAT,
186 P9_TUNLINKAT = 76,
187 P9_RUNLINKAT,
178 P9_TVERSION = 100, 188 P9_TVERSION = 100,
179 P9_RVERSION, 189 P9_RVERSION,
180 P9_TAUTH = 102, 190 P9_TAUTH = 102,
@@ -321,21 +331,6 @@ enum p9_qid_t {
321#define P9_READDIRHDRSZ 24 331#define P9_READDIRHDRSZ 24
322 332
323/** 333/**
324 * struct p9_str - length prefixed string type
325 * @len: length of the string
326 * @str: the string
327 *
328 * The protocol uses length prefixed strings for all
329 * string data, so we replicate that for our internal
330 * string members.
331 */
332
333struct p9_str {
334 u16 len;
335 char *str;
336};
337
338/**
339 * struct p9_qid - file system entity information 334 * struct p9_qid - file system entity information
340 * @type: 8-bit type &p9_qid_t 335 * @type: 8-bit type &p9_qid_t
341 * @version: 16-bit monotonically incrementing version number 336 * @version: 16-bit monotonically incrementing version number
@@ -371,11 +366,11 @@ struct p9_qid {
371 * @atime: Last access/read time 366 * @atime: Last access/read time
372 * @mtime: Last modify/write time 367 * @mtime: Last modify/write time
373 * @length: file length 368 * @length: file length
374 * @name: last element of path (aka filename) in type &p9_str 369 * @name: last element of path (aka filename)
375 * @uid: owner name in type &p9_str 370 * @uid: owner name
376 * @gid: group owner in type &p9_str 371 * @gid: group owner
377 * @muid: last modifier in type &p9_str 372 * @muid: last modifier
378 * @extension: area used to encode extended UNIX support in type &p9_str 373 * @extension: area used to encode extended UNIX support
379 * @n_uid: numeric user id of owner (part of 9p2000.u extension) 374 * @n_uid: numeric user id of owner (part of 9p2000.u extension)
380 * @n_gid: numeric group id (part of 9p2000.u extension) 375 * @n_gid: numeric group id (part of 9p2000.u extension)
381 * @n_muid: numeric user id of laster modifier (part of 9p2000.u extension) 376 * @n_muid: numeric user id of laster modifier (part of 9p2000.u extension)
@@ -512,11 +507,6 @@ struct p9_getlock {
512 char *client_id; 507 char *client_id;
513}; 508};
514 509
515/* Structures for Protocol Operations */
516struct p9_tstatfs {
517 u32 fid;
518};
519
520struct p9_rstatfs { 510struct p9_rstatfs {
521 u32 type; 511 u32 type;
522 u32 bsize; 512 u32 bsize;
@@ -529,159 +519,6 @@ struct p9_rstatfs {
529 u32 namelen; 519 u32 namelen;
530}; 520};
531 521
532struct p9_trename {
533 u32 fid;
534 u32 newdirfid;
535 struct p9_str name;
536};
537
538struct p9_rrename {
539};
540
541struct p9_tversion {
542 u32 msize;
543 struct p9_str version;
544};
545
546struct p9_rversion {
547 u32 msize;
548 struct p9_str version;
549};
550
551struct p9_tauth {
552 u32 afid;
553 struct p9_str uname;
554 struct p9_str aname;
555 u32 n_uname; /* 9P2000.u extensions */
556};
557
558struct p9_rauth {
559 struct p9_qid qid;
560};
561
562struct p9_rerror {
563 struct p9_str error;
564 u32 errno; /* 9p2000.u extension */
565};
566
567struct p9_tflush {
568 u16 oldtag;
569};
570
571struct p9_rflush {
572};
573
574struct p9_tattach {
575 u32 fid;
576 u32 afid;
577 struct p9_str uname;
578 struct p9_str aname;
579 u32 n_uname; /* 9P2000.u extensions */
580};
581
582struct p9_rattach {
583 struct p9_qid qid;
584};
585
586struct p9_twalk {
587 u32 fid;
588 u32 newfid;
589 u16 nwname;
590 struct p9_str wnames[16];
591};
592
593struct p9_rwalk {
594 u16 nwqid;
595 struct p9_qid wqids[16];
596};
597
598struct p9_topen {
599 u32 fid;
600 u8 mode;
601};
602
603struct p9_ropen {
604 struct p9_qid qid;
605 u32 iounit;
606};
607
608struct p9_tcreate {
609 u32 fid;
610 struct p9_str name;
611 u32 perm;
612 u8 mode;
613 struct p9_str extension;
614};
615
616struct p9_rcreate {
617 struct p9_qid qid;
618 u32 iounit;
619};
620
621struct p9_tread {
622 u32 fid;
623 u64 offset;
624 u32 count;
625};
626
627struct p9_rread {
628 u32 count;
629 u8 *data;
630};
631
632struct p9_twrite {
633 u32 fid;
634 u64 offset;
635 u32 count;
636 u8 *data;
637};
638
639struct p9_rwrite {
640 u32 count;
641};
642
643struct p9_treaddir {
644 u32 fid;
645 u64 offset;
646 u32 count;
647};
648
649struct p9_rreaddir {
650 u32 count;
651 u8 *data;
652};
653
654
655struct p9_tclunk {
656 u32 fid;
657};
658
659struct p9_rclunk {
660};
661
662struct p9_tremove {
663 u32 fid;
664};
665
666struct p9_rremove {
667};
668
669struct p9_tstat {
670 u32 fid;
671};
672
673struct p9_rstat {
674 struct p9_wstat stat;
675};
676
677struct p9_twstat {
678 u32 fid;
679 struct p9_wstat stat;
680};
681
682struct p9_rwstat {
683};
684
685/** 522/**
686 * struct p9_fcall - primary packet structure 523 * struct p9_fcall - primary packet structure
687 * @size: prefixed length of the structure 524 * @size: prefixed length of the structure
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index d26d5e98a173..55ce72ce9861 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -36,9 +36,9 @@
36 */ 36 */
37 37
38enum p9_proto_versions{ 38enum p9_proto_versions{
39 p9_proto_legacy = 0, 39 p9_proto_legacy,
40 p9_proto_2000u = 1, 40 p9_proto_2000u,
41 p9_proto_2000L = 2, 41 p9_proto_2000L,
42}; 42};
43 43
44 44
@@ -211,7 +211,10 @@ struct p9_dirent {
211}; 211};
212 212
213int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); 213int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
214int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name); 214int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid,
215 const char *name);
216int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
217 struct p9_fid *newdirfid, const char *new_name);
215struct p9_client *p9_client_create(const char *dev_name, char *options); 218struct p9_client *p9_client_create(const char *dev_name, char *options);
216void p9_client_destroy(struct p9_client *clnt); 219void p9_client_destroy(struct p9_client *clnt);
217void p9_client_disconnect(struct p9_client *clnt); 220void p9_client_disconnect(struct p9_client *clnt);
@@ -231,6 +234,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
231int p9_client_clunk(struct p9_fid *fid); 234int p9_client_clunk(struct p9_fid *fid);
232int p9_client_fsync(struct p9_fid *fid, int datasync); 235int p9_client_fsync(struct p9_fid *fid, int datasync);
233int p9_client_remove(struct p9_fid *fid); 236int p9_client_remove(struct p9_fid *fid);
237int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags);
234int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, 238int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
235 u64 offset, u32 count); 239 u64 offset, u32 count);
236int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, 240int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h
index d8549fb9c742..83531ebeee99 100644
--- a/include/net/9p/transport.h
+++ b/include/net/9p/transport.h
@@ -67,7 +67,7 @@ struct p9_trans_module {
67 67
68void v9fs_register_trans(struct p9_trans_module *m); 68void v9fs_register_trans(struct p9_trans_module *m);
69void v9fs_unregister_trans(struct p9_trans_module *m); 69void v9fs_unregister_trans(struct p9_trans_module *m);
70struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name); 70struct p9_trans_module *v9fs_get_trans_by_name(char *s);
71struct p9_trans_module *v9fs_get_default_trans(void); 71struct p9_trans_module *v9fs_get_default_trans(void);
72void v9fs_put_trans(struct p9_trans_module *m); 72void v9fs_put_trans(struct p9_trans_module *m);
73#endif /* NET_9P_TRANSPORT_H */ 73#endif /* NET_9P_TRANSPORT_H */
diff --git a/net/9p/client.c b/net/9p/client.c
index 9e3b0e640da1..0505a03c374c 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -72,23 +72,22 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
72EXPORT_SYMBOL(p9_is_proto_dotu); 72EXPORT_SYMBOL(p9_is_proto_dotu);
73 73
74/* Interpret mount option for protocol version */ 74/* Interpret mount option for protocol version */
75static int get_protocol_version(const substring_t *name) 75static int get_protocol_version(char *s)
76{ 76{
77 int version = -EINVAL; 77 int version = -EINVAL;
78 78
79 if (!strncmp("9p2000", name->from, name->to-name->from)) { 79 if (!strcmp(s, "9p2000")) {
80 version = p9_proto_legacy; 80 version = p9_proto_legacy;
81 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n"); 81 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
82 } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) { 82 } else if (!strcmp(s, "9p2000.u")) {
83 version = p9_proto_2000u; 83 version = p9_proto_2000u;
84 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n"); 84 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
85 } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) { 85 } else if (!strcmp(s, "9p2000.L")) {
86 version = p9_proto_2000L; 86 version = p9_proto_2000L;
87 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n"); 87 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
88 } else { 88 } else
89 P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ", 89 printk(KERN_INFO "9p: Unknown protocol version %s.\n", s);
90 name->from); 90
91 }
92 return version; 91 return version;
93} 92}
94 93
@@ -106,6 +105,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
106 char *p; 105 char *p;
107 substring_t args[MAX_OPT_ARGS]; 106 substring_t args[MAX_OPT_ARGS];
108 int option; 107 int option;
108 char *s;
109 int ret = 0; 109 int ret = 0;
110 110
111 clnt->proto_version = p9_proto_2000u; 111 clnt->proto_version = p9_proto_2000u;
@@ -141,22 +141,41 @@ static int parse_opts(char *opts, struct p9_client *clnt)
141 clnt->msize = option; 141 clnt->msize = option;
142 break; 142 break;
143 case Opt_trans: 143 case Opt_trans:
144 clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); 144 s = match_strdup(&args[0]);
145 if(clnt->trans_mod == NULL) { 145 if (!s) {
146 ret = -ENOMEM;
146 P9_DPRINTK(P9_DEBUG_ERROR, 147 P9_DPRINTK(P9_DEBUG_ERROR,
147 "Could not find request transport: %s\n", 148 "problem allocating copy of trans arg\n");
148 (char *) &args[0]); 149 goto free_and_return;
150 }
151 clnt->trans_mod = v9fs_get_trans_by_name(s);
152 if (clnt->trans_mod == NULL) {
153 printk(KERN_INFO
154 "9p: Could not find "
155 "request transport: %s\n", s);
149 ret = -EINVAL; 156 ret = -EINVAL;
157 kfree(s);
150 goto free_and_return; 158 goto free_and_return;
151 } 159 }
160 kfree(s);
152 break; 161 break;
153 case Opt_legacy: 162 case Opt_legacy:
154 clnt->proto_version = p9_proto_legacy; 163 clnt->proto_version = p9_proto_legacy;
155 break; 164 break;
156 case Opt_version: 165 case Opt_version:
157 ret = get_protocol_version(&args[0]); 166 s = match_strdup(&args[0]);
158 if (ret == -EINVAL) 167 if (!s) {
168 ret = -ENOMEM;
169 P9_DPRINTK(P9_DEBUG_ERROR,
170 "problem allocating copy of version arg\n");
159 goto free_and_return; 171 goto free_and_return;
172 }
173 ret = get_protocol_version(s);
174 if (ret == -EINVAL) {
175 kfree(s);
176 goto free_and_return;
177 }
178 kfree(s);
160 clnt->proto_version = ret; 179 clnt->proto_version = ret;
161 break; 180 break;
162 default: 181 default:
@@ -280,7 +299,8 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
280 * buffer to read the data into */ 299 * buffer to read the data into */
281 tag++; 300 tag++;
282 301
283 BUG_ON(tag >= c->max_tag); 302 if(tag >= c->max_tag)
303 return NULL;
284 304
285 row = tag / P9_ROW_MAXTAG; 305 row = tag / P9_ROW_MAXTAG;
286 col = tag % P9_ROW_MAXTAG; 306 col = tag % P9_ROW_MAXTAG;
@@ -749,7 +769,7 @@ static int p9_client_version(struct p9_client *c)
749 err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version); 769 err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
750 if (err) { 770 if (err) {
751 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err); 771 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
752 p9pdu_dump(1, req->rc); 772 P9_DUMP_PKT(1, req->rc);
753 goto error; 773 goto error;
754 } 774 }
755 775
@@ -821,8 +841,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
821 if (err) 841 if (err)
822 goto destroy_fidpool; 842 goto destroy_fidpool;
823 843
824 if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) 844 if (clnt->msize > clnt->trans_mod->maxsize)
825 clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; 845 clnt->msize = clnt->trans_mod->maxsize;
826 846
827 err = p9_client_version(clnt); 847 err = p9_client_version(clnt);
828 if (err) 848 if (err)
@@ -911,7 +931,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
911 931
912 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); 932 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
913 if (err) { 933 if (err) {
914 p9pdu_dump(1, req->rc); 934 P9_DUMP_PKT(1, req->rc);
915 p9_free_req(clnt, req); 935 p9_free_req(clnt, req);
916 goto error; 936 goto error;
917 } 937 }
@@ -971,7 +991,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
971 991
972 err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids); 992 err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
973 if (err) { 993 if (err) {
974 p9pdu_dump(1, req->rc); 994 P9_DUMP_PKT(1, req->rc);
975 p9_free_req(clnt, req); 995 p9_free_req(clnt, req);
976 goto clunk_fid; 996 goto clunk_fid;
977 } 997 }
@@ -1038,7 +1058,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
1038 1058
1039 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1059 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1040 if (err) { 1060 if (err) {
1041 p9pdu_dump(1, req->rc); 1061 P9_DUMP_PKT(1, req->rc);
1042 goto free_and_error; 1062 goto free_and_error;
1043 } 1063 }
1044 1064
@@ -1081,7 +1101,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
1081 1101
1082 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit); 1102 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit);
1083 if (err) { 1103 if (err) {
1084 p9pdu_dump(1, req->rc); 1104 P9_DUMP_PKT(1, req->rc);
1085 goto free_and_error; 1105 goto free_and_error;
1086 } 1106 }
1087 1107
@@ -1126,7 +1146,7 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
1126 1146
1127 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1147 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1128 if (err) { 1148 if (err) {
1129 p9pdu_dump(1, req->rc); 1149 P9_DUMP_PKT(1, req->rc);
1130 goto free_and_error; 1150 goto free_and_error;
1131 } 1151 }
1132 1152
@@ -1165,7 +1185,7 @@ int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
1165 1185
1166 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1186 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1167 if (err) { 1187 if (err) {
1168 p9pdu_dump(1, req->rc); 1188 P9_DUMP_PKT(1, req->rc);
1169 goto free_and_error; 1189 goto free_and_error;
1170 } 1190 }
1171 1191
@@ -1249,9 +1269,11 @@ int p9_client_clunk(struct p9_fid *fid)
1249 P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid); 1269 P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
1250 1270
1251 p9_free_req(clnt, req); 1271 p9_free_req(clnt, req);
1252 p9_fid_destroy(fid);
1253
1254error: 1272error:
1273 /*
1274 * Fid is not valid even after a failed clunk
1275 */
1276 p9_fid_destroy(fid);
1255 return err; 1277 return err;
1256} 1278}
1257EXPORT_SYMBOL(p9_client_clunk); 1279EXPORT_SYMBOL(p9_client_clunk);
@@ -1281,6 +1303,29 @@ error:
1281} 1303}
1282EXPORT_SYMBOL(p9_client_remove); 1304EXPORT_SYMBOL(p9_client_remove);
1283 1305
1306int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
1307{
1308 int err = 0;
1309 struct p9_req_t *req;
1310 struct p9_client *clnt;
1311
1312 P9_DPRINTK(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
1313 dfid->fid, name, flags);
1314
1315 clnt = dfid->clnt;
1316 req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
1317 if (IS_ERR(req)) {
1318 err = PTR_ERR(req);
1319 goto error;
1320 }
1321 P9_DPRINTK(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
1322
1323 p9_free_req(clnt, req);
1324error:
1325 return err;
1326}
1327EXPORT_SYMBOL(p9_client_unlinkat);
1328
1284int 1329int
1285p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, 1330p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1286 u32 count) 1331 u32 count)
@@ -1318,11 +1363,12 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1318 1363
1319 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 1364 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1320 if (err) { 1365 if (err) {
1321 p9pdu_dump(1, req->rc); 1366 P9_DUMP_PKT(1, req->rc);
1322 goto free_and_error; 1367 goto free_and_error;
1323 } 1368 }
1324 1369
1325 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count); 1370 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1371 P9_DUMP_PKT(1, req->rc);
1326 1372
1327 if (!req->tc->pbuf_size) { 1373 if (!req->tc->pbuf_size) {
1328 if (data) { 1374 if (data) {
@@ -1386,7 +1432,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1386 1432
1387 err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); 1433 err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
1388 if (err) { 1434 if (err) {
1389 p9pdu_dump(1, req->rc); 1435 P9_DUMP_PKT(1, req->rc);
1390 goto free_and_error; 1436 goto free_and_error;
1391 } 1437 }
1392 1438
@@ -1426,7 +1472,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1426 1472
1427 err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret); 1473 err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
1428 if (err) { 1474 if (err) {
1429 p9pdu_dump(1, req->rc); 1475 P9_DUMP_PKT(1, req->rc);
1430 p9_free_req(clnt, req); 1476 p9_free_req(clnt, req);
1431 goto error; 1477 goto error;
1432 } 1478 }
@@ -1477,7 +1523,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
1477 1523
1478 err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret); 1524 err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
1479 if (err) { 1525 if (err) {
1480 p9pdu_dump(1, req->rc); 1526 P9_DUMP_PKT(1, req->rc);
1481 p9_free_req(clnt, req); 1527 p9_free_req(clnt, req);
1482 goto error; 1528 goto error;
1483 } 1529 }
@@ -1625,7 +1671,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
1625 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail, 1671 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
1626 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen); 1672 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
1627 if (err) { 1673 if (err) {
1628 p9pdu_dump(1, req->rc); 1674 P9_DUMP_PKT(1, req->rc);
1629 p9_free_req(clnt, req); 1675 p9_free_req(clnt, req);
1630 goto error; 1676 goto error;
1631 } 1677 }
@@ -1643,7 +1689,8 @@ error:
1643} 1689}
1644EXPORT_SYMBOL(p9_client_statfs); 1690EXPORT_SYMBOL(p9_client_statfs);
1645 1691
1646int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name) 1692int p9_client_rename(struct p9_fid *fid,
1693 struct p9_fid *newdirfid, const char *name)
1647{ 1694{
1648 int err; 1695 int err;
1649 struct p9_req_t *req; 1696 struct p9_req_t *req;
@@ -1670,6 +1717,36 @@ error:
1670} 1717}
1671EXPORT_SYMBOL(p9_client_rename); 1718EXPORT_SYMBOL(p9_client_rename);
1672 1719
1720int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
1721 struct p9_fid *newdirfid, const char *new_name)
1722{
1723 int err;
1724 struct p9_req_t *req;
1725 struct p9_client *clnt;
1726
1727 err = 0;
1728 clnt = olddirfid->clnt;
1729
1730 P9_DPRINTK(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
1731 " newdirfid %d new name %s\n", olddirfid->fid, old_name,
1732 newdirfid->fid, new_name);
1733
1734 req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
1735 old_name, newdirfid->fid, new_name);
1736 if (IS_ERR(req)) {
1737 err = PTR_ERR(req);
1738 goto error;
1739 }
1740
1741 P9_DPRINTK(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
1742 newdirfid->fid, new_name);
1743
1744 p9_free_req(clnt, req);
1745error:
1746 return err;
1747}
1748EXPORT_SYMBOL(p9_client_renameat);
1749
1673/* 1750/*
1674 * An xattrwalk without @attr_name gives the fid for the lisxattr namespace 1751 * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
1675 */ 1752 */
@@ -1701,7 +1778,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
1701 } 1778 }
1702 err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size); 1779 err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
1703 if (err) { 1780 if (err) {
1704 p9pdu_dump(1, req->rc); 1781 P9_DUMP_PKT(1, req->rc);
1705 p9_free_req(clnt, req); 1782 p9_free_req(clnt, req);
1706 goto clunk_fid; 1783 goto clunk_fid;
1707 } 1784 }
@@ -1780,7 +1857,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1780 1857
1781 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 1858 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1782 if (err) { 1859 if (err) {
1783 p9pdu_dump(1, req->rc); 1860 P9_DUMP_PKT(1, req->rc);
1784 goto free_and_error; 1861 goto free_and_error;
1785 } 1862 }
1786 1863
@@ -1817,7 +1894,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
1817 1894
1818 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1895 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1819 if (err) { 1896 if (err) {
1820 p9pdu_dump(1, req->rc); 1897 P9_DUMP_PKT(1, req->rc);
1821 goto error; 1898 goto error;
1822 } 1899 }
1823 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type, 1900 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
@@ -1848,7 +1925,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
1848 1925
1849 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1926 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1850 if (err) { 1927 if (err) {
1851 p9pdu_dump(1, req->rc); 1928 P9_DUMP_PKT(1, req->rc);
1852 goto error; 1929 goto error;
1853 } 1930 }
1854 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type, 1931 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
@@ -1883,7 +1960,7 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
1883 1960
1884 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status); 1961 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
1885 if (err) { 1962 if (err) {
1886 p9pdu_dump(1, req->rc); 1963 P9_DUMP_PKT(1, req->rc);
1887 goto error; 1964 goto error;
1888 } 1965 }
1889 P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status); 1966 P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
@@ -1916,7 +1993,7 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
1916 &glock->start, &glock->length, &glock->proc_id, 1993 &glock->start, &glock->length, &glock->proc_id,
1917 &glock->client_id); 1994 &glock->client_id);
1918 if (err) { 1995 if (err) {
1919 p9pdu_dump(1, req->rc); 1996 P9_DUMP_PKT(1, req->rc);
1920 goto error; 1997 goto error;
1921 } 1998 }
1922 P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld " 1999 P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
@@ -1944,7 +2021,7 @@ int p9_client_readlink(struct p9_fid *fid, char **target)
1944 2021
1945 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target); 2022 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
1946 if (err) { 2023 if (err) {
1947 p9pdu_dump(1, req->rc); 2024 P9_DUMP_PKT(1, req->rc);
1948 goto error; 2025 goto error;
1949 } 2026 }
1950 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target); 2027 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
diff --git a/net/9p/mod.c b/net/9p/mod.c
index 72c398275051..2664d1292291 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -80,14 +80,14 @@ EXPORT_SYMBOL(v9fs_unregister_trans);
80 * @name: string identifying transport 80 * @name: string identifying transport
81 * 81 *
82 */ 82 */
83struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name) 83struct p9_trans_module *v9fs_get_trans_by_name(char *s)
84{ 84{
85 struct p9_trans_module *t, *found = NULL; 85 struct p9_trans_module *t, *found = NULL;
86 86
87 spin_lock(&v9fs_trans_lock); 87 spin_lock(&v9fs_trans_lock);
88 88
89 list_for_each_entry(t, &v9fs_trans_list, list) 89 list_for_each_entry(t, &v9fs_trans_list, list)
90 if (strncmp(t->name, name->from, name->to-name->from) == 0 && 90 if (strcmp(t->name, s) == 0 &&
91 try_module_get(t->owner)) { 91 try_module_get(t->owner)) {
92 found = t; 92 found = t;
93 break; 93 break;
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index a873277cb996..df58375ea6b3 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -44,30 +44,24 @@ p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
44void 44void
45p9pdu_dump(int way, struct p9_fcall *pdu) 45p9pdu_dump(int way, struct p9_fcall *pdu)
46{ 46{
47 int i, n; 47 int len = pdu->size;
48 u8 *data = pdu->sdata; 48
49 int datalen = pdu->size; 49 if ((p9_debug_level & P9_DEBUG_VPKT) != P9_DEBUG_VPKT) {
50 char buf[255]; 50 if ((p9_debug_level & P9_DEBUG_PKT) == P9_DEBUG_PKT) {
51 int buflen = 255; 51 if (len > 32)
52 52 len = 32;
53 i = n = 0; 53 } else {
54 if (datalen > (buflen-16)) 54 /* shouldn't happen */
55 datalen = buflen-16; 55 return;
56 while (i < datalen) { 56 }
57 n += scnprintf(buf + n, buflen - n, "%02x ", data[i]);
58 if (i%4 == 3)
59 n += scnprintf(buf + n, buflen - n, " ");
60 if (i%32 == 31)
61 n += scnprintf(buf + n, buflen - n, "\n");
62
63 i++;
64 } 57 }
65 n += scnprintf(buf + n, buflen - n, "\n");
66 58
67 if (way) 59 if (way)
68 P9_DPRINTK(P9_DEBUG_PKT, "[[[(%d) %s\n", datalen, buf); 60 print_hex_dump_bytes("[9P] ", DUMP_PREFIX_OFFSET, pdu->sdata,
61 len);
69 else 62 else
70 P9_DPRINTK(P9_DEBUG_PKT, "]]](%d) %s\n", datalen, buf); 63 print_hex_dump_bytes("]9P[ ", DUMP_PREFIX_OFFSET, pdu->sdata,
64 len);
71} 65}
72#else 66#else
73void 67void
@@ -610,7 +604,7 @@ int p9stat_read(char *buf, int len, struct p9_wstat *st, int proto_version)
610 ret = p9pdu_readf(&fake_pdu, proto_version, "S", st); 604 ret = p9pdu_readf(&fake_pdu, proto_version, "S", st);
611 if (ret) { 605 if (ret) {
612 P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret); 606 P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
613 p9pdu_dump(1, &fake_pdu); 607 P9_DUMP_PKT(0, &fake_pdu);
614 } 608 }
615 609
616 return ret; 610 return ret;
@@ -632,11 +626,7 @@ int p9pdu_finalize(struct p9_fcall *pdu)
632 err = p9pdu_writef(pdu, 0, "d", size); 626 err = p9pdu_writef(pdu, 0, "d", size);
633 pdu->size = size; 627 pdu->size = size;
634 628
635#ifdef CONFIG_NET_9P_DEBUG 629 P9_DUMP_PKT(0, pdu);
636 if ((p9_debug_level & P9_DEBUG_PKT) == P9_DEBUG_PKT)
637 p9pdu_dump(0, pdu);
638#endif
639
640 P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size, 630 P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size,
641 pdu->id, pdu->tag); 631 pdu->id, pdu->tag);
642 632
@@ -669,7 +659,7 @@ int p9dirent_read(char *buf, int len, struct p9_dirent *dirent,
669 &dirent->d_off, &dirent->d_type, &nameptr); 659 &dirent->d_off, &dirent->d_type, &nameptr);
670 if (ret) { 660 if (ret) {
671 P9_DPRINTK(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret); 661 P9_DPRINTK(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
672 p9pdu_dump(1, &fake_pdu); 662 P9_DUMP_PKT(1, &fake_pdu);
673 goto out; 663 goto out;
674 } 664 }
675 665
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 244e70742183..175b5135bdcf 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -367,7 +367,7 @@ req_retry_pinned:
367 in += inp; 367 in += inp;
368 } else { 368 } else {
369 in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, 369 in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata,
370 client->msize); 370 req->rc->capacity);
371 } 371 }
372 372
373 err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc); 373 err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc);
@@ -592,7 +592,7 @@ static struct p9_trans_module p9_virtio_trans = {
592 .close = p9_virtio_close, 592 .close = p9_virtio_close,
593 .request = p9_virtio_request, 593 .request = p9_virtio_request,
594 .cancel = p9_virtio_cancel, 594 .cancel = p9_virtio_cancel,
595 .maxsize = PAGE_SIZE*16, 595 .maxsize = PAGE_SIZE*VIRTQUEUE_NUM,
596 .pref = P9_TRANS_PREF_PAYLOAD_SEP, 596 .pref = P9_TRANS_PREF_PAYLOAD_SEP,
597 .def = 0, 597 .def = 0,
598 .owner = THIS_MODULE, 598 .owner = THIS_MODULE,