diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 12:39:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 12:39:47 -0400 |
commit | 45e4a24f7b6b23810142112b5850fe75696a1155 (patch) | |
tree | c6a46c3d19a0406b477240ecae7a41886c9ad7d0 /fs | |
parent | 52c6738b7f46255217942062dfa60daa7cf72510 (diff) | |
parent | 7eb923b80c8ce16697129fb2dcdfaeabf83f0dbc (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: (26 commits)
9p: add more conservative locking
9p: fix oops in protocol stat parsing error path.
9p: fix device file handling
9p: Improve debug support
9p: eliminate depricated conv functions
9p: rework client code to use new protocol support functions
9p: remove unnecessary tag field from p9_req_t structure
9p: remove 9p fcall debug prints
9p: add new protocol support code
9p: encapsulate version function
9p: move dirread to fs layer
9p: adjust 9p vfs write operation
9p: move readn meta-function from client to fs layer
9p: consolidate read/write functions
9p: drop broken unused error path from p9_conn_create()
9p: make rpc code common and rework flush code
9p: use the rcall structure passed in the request in trans_fd read_work
9p: apply common request code to trans_fd
9p: apply common tagpool handling to trans_fd
9p: move request management to client code
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/v9fs.c | 4 | ||||
-rw-r--r-- | fs/9p/v9fs_vfs.h | 6 | ||||
-rw-r--r-- | fs/9p/vfs_addr.c | 5 | ||||
-rw-r--r-- | fs/9p/vfs_dir.c | 60 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 93 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 39 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 6 |
7 files changed, 156 insertions, 57 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index c061c3f18e7c..24eb01087b6d 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #include <linux/parser.h> | 30 | #include <linux/parser.h> |
31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
32 | #include <net/9p/9p.h> | 32 | #include <net/9p/9p.h> |
33 | #include <net/9p/transport.h> | ||
34 | #include <net/9p/client.h> | 33 | #include <net/9p/client.h> |
34 | #include <net/9p/transport.h> | ||
35 | #include "v9fs.h" | 35 | #include "v9fs.h" |
36 | #include "v9fs_vfs.h" | 36 | #include "v9fs_vfs.h" |
37 | 37 | ||
@@ -234,7 +234,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
234 | if (!v9ses->clnt->dotu) | 234 | if (!v9ses->clnt->dotu) |
235 | v9ses->flags &= ~V9FS_EXTENDED; | 235 | v9ses->flags &= ~V9FS_EXTENDED; |
236 | 236 | ||
237 | v9ses->maxdata = v9ses->clnt->msize; | 237 | v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; |
238 | 238 | ||
239 | /* for legacy mode, fall back to V9FS_ACCESS_ANY */ | 239 | /* for legacy mode, fall back to V9FS_ACCESS_ANY */ |
240 | if (!v9fs_extended(v9ses) && | 240 | if (!v9fs_extended(v9ses) && |
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 57997fa14e69..c295ba786edd 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
@@ -46,9 +46,11 @@ extern struct dentry_operations v9fs_cached_dentry_operations; | |||
46 | 46 | ||
47 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); | 47 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); |
48 | ino_t v9fs_qid2ino(struct p9_qid *qid); | 48 | ino_t v9fs_qid2ino(struct p9_qid *qid); |
49 | void v9fs_stat2inode(struct p9_stat *, struct inode *, struct super_block *); | 49 | void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); |
50 | int v9fs_dir_release(struct inode *inode, struct file *filp); | 50 | int v9fs_dir_release(struct inode *inode, struct file *filp); |
51 | int v9fs_file_open(struct inode *inode, struct file *file); | 51 | int v9fs_file_open(struct inode *inode, struct file *file); |
52 | void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat); | 52 | void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat); |
53 | void v9fs_dentry_release(struct dentry *); | 53 | void v9fs_dentry_release(struct dentry *); |
54 | int v9fs_uflags2omode(int uflags, int extended); | 54 | int v9fs_uflags2omode(int uflags, int extended); |
55 | |||
56 | ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64); | ||
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 97d3aed57983..6fcb1e7095cf 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | #include "v9fs.h" | 39 | #include "v9fs.h" |
40 | #include "v9fs_vfs.h" | 40 | #include "v9fs_vfs.h" |
41 | #include "fid.h" | ||
42 | 41 | ||
43 | /** | 42 | /** |
44 | * v9fs_vfs_readpage - read an entire page in from 9P | 43 | * v9fs_vfs_readpage - read an entire page in from 9P |
@@ -53,14 +52,12 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page) | |||
53 | int retval; | 52 | int retval; |
54 | loff_t offset; | 53 | loff_t offset; |
55 | char *buffer; | 54 | char *buffer; |
56 | struct p9_fid *fid; | ||
57 | 55 | ||
58 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 56 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
59 | fid = filp->private_data; | ||
60 | buffer = kmap(page); | 57 | buffer = kmap(page); |
61 | offset = page_offset(page); | 58 | offset = page_offset(page); |
62 | 59 | ||
63 | retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE); | 60 | retval = v9fs_file_readn(filp, buffer, NULL, offset, PAGE_CACHE_SIZE); |
64 | if (retval < 0) | 61 | if (retval < 0) |
65 | goto done; | 62 | goto done; |
66 | 63 | ||
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index e298fe194093..873cd31baa47 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -45,7 +45,7 @@ | |||
45 | * | 45 | * |
46 | */ | 46 | */ |
47 | 47 | ||
48 | static inline int dt_type(struct p9_stat *mistat) | 48 | static inline int dt_type(struct p9_wstat *mistat) |
49 | { | 49 | { |
50 | unsigned long perm = mistat->mode; | 50 | unsigned long perm = mistat->mode; |
51 | int rettype = DT_REG; | 51 | int rettype = DT_REG; |
@@ -69,32 +69,58 @@ static inline int dt_type(struct p9_stat *mistat) | |||
69 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | 69 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) |
70 | { | 70 | { |
71 | int over; | 71 | int over; |
72 | struct p9_wstat st; | ||
73 | int err; | ||
72 | struct p9_fid *fid; | 74 | struct p9_fid *fid; |
73 | struct v9fs_session_info *v9ses; | 75 | int buflen; |
74 | struct inode *inode; | 76 | char *statbuf; |
75 | struct p9_stat *st; | 77 | int n, i = 0; |
76 | 78 | ||
77 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); | 79 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); |
78 | inode = filp->f_path.dentry->d_inode; | ||
79 | v9ses = v9fs_inode2v9ses(inode); | ||
80 | fid = filp->private_data; | 80 | fid = filp->private_data; |
81 | while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) { | ||
82 | if (IS_ERR(st)) | ||
83 | return PTR_ERR(st); | ||
84 | 81 | ||
85 | over = filldir(dirent, st->name.str, st->name.len, filp->f_pos, | 82 | buflen = fid->clnt->msize - P9_IOHDRSZ; |
86 | v9fs_qid2ino(&st->qid), dt_type(st)); | 83 | statbuf = kmalloc(buflen, GFP_KERNEL); |
84 | if (!statbuf) | ||
85 | return -ENOMEM; | ||
87 | 86 | ||
88 | if (over) | 87 | while (1) { |
88 | err = v9fs_file_readn(filp, statbuf, NULL, buflen, | ||
89 | fid->rdir_fpos); | ||
90 | if (err <= 0) | ||
89 | break; | 91 | break; |
90 | 92 | ||
91 | filp->f_pos += st->size; | 93 | n = err; |
92 | kfree(st); | 94 | while (i < n) { |
93 | st = NULL; | 95 | err = p9stat_read(statbuf + i, buflen-i, &st, |
96 | fid->clnt->dotu); | ||
97 | if (err) { | ||
98 | P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err); | ||
99 | err = -EIO; | ||
100 | p9stat_free(&st); | ||
101 | goto free_and_exit; | ||
102 | } | ||
103 | |||
104 | i += st.size+2; | ||
105 | fid->rdir_fpos += st.size+2; | ||
106 | |||
107 | over = filldir(dirent, st.name, strlen(st.name), | ||
108 | filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st)); | ||
109 | |||
110 | filp->f_pos += st.size+2; | ||
111 | |||
112 | p9stat_free(&st); | ||
113 | |||
114 | if (over) { | ||
115 | err = 0; | ||
116 | goto free_and_exit; | ||
117 | } | ||
118 | } | ||
94 | } | 119 | } |
95 | 120 | ||
96 | kfree(st); | 121 | free_and_exit: |
97 | return 0; | 122 | kfree(statbuf); |
123 | return err; | ||
98 | } | 124 | } |
99 | 125 | ||
100 | 126 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 52944d2249a4..041c52692284 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -120,23 +120,72 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | /** | 122 | /** |
123 | * v9fs_file_read - read from a file | 123 | * v9fs_file_readn - read from a file |
124 | * @filp: file pointer to read | 124 | * @filp: file pointer to read |
125 | * @data: data buffer to read data into | 125 | * @data: data buffer to read data into |
126 | * @udata: user data buffer to read data into | ||
126 | * @count: size of buffer | 127 | * @count: size of buffer |
127 | * @offset: offset at which to read data | 128 | * @offset: offset at which to read data |
128 | * | 129 | * |
129 | */ | 130 | */ |
131 | |||
132 | ssize_t | ||
133 | v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count, | ||
134 | u64 offset) | ||
135 | { | ||
136 | int n, total; | ||
137 | struct p9_fid *fid = filp->private_data; | ||
138 | |||
139 | P9_DPRINTK(P9_DEBUG_VFS, "fid %d offset %llu count %d\n", fid->fid, | ||
140 | (long long unsigned) offset, count); | ||
141 | |||
142 | n = 0; | ||
143 | total = 0; | ||
144 | do { | ||
145 | n = p9_client_read(fid, data, udata, offset, count); | ||
146 | if (n <= 0) | ||
147 | break; | ||
148 | |||
149 | if (data) | ||
150 | data += n; | ||
151 | if (udata) | ||
152 | udata += n; | ||
153 | |||
154 | offset += n; | ||
155 | count -= n; | ||
156 | total += n; | ||
157 | } while (count > 0 && n == (fid->clnt->msize - P9_IOHDRSZ)); | ||
158 | |||
159 | if (n < 0) | ||
160 | total = n; | ||
161 | |||
162 | return total; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * v9fs_file_read - read from a file | ||
167 | * @filp: file pointer to read | ||
168 | * @udata: user data buffer to read data into | ||
169 | * @count: size of buffer | ||
170 | * @offset: offset at which to read data | ||
171 | * | ||
172 | */ | ||
173 | |||
130 | static ssize_t | 174 | static ssize_t |
131 | v9fs_file_read(struct file *filp, char __user * data, size_t count, | 175 | v9fs_file_read(struct file *filp, char __user *udata, size_t count, |
132 | loff_t * offset) | 176 | loff_t * offset) |
133 | { | 177 | { |
134 | int ret; | 178 | int ret; |
135 | struct p9_fid *fid; | 179 | struct p9_fid *fid; |
136 | 180 | ||
137 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 181 | P9_DPRINTK(P9_DEBUG_VFS, "count %d offset %lld\n", count, *offset); |
138 | fid = filp->private_data; | 182 | fid = filp->private_data; |
139 | ret = p9_client_uread(fid, data, *offset, count); | 183 | |
184 | if (count > (fid->clnt->msize - P9_IOHDRSZ)) | ||
185 | ret = v9fs_file_readn(filp, NULL, udata, count, *offset); | ||
186 | else | ||
187 | ret = p9_client_read(fid, NULL, udata, *offset, count); | ||
188 | |||
140 | if (ret > 0) | 189 | if (ret > 0) |
141 | *offset += ret; | 190 | *offset += ret; |
142 | 191 | ||
@@ -156,19 +205,38 @@ static ssize_t | |||
156 | v9fs_file_write(struct file *filp, const char __user * data, | 205 | v9fs_file_write(struct file *filp, const char __user * data, |
157 | size_t count, loff_t * offset) | 206 | size_t count, loff_t * offset) |
158 | { | 207 | { |
159 | int ret; | 208 | int n, rsize, total = 0; |
160 | struct p9_fid *fid; | 209 | struct p9_fid *fid; |
210 | struct p9_client *clnt; | ||
161 | struct inode *inode = filp->f_path.dentry->d_inode; | 211 | struct inode *inode = filp->f_path.dentry->d_inode; |
212 | int origin = *offset; | ||
162 | 213 | ||
163 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, | 214 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, |
164 | (int)count, (int)*offset); | 215 | (int)count, (int)*offset); |
165 | 216 | ||
166 | fid = filp->private_data; | 217 | fid = filp->private_data; |
167 | ret = p9_client_uwrite(fid, data, *offset, count); | 218 | clnt = fid->clnt; |
168 | if (ret > 0) { | 219 | |
169 | invalidate_inode_pages2_range(inode->i_mapping, *offset, | 220 | rsize = fid->iounit; |
170 | *offset+ret); | 221 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) |
171 | *offset += ret; | 222 | rsize = clnt->msize - P9_IOHDRSZ; |
223 | |||
224 | do { | ||
225 | if (count < rsize) | ||
226 | rsize = count; | ||
227 | |||
228 | n = p9_client_write(fid, NULL, data+total, *offset+total, | ||
229 | rsize); | ||
230 | if (n <= 0) | ||
231 | break; | ||
232 | count -= n; | ||
233 | total += n; | ||
234 | } while (count > 0); | ||
235 | |||
236 | if (total > 0) { | ||
237 | invalidate_inode_pages2_range(inode->i_mapping, origin, | ||
238 | origin+total); | ||
239 | *offset += total; | ||
172 | } | 240 | } |
173 | 241 | ||
174 | if (*offset > inode->i_size) { | 242 | if (*offset > inode->i_size) { |
@@ -176,7 +244,10 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
176 | inode->i_blocks = (inode->i_size + 512 - 1) >> 9; | 244 | inode->i_blocks = (inode->i_size + 512 - 1) >> 9; |
177 | } | 245 | } |
178 | 246 | ||
179 | return ret; | 247 | if (n < 0) |
248 | return n; | ||
249 | |||
250 | return total; | ||
180 | } | 251 | } |
181 | 252 | ||
182 | static const struct file_operations v9fs_cached_file_operations = { | 253 | static const struct file_operations v9fs_cached_file_operations = { |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index e83aa5ebe861..8314d3f43b71 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -334,7 +334,7 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
334 | { | 334 | { |
335 | int err, umode; | 335 | int err, umode; |
336 | struct inode *ret; | 336 | struct inode *ret; |
337 | struct p9_stat *st; | 337 | struct p9_wstat *st; |
338 | 338 | ||
339 | ret = NULL; | 339 | ret = NULL; |
340 | st = p9_client_stat(fid); | 340 | st = p9_client_stat(fid); |
@@ -417,6 +417,8 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
417 | struct p9_fid *dfid, *ofid, *fid; | 417 | struct p9_fid *dfid, *ofid, *fid; |
418 | struct inode *inode; | 418 | struct inode *inode; |
419 | 419 | ||
420 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | ||
421 | |||
420 | err = 0; | 422 | err = 0; |
421 | ofid = NULL; | 423 | ofid = NULL; |
422 | fid = NULL; | 424 | fid = NULL; |
@@ -424,6 +426,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
424 | dfid = v9fs_fid_clone(dentry->d_parent); | 426 | dfid = v9fs_fid_clone(dentry->d_parent); |
425 | if (IS_ERR(dfid)) { | 427 | if (IS_ERR(dfid)) { |
426 | err = PTR_ERR(dfid); | 428 | err = PTR_ERR(dfid); |
429 | P9_DPRINTK(P9_DEBUG_VFS, "fid clone failed %d\n", err); | ||
427 | dfid = NULL; | 430 | dfid = NULL; |
428 | goto error; | 431 | goto error; |
429 | } | 432 | } |
@@ -432,18 +435,22 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
432 | ofid = p9_client_walk(dfid, 0, NULL, 1); | 435 | ofid = p9_client_walk(dfid, 0, NULL, 1); |
433 | if (IS_ERR(ofid)) { | 436 | if (IS_ERR(ofid)) { |
434 | err = PTR_ERR(ofid); | 437 | err = PTR_ERR(ofid); |
438 | P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); | ||
435 | ofid = NULL; | 439 | ofid = NULL; |
436 | goto error; | 440 | goto error; |
437 | } | 441 | } |
438 | 442 | ||
439 | err = p9_client_fcreate(ofid, name, perm, mode, extension); | 443 | err = p9_client_fcreate(ofid, name, perm, mode, extension); |
440 | if (err < 0) | 444 | if (err < 0) { |
445 | P9_DPRINTK(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err); | ||
441 | goto error; | 446 | goto error; |
447 | } | ||
442 | 448 | ||
443 | /* now walk from the parent so we can get unopened fid */ | 449 | /* now walk from the parent so we can get unopened fid */ |
444 | fid = p9_client_walk(dfid, 1, &name, 0); | 450 | fid = p9_client_walk(dfid, 1, &name, 0); |
445 | if (IS_ERR(fid)) { | 451 | if (IS_ERR(fid)) { |
446 | err = PTR_ERR(fid); | 452 | err = PTR_ERR(fid); |
453 | P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); | ||
447 | fid = NULL; | 454 | fid = NULL; |
448 | goto error; | 455 | goto error; |
449 | } else | 456 | } else |
@@ -453,6 +460,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
453 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); | 460 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); |
454 | if (IS_ERR(inode)) { | 461 | if (IS_ERR(inode)) { |
455 | err = PTR_ERR(inode); | 462 | err = PTR_ERR(inode); |
463 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); | ||
456 | goto error; | 464 | goto error; |
457 | } | 465 | } |
458 | 466 | ||
@@ -734,7 +742,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
734 | int err; | 742 | int err; |
735 | struct v9fs_session_info *v9ses; | 743 | struct v9fs_session_info *v9ses; |
736 | struct p9_fid *fid; | 744 | struct p9_fid *fid; |
737 | struct p9_stat *st; | 745 | struct p9_wstat *st; |
738 | 746 | ||
739 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); | 747 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); |
740 | err = -EPERM; | 748 | err = -EPERM; |
@@ -815,10 +823,9 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
815 | */ | 823 | */ |
816 | 824 | ||
817 | void | 825 | void |
818 | v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, | 826 | v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, |
819 | struct super_block *sb) | 827 | struct super_block *sb) |
820 | { | 828 | { |
821 | int n; | ||
822 | char ext[32]; | 829 | char ext[32]; |
823 | struct v9fs_session_info *v9ses = sb->s_fs_info; | 830 | struct v9fs_session_info *v9ses = sb->s_fs_info; |
824 | 831 | ||
@@ -842,11 +849,7 @@ v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, | |||
842 | int major = -1; | 849 | int major = -1; |
843 | int minor = -1; | 850 | int minor = -1; |
844 | 851 | ||
845 | n = stat->extension.len; | 852 | strncpy(ext, stat->extension, sizeof(ext)); |
846 | if (n > sizeof(ext)-1) | ||
847 | n = sizeof(ext)-1; | ||
848 | memmove(ext, stat->extension.str, n); | ||
849 | ext[n] = 0; | ||
850 | sscanf(ext, "%c %u %u", &type, &major, &minor); | 853 | sscanf(ext, "%c %u %u", &type, &major, &minor); |
851 | switch (type) { | 854 | switch (type) { |
852 | case 'c': | 855 | case 'c': |
@@ -857,10 +860,11 @@ v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, | |||
857 | break; | 860 | break; |
858 | default: | 861 | default: |
859 | P9_DPRINTK(P9_DEBUG_ERROR, | 862 | P9_DPRINTK(P9_DEBUG_ERROR, |
860 | "Unknown special type %c (%.*s)\n", type, | 863 | "Unknown special type %c %s\n", type, |
861 | stat->extension.len, stat->extension.str); | 864 | stat->extension); |
862 | }; | 865 | }; |
863 | inode->i_rdev = MKDEV(major, minor); | 866 | inode->i_rdev = MKDEV(major, minor); |
867 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | ||
864 | } else | 868 | } else |
865 | inode->i_rdev = 0; | 869 | inode->i_rdev = 0; |
866 | 870 | ||
@@ -904,7 +908,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
904 | 908 | ||
905 | struct v9fs_session_info *v9ses; | 909 | struct v9fs_session_info *v9ses; |
906 | struct p9_fid *fid; | 910 | struct p9_fid *fid; |
907 | struct p9_stat *st; | 911 | struct p9_wstat *st; |
908 | 912 | ||
909 | P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); | 913 | P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); |
910 | retval = -EPERM; | 914 | retval = -EPERM; |
@@ -926,15 +930,10 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
926 | } | 930 | } |
927 | 931 | ||
928 | /* copy extension buffer into buffer */ | 932 | /* copy extension buffer into buffer */ |
929 | if (st->extension.len < buflen) | 933 | strncpy(buffer, st->extension, buflen); |
930 | buflen = st->extension.len + 1; | ||
931 | |||
932 | memmove(buffer, st->extension.str, buflen - 1); | ||
933 | buffer[buflen-1] = 0; | ||
934 | 934 | ||
935 | P9_DPRINTK(P9_DEBUG_VFS, | 935 | P9_DPRINTK(P9_DEBUG_VFS, |
936 | "%s -> %.*s (%s)\n", dentry->d_name.name, st->extension.len, | 936 | "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer); |
937 | st->extension.str, buffer); | ||
938 | 937 | ||
939 | retval = buflen; | 938 | retval = buflen; |
940 | 939 | ||
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index bf59c3960494..d6cb1a0ca724 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -111,7 +111,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
111 | struct inode *inode = NULL; | 111 | struct inode *inode = NULL; |
112 | struct dentry *root = NULL; | 112 | struct dentry *root = NULL; |
113 | struct v9fs_session_info *v9ses = NULL; | 113 | struct v9fs_session_info *v9ses = NULL; |
114 | struct p9_stat *st = NULL; | 114 | struct p9_wstat *st = NULL; |
115 | int mode = S_IRWXUGO | S_ISVTX; | 115 | int mode = S_IRWXUGO | S_ISVTX; |
116 | uid_t uid = current->fsuid; | 116 | uid_t uid = current->fsuid; |
117 | gid_t gid = current->fsgid; | 117 | gid_t gid = current->fsgid; |
@@ -161,10 +161,14 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
161 | 161 | ||
162 | sb->s_root = root; | 162 | sb->s_root = root; |
163 | root->d_inode->i_ino = v9fs_qid2ino(&st->qid); | 163 | root->d_inode->i_ino = v9fs_qid2ino(&st->qid); |
164 | |||
164 | v9fs_stat2inode(st, root->d_inode, sb); | 165 | v9fs_stat2inode(st, root->d_inode, sb); |
166 | |||
165 | v9fs_fid_add(root, fid); | 167 | v9fs_fid_add(root, fid); |
168 | p9stat_free(st); | ||
166 | kfree(st); | 169 | kfree(st); |
167 | 170 | ||
171 | P9_DPRINTK(P9_DEBUG_VFS, " return simple set mount\n"); | ||
168 | return simple_set_mnt(mnt, sb); | 172 | return simple_set_mnt(mnt, sb); |
169 | 173 | ||
170 | release_sb: | 174 | release_sb: |