diff options
author | Alex Elder <elder@inktank.com> | 2013-04-15 11:18:01 -0500 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-01 21:18:51 -0700 |
commit | 7d7d51ce14fde491a6d0677d9bded9b3bd0d21d9 (patch) | |
tree | c351dc531724bcb8002ab60e847737c8d8617955 | |
parent | 0b93267252ef5fe6c6d77e3013ed6a0d766352ad (diff) | |
download | linux-3.10-7d7d51ce14fde491a6d0677d9bded9b3bd0d21d9.tar.gz linux-3.10-7d7d51ce14fde491a6d0677d9bded9b3bd0d21d9.tar.bz2 linux-3.10-7d7d51ce14fde491a6d0677d9bded9b3bd0d21d9.zip |
ceph: let osd client clean up for interrupted request
In ceph_sync_write(), if a safe callback is supplied with a request,
and an error is returned by ceph_osdc_wait_request(), a block of
code is executed to remove the request from the unsafe writes list
and drop references to capabilities acquired just prior to a call to
ceph_osdc_wait_request().
The only function used for this callback is sync_write_commit(),
and it does *exactly* what that block of error handling code does.
Now in ceph_osdc_wait_request(), if an error occurs (due to an
interupt during a wait_for_completion_interruptible() call),
complete_request() gets called, and that calls the request's
safe_callback method if it's defined.
So this means that this cleanup activity gets called twice in this
case, which is erroneous (and in fact leads to a crash).
Fix this by just letting the osd client handle the cleanup in
the event of an interrupt.
This resolves one problem mentioned in:
http://tracker.ceph.com/issues/4706
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Yan, Zheng <zheng.z.yan@intel.com>
-rw-r--r-- | fs/ceph/file.c | 6 |
1 files changed, 0 insertions, 6 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 0f9c4095614..ae23e31a8f3 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -595,12 +595,6 @@ more: } ret = ceph_osdc_wait_request(&fsc->client->osdc, req); - if (ret < 0 && req->r_safe_callback) { - spin_lock(&ci->i_unsafe_lock); - list_del_init(&req->r_unsafe_item); - spin_unlock(&ci->i_unsafe_lock); - ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR); - } } if (file->f_flags & O_DIRECT) |