aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/9p.c8
-rw-r--r--fs/9p/9p.h3
-rw-r--r--fs/9p/conv.c8
-rw-r--r--fs/9p/conv.h3
-rw-r--r--fs/9p/vfs_file.c32
-rw-r--r--fs/9p/vfs_inode.c47
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
336int 336int
337v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, 337v9fs_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
240struct Rcreate { 241struct 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
366int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, 367int 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
369int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, 370int 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
669struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) 669struct 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);
39struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, 39struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
40 char **wnames); 40 char **wnames);
41struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); 41struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode);
42struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode); 42struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
43 char *extension, int extended);
43struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); 44struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count);
44struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, 45struct 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
109destroy_vfid:
110 v9fs_fid_destroy(vfid);
111
112clunk_fid: 110clunk_fid:
113 v9fs_t_clunk(v9ses, fid); 111 v9fs_t_clunk(v9ses, fid);
114 112
115put_fid: 113put_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
257static int 257static int
258v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, 258v9fs_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
296error: 296clunk_fid:
297 v9fs_t_clunk(v9ses, fid);
298 fid = V9FS_NOFID;
299
300put_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
1166error: 1158error:
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