diff options
Diffstat (limited to 'fs/9p')
| -rw-r--r-- | fs/9p/v9fs.c | 6 | ||||
| -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, 157 insertions, 58 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 047c791427aa..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 | ||
| @@ -55,7 +55,7 @@ enum { | |||
| 55 | Opt_err | 55 | Opt_err |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | static match_table_t tokens = { | 58 | static const match_table_t tokens = { |
| 59 | {Opt_debug, "debug=%x"}, | 59 | {Opt_debug, "debug=%x"}, |
| 60 | {Opt_dfltuid, "dfltuid=%u"}, | 60 | {Opt_dfltuid, "dfltuid=%u"}, |
| 61 | {Opt_dfltgid, "dfltgid=%u"}, | 61 | {Opt_dfltgid, "dfltgid=%u"}, |
| @@ -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: |
