diff options
-rw-r--r-- | fs/9p/cache.c | 20 | ||||
-rw-r--r-- | fs/9p/cache.h | 9 | ||||
-rw-r--r-- | fs/9p/v9fs.c | 45 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 29 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 118 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 67 | ||||
-rw-r--r-- | include/net/9p/9p.h | 193 | ||||
-rw-r--r-- | include/net/9p/client.h | 12 | ||||
-rw-r--r-- | include/net/9p/transport.h | 2 | ||||
-rw-r--r-- | net/9p/client.c | 155 | ||||
-rw-r--r-- | net/9p/mod.c | 4 | ||||
-rw-r--r-- | net/9p/protocol.c | 44 | ||||
-rw-r--r-- | net/9p/trans_virtio.c | 4 |
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 | ||
118 | static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data, | 117 | static 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 | ||
139 | static enum | 137 | static 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 | ||
96 | static 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 | |||
105 | static inline void v9fs_fscache_wait_on_page_write(struct inode *inode, | 96 | static 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 */ | ||
82 | static 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); |
154 | extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, | 154 | extern 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); |
157 | extern const struct inode_operations v9fs_dir_inode_operations_dotl; | 157 | extern const struct inode_operations v9fs_dir_inode_operations_dotl; |
158 | extern const struct inode_operations v9fs_file_inode_operations_dotl; | 158 | extern const struct inode_operations v9fs_file_inode_operations_dotl; |
159 | extern const struct inode_operations v9fs_symlink_inode_operations_dotl; | 159 | extern const struct inode_operations v9fs_symlink_inode_operations_dotl; |
160 | extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, | 160 | extern 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 | */ | ||
217 | static inline struct inode * | ||
218 | v9fs_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 | ||
435 | static 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 | |||
457 | static int v9fs_test_new_inode(struct inode *inode, void *data) | ||
458 | { | ||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | static 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 | |||
436 | static struct inode *v9fs_qid_iget(struct super_block *sb, | 471 | static 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 | ||
475 | struct inode * | 517 | struct inode * |
476 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | 518 | v9fs_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 | ||
500 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | 542 | static 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 | ||
815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) | 869 | int 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 | ||
89 | static 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 */ | ||
112 | static int v9fs_test_new_inode_dotl(struct inode *inode, void *data) | ||
113 | { | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static 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 | |||
89 | static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, | 127 | static 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 | ||
132 | struct inode * | 177 | struct inode * |
133 | v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, | 178 | v9fs_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...) \ |
82 | do { \ | 88 | do { \ |
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 | |||
333 | struct 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 */ | ||
516 | struct p9_tstatfs { | ||
517 | u32 fid; | ||
518 | }; | ||
519 | |||
520 | struct p9_rstatfs { | 510 | struct 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 | ||
532 | struct p9_trename { | ||
533 | u32 fid; | ||
534 | u32 newdirfid; | ||
535 | struct p9_str name; | ||
536 | }; | ||
537 | |||
538 | struct p9_rrename { | ||
539 | }; | ||
540 | |||
541 | struct p9_tversion { | ||
542 | u32 msize; | ||
543 | struct p9_str version; | ||
544 | }; | ||
545 | |||
546 | struct p9_rversion { | ||
547 | u32 msize; | ||
548 | struct p9_str version; | ||
549 | }; | ||
550 | |||
551 | struct p9_tauth { | ||
552 | u32 afid; | ||
553 | struct p9_str uname; | ||
554 | struct p9_str aname; | ||
555 | u32 n_uname; /* 9P2000.u extensions */ | ||
556 | }; | ||
557 | |||
558 | struct p9_rauth { | ||
559 | struct p9_qid qid; | ||
560 | }; | ||
561 | |||
562 | struct p9_rerror { | ||
563 | struct p9_str error; | ||
564 | u32 errno; /* 9p2000.u extension */ | ||
565 | }; | ||
566 | |||
567 | struct p9_tflush { | ||
568 | u16 oldtag; | ||
569 | }; | ||
570 | |||
571 | struct p9_rflush { | ||
572 | }; | ||
573 | |||
574 | struct 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 | |||
582 | struct p9_rattach { | ||
583 | struct p9_qid qid; | ||
584 | }; | ||
585 | |||
586 | struct p9_twalk { | ||
587 | u32 fid; | ||
588 | u32 newfid; | ||
589 | u16 nwname; | ||
590 | struct p9_str wnames[16]; | ||
591 | }; | ||
592 | |||
593 | struct p9_rwalk { | ||
594 | u16 nwqid; | ||
595 | struct p9_qid wqids[16]; | ||
596 | }; | ||
597 | |||
598 | struct p9_topen { | ||
599 | u32 fid; | ||
600 | u8 mode; | ||
601 | }; | ||
602 | |||
603 | struct p9_ropen { | ||
604 | struct p9_qid qid; | ||
605 | u32 iounit; | ||
606 | }; | ||
607 | |||
608 | struct p9_tcreate { | ||
609 | u32 fid; | ||
610 | struct p9_str name; | ||
611 | u32 perm; | ||
612 | u8 mode; | ||
613 | struct p9_str extension; | ||
614 | }; | ||
615 | |||
616 | struct p9_rcreate { | ||
617 | struct p9_qid qid; | ||
618 | u32 iounit; | ||
619 | }; | ||
620 | |||
621 | struct p9_tread { | ||
622 | u32 fid; | ||
623 | u64 offset; | ||
624 | u32 count; | ||
625 | }; | ||
626 | |||
627 | struct p9_rread { | ||
628 | u32 count; | ||
629 | u8 *data; | ||
630 | }; | ||
631 | |||
632 | struct p9_twrite { | ||
633 | u32 fid; | ||
634 | u64 offset; | ||
635 | u32 count; | ||
636 | u8 *data; | ||
637 | }; | ||
638 | |||
639 | struct p9_rwrite { | ||
640 | u32 count; | ||
641 | }; | ||
642 | |||
643 | struct p9_treaddir { | ||
644 | u32 fid; | ||
645 | u64 offset; | ||
646 | u32 count; | ||
647 | }; | ||
648 | |||
649 | struct p9_rreaddir { | ||
650 | u32 count; | ||
651 | u8 *data; | ||
652 | }; | ||
653 | |||
654 | |||
655 | struct p9_tclunk { | ||
656 | u32 fid; | ||
657 | }; | ||
658 | |||
659 | struct p9_rclunk { | ||
660 | }; | ||
661 | |||
662 | struct p9_tremove { | ||
663 | u32 fid; | ||
664 | }; | ||
665 | |||
666 | struct p9_rremove { | ||
667 | }; | ||
668 | |||
669 | struct p9_tstat { | ||
670 | u32 fid; | ||
671 | }; | ||
672 | |||
673 | struct p9_rstat { | ||
674 | struct p9_wstat stat; | ||
675 | }; | ||
676 | |||
677 | struct p9_twstat { | ||
678 | u32 fid; | ||
679 | struct p9_wstat stat; | ||
680 | }; | ||
681 | |||
682 | struct 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 | ||
38 | enum p9_proto_versions{ | 38 | enum 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 | ||
213 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); | 213 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); |
214 | int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name); | 214 | int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, |
215 | const char *name); | ||
216 | int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name, | ||
217 | struct p9_fid *newdirfid, const char *new_name); | ||
215 | struct p9_client *p9_client_create(const char *dev_name, char *options); | 218 | struct p9_client *p9_client_create(const char *dev_name, char *options); |
216 | void p9_client_destroy(struct p9_client *clnt); | 219 | void p9_client_destroy(struct p9_client *clnt); |
217 | void p9_client_disconnect(struct p9_client *clnt); | 220 | void 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, | |||
231 | int p9_client_clunk(struct p9_fid *fid); | 234 | int p9_client_clunk(struct p9_fid *fid); |
232 | int p9_client_fsync(struct p9_fid *fid, int datasync); | 235 | int p9_client_fsync(struct p9_fid *fid, int datasync); |
233 | int p9_client_remove(struct p9_fid *fid); | 236 | int p9_client_remove(struct p9_fid *fid); |
237 | int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags); | ||
234 | int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, | 238 | int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, |
235 | u64 offset, u32 count); | 239 | u64 offset, u32 count); |
236 | int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, | 240 | int 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 | ||
68 | void v9fs_register_trans(struct p9_trans_module *m); | 68 | void v9fs_register_trans(struct p9_trans_module *m); |
69 | void v9fs_unregister_trans(struct p9_trans_module *m); | 69 | void v9fs_unregister_trans(struct p9_trans_module *m); |
70 | struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name); | 70 | struct p9_trans_module *v9fs_get_trans_by_name(char *s); |
71 | struct p9_trans_module *v9fs_get_default_trans(void); | 71 | struct p9_trans_module *v9fs_get_default_trans(void); |
72 | void v9fs_put_trans(struct p9_trans_module *m); | 72 | void 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) | |||
72 | EXPORT_SYMBOL(p9_is_proto_dotu); | 72 | EXPORT_SYMBOL(p9_is_proto_dotu); |
73 | 73 | ||
74 | /* Interpret mount option for protocol version */ | 74 | /* Interpret mount option for protocol version */ |
75 | static int get_protocol_version(const substring_t *name) | 75 | static 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 | |||
1254 | error: | 1272 | error: |
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 | } |
1257 | EXPORT_SYMBOL(p9_client_clunk); | 1279 | EXPORT_SYMBOL(p9_client_clunk); |
@@ -1281,6 +1303,29 @@ error: | |||
1281 | } | 1303 | } |
1282 | EXPORT_SYMBOL(p9_client_remove); | 1304 | EXPORT_SYMBOL(p9_client_remove); |
1283 | 1305 | ||
1306 | int 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); | ||
1324 | error: | ||
1325 | return err; | ||
1326 | } | ||
1327 | EXPORT_SYMBOL(p9_client_unlinkat); | ||
1328 | |||
1284 | int | 1329 | int |
1285 | p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, | 1330 | p9_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 | } |
1644 | EXPORT_SYMBOL(p9_client_statfs); | 1690 | EXPORT_SYMBOL(p9_client_statfs); |
1645 | 1691 | ||
1646 | int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name) | 1692 | int 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 | } |
1671 | EXPORT_SYMBOL(p9_client_rename); | 1718 | EXPORT_SYMBOL(p9_client_rename); |
1672 | 1719 | ||
1720 | int 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); | ||
1745 | error: | ||
1746 | return err; | ||
1747 | } | ||
1748 | EXPORT_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 | */ |
83 | struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name) | 83 | struct 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, ...); | |||
44 | void | 44 | void |
45 | p9pdu_dump(int way, struct p9_fcall *pdu) | 45 | p9pdu_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 |
73 | void | 67 | void |
@@ -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, |