diff options
-rw-r--r-- | fs/9p/9p.c | 8 | ||||
-rw-r--r-- | fs/9p/9p.h | 3 | ||||
-rw-r--r-- | fs/9p/conv.c | 8 | ||||
-rw-r--r-- | fs/9p/conv.h | 3 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 32 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 47 |
6 files changed, 50 insertions, 51 deletions
diff --git a/fs/9p/9p.c b/fs/9p/9p.c index ea2cf9692ff4..81027bc1f099 100644 --- a/fs/9p/9p.c +++ b/fs/9p/9p.c | |||
@@ -334,8 +334,8 @@ v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, | |||
334 | */ | 334 | */ |
335 | 335 | ||
336 | int | 336 | int |
337 | v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, | 337 | v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, u32 perm, |
338 | u32 perm, u8 mode, struct v9fs_fcall **rcp) | 338 | u8 mode, char *extension, struct v9fs_fcall **rcp) |
339 | { | 339 | { |
340 | int ret; | 340 | int ret; |
341 | struct v9fs_fcall *tc; | 341 | struct v9fs_fcall *tc; |
@@ -343,7 +343,9 @@ v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, | |||
343 | dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", | 343 | dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", |
344 | fid, name, perm, mode); | 344 | fid, name, perm, mode); |
345 | 345 | ||
346 | tc = v9fs_create_tcreate(fid, name, perm, mode); | 346 | tc = v9fs_create_tcreate(fid, name, perm, mode, extension, |
347 | v9ses->extended); | ||
348 | |||
347 | if (!IS_ERR(tc)) { | 349 | if (!IS_ERR(tc)) { |
348 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | 350 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); |
349 | kfree(tc); | 351 | kfree(tc); |
diff --git a/fs/9p/9p.h b/fs/9p/9p.h index 1df9e69b794b..2bb89b4005a1 100644 --- a/fs/9p/9p.h +++ b/fs/9p/9p.h | |||
@@ -235,6 +235,7 @@ struct Tcreate { | |||
235 | struct v9fs_str name; | 235 | struct v9fs_str name; |
236 | u32 perm; | 236 | u32 perm; |
237 | u8 mode; | 237 | u8 mode; |
238 | struct v9fs_str extension; | ||
238 | }; | 239 | }; |
239 | 240 | ||
240 | struct Rcreate { | 241 | struct Rcreate { |
@@ -364,7 +365,7 @@ int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, | |||
364 | struct v9fs_fcall **rcall); | 365 | struct v9fs_fcall **rcall); |
365 | 366 | ||
366 | int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, | 367 | int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, |
367 | u32 perm, u8 mode, struct v9fs_fcall **rcall); | 368 | u32 perm, u8 mode, char *extension, struct v9fs_fcall **rcall); |
368 | 369 | ||
369 | int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, | 370 | int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, |
370 | u64 offset, u32 count, struct v9fs_fcall **rcall); | 371 | u64 offset, u32 count, struct v9fs_fcall **rcall); |
diff --git a/fs/9p/conv.c b/fs/9p/conv.c index bba817142465..b129079e5f32 100644 --- a/fs/9p/conv.c +++ b/fs/9p/conv.c | |||
@@ -666,7 +666,8 @@ struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode) | |||
666 | return fc; | 666 | return fc; |
667 | } | 667 | } |
668 | 668 | ||
669 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) | 669 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, |
670 | char *extension, int extended) | ||
670 | { | 671 | { |
671 | int size; | 672 | int size; |
672 | struct v9fs_fcall *fc; | 673 | struct v9fs_fcall *fc; |
@@ -674,6 +675,9 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) | |||
674 | struct cbuf *bufp = &buffer; | 675 | struct cbuf *bufp = &buffer; |
675 | 676 | ||
676 | size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ | 677 | size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ |
678 | if (extended && extension!=NULL) | ||
679 | size += 2 + strlen(extension); /* extension[s] */ | ||
680 | |||
677 | fc = v9fs_create_common(bufp, size, TCREATE); | 681 | fc = v9fs_create_common(bufp, size, TCREATE); |
678 | if (IS_ERR(fc)) | 682 | if (IS_ERR(fc)) |
679 | goto error; | 683 | goto error; |
@@ -682,6 +686,8 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) | |||
682 | v9fs_put_str(bufp, name, &fc->params.tcreate.name); | 686 | v9fs_put_str(bufp, name, &fc->params.tcreate.name); |
683 | v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); | 687 | v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); |
684 | v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); | 688 | v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); |
689 | if (extended) | ||
690 | v9fs_put_str(bufp, extension, &fc->params.tcreate.extension); | ||
685 | 691 | ||
686 | if (buf_check_overflow(bufp)) { | 692 | if (buf_check_overflow(bufp)) { |
687 | kfree(fc); | 693 | kfree(fc); |
diff --git a/fs/9p/conv.h b/fs/9p/conv.h index f5896628dae4..03cacdda7891 100644 --- a/fs/9p/conv.h +++ b/fs/9p/conv.h | |||
@@ -39,7 +39,8 @@ struct v9fs_fcall *v9fs_create_tflush(u16 oldtag); | |||
39 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | 39 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, |
40 | char **wnames); | 40 | char **wnames); |
41 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); | 41 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); |
42 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode); | 42 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, |
43 | char *extension, int extended); | ||
43 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); | 44 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); |
44 | struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | 45 | struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, |
45 | const char __user *data); | 46 | const char __user *data); |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index de3a129698da..1144d59d6469 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -69,29 +69,30 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
69 | 69 | ||
70 | fid = v9fs_get_idpool(&v9ses->fidpool); | 70 | fid = v9fs_get_idpool(&v9ses->fidpool); |
71 | if (fid < 0) { | 71 | if (fid < 0) { |
72 | eprintk(KERN_WARNING, "newfid fails!\n"); | 72 | eprintk(KERN_WARNING, "newfid fails!\n"); |
73 | return -ENOSPC; | 73 | return -ENOSPC; |
74 | } | 74 | } |
75 | 75 | ||
76 | err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); | 76 | err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); |
77 | if (err < 0) { | 77 | if (err < 0) { |
78 | dprintk(DEBUG_ERROR, "rewalk didn't work\n"); | 78 | dprintk(DEBUG_ERROR, "rewalk didn't work\n"); |
79 | goto put_fid; | 79 | goto put_fid; |
80 | } | 80 | } |
81 | 81 | ||
82 | vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); | 82 | /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ |
83 | if (vfid == NULL) { | 83 | /* translate open mode appropriately */ |
84 | dprintk(DEBUG_ERROR, "out of memory\n"); | ||
85 | goto clunk_fid; | ||
86 | } | ||
87 | |||
88 | /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ | ||
89 | /* translate open mode appropriately */ | ||
90 | omode = v9fs_uflags2omode(file->f_flags); | 84 | omode = v9fs_uflags2omode(file->f_flags); |
91 | err = v9fs_t_open(v9ses, fid, omode, &fcall); | 85 | err = v9fs_t_open(v9ses, fid, omode, &fcall); |
92 | if (err < 0) { | 86 | if (err < 0) { |
93 | PRINT_FCALL_ERROR("open failed", fcall); | 87 | PRINT_FCALL_ERROR("open failed", fcall); |
94 | goto destroy_vfid; | 88 | goto clunk_fid; |
89 | } | ||
90 | |||
91 | vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); | ||
92 | if (vfid == NULL) { | ||
93 | dprintk(DEBUG_ERROR, "out of memory\n"); | ||
94 | err = -ENOMEM; | ||
95 | goto clunk_fid; | ||
95 | } | 96 | } |
96 | 97 | ||
97 | file->private_data = vfid; | 98 | file->private_data = vfid; |
@@ -106,15 +107,12 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
106 | 107 | ||
107 | return 0; | 108 | return 0; |
108 | 109 | ||
109 | destroy_vfid: | ||
110 | v9fs_fid_destroy(vfid); | ||
111 | |||
112 | clunk_fid: | 110 | clunk_fid: |
113 | v9fs_t_clunk(v9ses, fid); | 111 | v9fs_t_clunk(v9ses, fid); |
114 | 112 | ||
115 | put_fid: | 113 | put_fid: |
116 | v9fs_put_idpool(fid, &v9ses->fidpool); | 114 | v9fs_put_idpool(fid, &v9ses->fidpool); |
117 | kfree(fcall); | 115 | kfree(fcall); |
118 | 116 | ||
119 | return err; | 117 | return err; |
120 | } | 118 | } |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index e46bb5a82e1a..dc67f83d0dae 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -255,8 +255,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | static int | 257 | static int |
258 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | 258 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, |
259 | u32 perm, u8 mode, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) | 259 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) |
260 | { | 260 | { |
261 | u32 fid; | 261 | u32 fid; |
262 | int err; | 262 | int err; |
@@ -271,14 +271,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | |||
271 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); | 271 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); |
272 | if (err < 0) { | 272 | if (err < 0) { |
273 | PRINT_FCALL_ERROR("clone error", fcall); | 273 | PRINT_FCALL_ERROR("clone error", fcall); |
274 | goto error; | 274 | goto put_fid; |
275 | } | 275 | } |
276 | kfree(fcall); | 276 | kfree(fcall); |
277 | 277 | ||
278 | err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); | 278 | err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall); |
279 | if (err < 0) { | 279 | if (err < 0) { |
280 | PRINT_FCALL_ERROR("create fails", fcall); | 280 | PRINT_FCALL_ERROR("create fails", fcall); |
281 | goto error; | 281 | goto clunk_fid; |
282 | } | 282 | } |
283 | 283 | ||
284 | if (iounit) | 284 | if (iounit) |
@@ -293,7 +293,11 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | |||
293 | kfree(fcall); | 293 | kfree(fcall); |
294 | return 0; | 294 | return 0; |
295 | 295 | ||
296 | error: | 296 | clunk_fid: |
297 | v9fs_t_clunk(v9ses, fid); | ||
298 | fid = V9FS_NOFID; | ||
299 | |||
300 | put_fid: | ||
297 | if (fid >= 0) | 301 | if (fid >= 0) |
298 | v9fs_put_idpool(fid, &v9ses->fidpool); | 302 | v9fs_put_idpool(fid, &v9ses->fidpool); |
299 | 303 | ||
@@ -474,7 +478,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
474 | flags = O_RDWR; | 478 | flags = O_RDWR; |
475 | 479 | ||
476 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 480 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
477 | perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); | 481 | perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); |
478 | 482 | ||
479 | if (err) | 483 | if (err) |
480 | goto error; | 484 | goto error; |
@@ -550,7 +554,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
550 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); | 554 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); |
551 | 555 | ||
552 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 556 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
553 | perm, V9FS_OREAD, &fid, NULL, NULL); | 557 | perm, V9FS_OREAD, NULL, &fid, NULL, NULL); |
554 | 558 | ||
555 | if (err) { | 559 | if (err) { |
556 | dprintk(DEBUG_ERROR, "create error %d\n", err); | 560 | dprintk(DEBUG_ERROR, "create error %d\n", err); |
@@ -1008,11 +1012,13 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1008 | 1012 | ||
1009 | /* copy extension buffer into buffer */ | 1013 | /* copy extension buffer into buffer */ |
1010 | if (fcall->params.rstat.stat.extension.len < buflen) | 1014 | if (fcall->params.rstat.stat.extension.len < buflen) |
1011 | buflen = fcall->params.rstat.stat.extension.len; | 1015 | buflen = fcall->params.rstat.stat.extension.len + 1; |
1012 | 1016 | ||
1013 | memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); | 1017 | memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); |
1014 | buffer[buflen-1] = 0; | 1018 | buffer[buflen-1] = 0; |
1015 | 1019 | ||
1020 | dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len, | ||
1021 | fcall->params.rstat.stat.extension.str, buffer); | ||
1016 | retval = buflen; | 1022 | retval = buflen; |
1017 | 1023 | ||
1018 | FreeFcall: | 1024 | FreeFcall: |
@@ -1072,7 +1078,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1072 | if (!link) | 1078 | if (!link) |
1073 | link = ERR_PTR(-ENOMEM); | 1079 | link = ERR_PTR(-ENOMEM); |
1074 | else { | 1080 | else { |
1075 | len = v9fs_readlink(dentry, link, strlen(link)); | 1081 | len = v9fs_readlink(dentry, link, PATH_MAX); |
1076 | 1082 | ||
1077 | if (len < 0) { | 1083 | if (len < 0) { |
1078 | __putname(link); | 1084 | __putname(link); |
@@ -1109,10 +1115,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1109 | struct v9fs_session_info *v9ses; | 1115 | struct v9fs_session_info *v9ses; |
1110 | struct v9fs_fid *dfid, *vfid; | 1116 | struct v9fs_fid *dfid, *vfid; |
1111 | struct inode *inode; | 1117 | struct inode *inode; |
1112 | struct v9fs_fcall *fcall; | ||
1113 | struct v9fs_wstat wstat; | ||
1114 | 1118 | ||
1115 | fcall = NULL; | ||
1116 | inode = NULL; | 1119 | inode = NULL; |
1117 | vfid = NULL; | 1120 | vfid = NULL; |
1118 | v9ses = v9fs_inode2v9ses(dir); | 1121 | v9ses = v9fs_inode2v9ses(dir); |
@@ -1125,7 +1128,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1125 | } | 1128 | } |
1126 | 1129 | ||
1127 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 1130 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
1128 | perm, V9FS_OREAD, &fid, NULL, NULL); | 1131 | perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); |
1129 | 1132 | ||
1130 | if (err) | 1133 | if (err) |
1131 | goto error; | 1134 | goto error; |
@@ -1148,23 +1151,11 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1148 | goto error; | 1151 | goto error; |
1149 | } | 1152 | } |
1150 | 1153 | ||
1151 | /* issue a Twstat */ | ||
1152 | v9fs_blank_wstat(&wstat); | ||
1153 | wstat.muid = v9ses->name; | ||
1154 | wstat.extension = (char *) extension; | ||
1155 | err = v9fs_t_wstat(v9ses, vfid->fid, &wstat, &fcall); | ||
1156 | if (err < 0) { | ||
1157 | PRINT_FCALL_ERROR("wstat error", fcall); | ||
1158 | goto error; | ||
1159 | } | ||
1160 | |||
1161 | kfree(fcall); | ||
1162 | dentry->d_op = &v9fs_dentry_operations; | 1154 | dentry->d_op = &v9fs_dentry_operations; |
1163 | d_instantiate(dentry, inode); | 1155 | d_instantiate(dentry, inode); |
1164 | return 0; | 1156 | return 0; |
1165 | 1157 | ||
1166 | error: | 1158 | error: |
1167 | kfree(fcall); | ||
1168 | if (vfid) | 1159 | if (vfid) |
1169 | v9fs_fid_destroy(vfid); | 1160 | v9fs_fid_destroy(vfid); |
1170 | 1161 | ||
@@ -1224,7 +1215,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1224 | } | 1215 | } |
1225 | 1216 | ||
1226 | name = __getname(); | 1217 | name = __getname(); |
1227 | sprintf(name, "hardlink(%d)\n", oldfid->fid); | 1218 | sprintf(name, "%d\n", oldfid->fid); |
1228 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); | 1219 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); |
1229 | __putname(name); | 1220 | __putname(name); |
1230 | 1221 | ||