diff options
author | Latchesar Ionkov <lucho@ionkov.net> | 2006-01-08 04:04:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:14:05 -0500 |
commit | 3cf6429a26da5c4d7b795e6d0f8f56ed2e4fdfc0 (patch) | |
tree | a8d856763fd9a0536519634c93ab92da684107fa /fs/9p/vfs_inode.c | |
parent | f5ef3c105bee3a52486d7b55cef3330fcde9bca6 (diff) |
[PATCH] v9fs: new multiplexer implementation
New multiplexer implementation. Decreases the number of kernel threads
required. Better handling when the user process receives a signal.
Signed-off-by: Latchesar Ionkov <lucho@ionkov.net>
Cc: Eric Van Hensbergen <ericvh@ericvh.myip.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r-- | fs/9p/vfs_inode.c | 89 |
1 files changed, 42 insertions, 47 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 0ea965c3bb7d..466002a1fe32 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -318,6 +318,7 @@ v9fs_create(struct inode *dir, | |||
318 | int result = 0; | 318 | int result = 0; |
319 | unsigned int iounit = 0; | 319 | unsigned int iounit = 0; |
320 | int wfidno = -1; | 320 | int wfidno = -1; |
321 | int err; | ||
321 | 322 | ||
322 | perm = unixmode2p9mode(v9ses, perm); | 323 | perm = unixmode2p9mode(v9ses, perm); |
323 | 324 | ||
@@ -356,6 +357,7 @@ v9fs_create(struct inode *dir, | |||
356 | } | 357 | } |
357 | 358 | ||
358 | kfree(fcall); | 359 | kfree(fcall); |
360 | fcall = NULL; | ||
359 | 361 | ||
360 | result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name, | 362 | result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name, |
361 | perm, open_mode, &fcall); | 363 | perm, open_mode, &fcall); |
@@ -369,16 +371,23 @@ v9fs_create(struct inode *dir, | |||
369 | iounit = fcall->params.rcreate.iounit; | 371 | iounit = fcall->params.rcreate.iounit; |
370 | qid = fcall->params.rcreate.qid; | 372 | qid = fcall->params.rcreate.qid; |
371 | kfree(fcall); | 373 | kfree(fcall); |
374 | fcall = NULL; | ||
372 | 375 | ||
373 | fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1); | 376 | if (!(perm&V9FS_DMDIR)) { |
374 | dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate); | 377 | fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1); |
375 | if (!fid) { | 378 | dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate); |
376 | result = -ENOMEM; | 379 | if (!fid) { |
377 | goto CleanUpFid; | 380 | result = -ENOMEM; |
378 | } | 381 | goto CleanUpFid; |
382 | } | ||
379 | 383 | ||
380 | fid->qid = qid; | 384 | fid->qid = qid; |
381 | fid->iounit = iounit; | 385 | fid->iounit = iounit; |
386 | } else { | ||
387 | err = v9fs_t_clunk(v9ses, newfid); | ||
388 | if (err < 0) | ||
389 | dprintk(DEBUG_ERROR, "clunk for mkdir failed: %d\n", err); | ||
390 | } | ||
382 | 391 | ||
383 | /* walk to the newly created file and put the fid in the dentry */ | 392 | /* walk to the newly created file and put the fid in the dentry */ |
384 | wfidno = v9fs_get_idpool(&v9ses->fidpool); | 393 | wfidno = v9fs_get_idpool(&v9ses->fidpool); |
@@ -388,18 +397,19 @@ v9fs_create(struct inode *dir, | |||
388 | } | 397 | } |
389 | 398 | ||
390 | result = v9fs_t_walk(v9ses, dirfidnum, wfidno, | 399 | result = v9fs_t_walk(v9ses, dirfidnum, wfidno, |
391 | (char *) file_dentry->d_name.name, NULL); | 400 | (char *) file_dentry->d_name.name, &fcall); |
392 | if (result < 0) { | 401 | if (result < 0) { |
393 | dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); | 402 | dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); |
394 | v9fs_put_idpool(wfidno, &v9ses->fidpool); | 403 | v9fs_put_idpool(wfidno, &v9ses->fidpool); |
395 | wfidno = -1; | 404 | wfidno = -1; |
396 | goto CleanUpFid; | 405 | goto CleanUpFid; |
397 | } | 406 | } |
407 | kfree(fcall); | ||
408 | fcall = NULL; | ||
398 | 409 | ||
399 | if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) { | 410 | if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) { |
400 | if (!v9fs_t_clunk(v9ses, newfid, &fcall)) { | 411 | v9fs_t_clunk(v9ses, newfid); |
401 | v9fs_put_idpool(wfidno, &v9ses->fidpool); | 412 | v9fs_put_idpool(wfidno, &v9ses->fidpool); |
402 | } | ||
403 | 413 | ||
404 | goto CleanUpFid; | 414 | goto CleanUpFid; |
405 | } | 415 | } |
@@ -431,40 +441,21 @@ v9fs_create(struct inode *dir, | |||
431 | file_dentry->d_op = &v9fs_dentry_operations; | 441 | file_dentry->d_op = &v9fs_dentry_operations; |
432 | d_instantiate(file_dentry, file_inode); | 442 | d_instantiate(file_dentry, file_inode); |
433 | 443 | ||
434 | if (perm & V9FS_DMDIR) { | ||
435 | if (!v9fs_t_clunk(v9ses, newfid, &fcall)) | ||
436 | v9fs_put_idpool(newfid, &v9ses->fidpool); | ||
437 | else | ||
438 | dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n", | ||
439 | FCALL_ERROR(fcall)); | ||
440 | kfree(fcall); | ||
441 | fid->fidopen = 0; | ||
442 | fid->fidcreate = 0; | ||
443 | d_drop(file_dentry); | ||
444 | } | ||
445 | |||
446 | return 0; | 444 | return 0; |
447 | 445 | ||
448 | CleanUpFid: | 446 | CleanUpFid: |
449 | kfree(fcall); | 447 | kfree(fcall); |
448 | fcall = NULL; | ||
450 | 449 | ||
451 | if (newfid >= 0) { | 450 | if (newfid >= 0) { |
452 | if (!v9fs_t_clunk(v9ses, newfid, &fcall)) | 451 | err = v9fs_t_clunk(v9ses, newfid); |
453 | v9fs_put_idpool(newfid, &v9ses->fidpool); | 452 | if (err < 0) |
454 | else | 453 | dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); |
455 | dprintk(DEBUG_ERROR, "clunk failed: %s\n", | ||
456 | FCALL_ERROR(fcall)); | ||
457 | |||
458 | kfree(fcall); | ||
459 | } | 454 | } |
460 | if (wfidno >= 0) { | 455 | if (wfidno >= 0) { |
461 | if (!v9fs_t_clunk(v9ses, wfidno, &fcall)) | 456 | err = v9fs_t_clunk(v9ses, wfidno); |
462 | v9fs_put_idpool(wfidno, &v9ses->fidpool); | 457 | if (err < 0) |
463 | else | 458 | dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); |
464 | dprintk(DEBUG_ERROR, "clunk failed: %s\n", | ||
465 | FCALL_ERROR(fcall)); | ||
466 | |||
467 | kfree(fcall); | ||
468 | } | 459 | } |
469 | return result; | 460 | return result; |
470 | } | 461 | } |
@@ -972,6 +963,7 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
972 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); | 963 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); |
973 | struct v9fs_fcall *fcall = NULL; | 964 | struct v9fs_fcall *fcall = NULL; |
974 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); | 965 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); |
966 | int err; | ||
975 | 967 | ||
976 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | 968 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, |
977 | symname); | 969 | symname); |
@@ -1004,9 +996,9 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
1004 | 996 | ||
1005 | kfree(fcall); | 997 | kfree(fcall); |
1006 | 998 | ||
1007 | if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) { | 999 | err = v9fs_t_clunk(v9ses, newfid->fid); |
1008 | dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n", | 1000 | if (err < 0) { |
1009 | FCALL_ERROR(fcall)); | 1001 | dprintk(DEBUG_ERROR, "clunk for symlink failed: %d\n", err); |
1010 | goto FreeFcall; | 1002 | goto FreeFcall; |
1011 | } | 1003 | } |
1012 | 1004 | ||
@@ -1180,6 +1172,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1180 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); | 1172 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); |
1181 | struct v9fs_fid *newfid = NULL; | 1173 | struct v9fs_fid *newfid = NULL; |
1182 | char *symname = __getname(); | 1174 | char *symname = __getname(); |
1175 | int err; | ||
1183 | 1176 | ||
1184 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | 1177 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, |
1185 | old_dentry->d_name.name); | 1178 | old_dentry->d_name.name); |
@@ -1216,9 +1209,10 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1216 | 1209 | ||
1217 | kfree(fcall); | 1210 | kfree(fcall); |
1218 | 1211 | ||
1219 | if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) { | 1212 | err = v9fs_t_clunk(v9ses, newfid->fid); |
1220 | dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n", | 1213 | |
1221 | FCALL_ERROR(fcall)); | 1214 | if (err < 0) { |
1215 | dprintk(DEBUG_ERROR, "clunk for symlink failed: %d\n", err); | ||
1222 | goto FreeMem; | 1216 | goto FreeMem; |
1223 | } | 1217 | } |
1224 | 1218 | ||
@@ -1252,6 +1246,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
1252 | struct v9fs_fcall *fcall = NULL; | 1246 | struct v9fs_fcall *fcall = NULL; |
1253 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); | 1247 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); |
1254 | char *symname = __getname(); | 1248 | char *symname = __getname(); |
1249 | int err; | ||
1255 | 1250 | ||
1256 | dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, | 1251 | dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, |
1257 | dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); | 1252 | dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); |
@@ -1310,9 +1305,9 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
1310 | /* need to update dcache so we show up */ | 1305 | /* need to update dcache so we show up */ |
1311 | kfree(fcall); | 1306 | kfree(fcall); |
1312 | 1307 | ||
1313 | if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) { | 1308 | err = v9fs_t_clunk(v9ses, newfid->fid); |
1314 | dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n", | 1309 | if (err < 0) { |
1315 | FCALL_ERROR(fcall)); | 1310 | dprintk(DEBUG_ERROR, "clunk for symlink failed: %d\n", err); |
1316 | goto FreeMem; | 1311 | goto FreeMem; |
1317 | } | 1312 | } |
1318 | 1313 | ||