diff options
author | Latchesar Ionkov <lucho@ionkov.net> | 2006-05-15 09:44:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-15 11:20:56 -0700 |
commit | 41e5a6ac80c600e1f8bda0a4871f0b797e097d78 (patch) | |
tree | e2796bac0d285751d027eff931e31c0842669788 /fs/9p/vfs_file.c | |
parent | 343f1fe6f2e3fb4912db241e639b0721c2e14f2e (diff) | |
download | op-kernel-dev-41e5a6ac80c600e1f8bda0a4871f0b797e097d78.zip op-kernel-dev-41e5a6ac80c600e1f8bda0a4871f0b797e097d78.tar.gz |
[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.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 083dcfc..1a8e460 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; |