aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_file.c
diff options
context:
space:
mode:
authorLatchesar Ionkov <lucho@ionkov.net>2006-05-15 09:44:21 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-05-15 11:20:56 -0700
commit41e5a6ac80c600e1f8bda0a4871f0b797e097d78 (patch)
treee2796bac0d285751d027eff931e31c0842669788 /fs/9p/vfs_file.c
parent[PATCH] v9fs: Twalk memory leak (diff)
downloadlinux-dev-41e5a6ac80c600e1f8bda0a4871f0b797e097d78.tar.xz
linux-dev-41e5a6ac80c600e1f8bda0a4871f0b797e097d78.zip
[PATCH] v9fs: signal handling fixes
Multiple races can happen when v9fs is interrupted by a signal and Tflush message is sent to the server. After v9fs sends Tflush it doesn't wait until it receives Rflush, and possibly the response of the original message. This behavior may confuse v9fs what fids are allocated by the file server. This patch fixes the races and the fid allocation. Signed-off-by: Latchesar Ionkov <lucho@ionkov.net> Cc: Eric Van Hensbergen <ericvh@hera.kernel.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/9p/vfs_file.c')
-rw-r--r--fs/9p/vfs_file.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 083dcfcd158e..1a8e46084f0e 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -72,11 +72,17 @@ int v9fs_file_open(struct inode *inode, struct file *file)
return -ENOSPC;
}
- err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL);
+ err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall);
if (err < 0) {
dprintk(DEBUG_ERROR, "rewalk didn't work\n");
- goto put_fid;
+ if (fcall && fcall->id == RWALK)
+ goto clunk_fid;
+ else {
+ v9fs_put_idpool(fid, &v9ses->fidpool);
+ goto free_fcall;
+ }
}
+ kfree(fcall);
/* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
/* translate open mode appropriately */
@@ -109,8 +115,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
clunk_fid:
v9fs_t_clunk(v9ses, fid);
-put_fid:
- v9fs_put_idpool(fid, &v9ses->fidpool);
+free_fcall:
kfree(fcall);
return err;