From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Sage Weil <sage@inktank.com>,
Josh Durgin <josh.durgin@inktank.com>
Subject: [PATCH 3.4 02/13] libceph: resend all writes after the osdmap loses the full flag
Date: Fri, 28 Mar 2014 10:31:52 -0700 [thread overview]
Message-ID: <20140328173053.390128975@linuxfoundation.org> (raw)
In-Reply-To: <20140328173053.049244535@linuxfoundation.org>
3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Durgin <josh.durgin@inktank.com>
commit 9a1ea2dbff11547a8e664f143c1ffefc586a577a upstream.
With the current full handling, there is a race between osds and
clients getting the first map marked full. If the osd wins, it will
return -ENOSPC to any writes, but the client may already have writes
in flight. This results in the client getting the error and
propagating it up the stack. For rbd, the block layer turns this into
EIO, which can cause corruption in filesystems above it.
To avoid this race, osds are being changed to drop writes that came
from clients with an osdmap older than the last osdmap marked full.
In order for this to work, clients must resend all writes after they
encounter a full -> not full transition in the osdmap. osds will wait
for an updated map instead of processing a request from a client with
a newer map, so resent writes will not be dropped by the osd unless
there is another not full -> full transition.
This approach requires both osds and clients to be fixed to avoid the
race. Old clients talking to osds with this fix may hang instead of
returning EIO and potentially corrupting an fs. New clients talking to
old osds have the same behavior as before if they encounter this race.
Fixes: http://tracker.ceph.com/issues/6938
Reviewed-by: Sage Weil <sage@inktank.com>
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ceph/osd_client.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -1269,14 +1269,17 @@ static void reset_changed_osds(struct ce
*
* Caller should hold map_sem for read.
*/
-static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
+static void kick_requests(struct ceph_osd_client *osdc, bool force_resend,
+ bool force_resend_writes)
{
struct ceph_osd_request *req, *nreq;
struct rb_node *p;
int needmap = 0;
int err;
+ bool force_resend_req;
- dout("kick_requests %s\n", force_resend ? " (force resend)" : "");
+ dout("kick_requests %s %s\n", force_resend ? " (force resend)" : "",
+ force_resend_writes ? " (force resend writes)" : "");
mutex_lock(&osdc->request_mutex);
for (p = rb_first(&osdc->requests); p; ) {
req = rb_entry(p, struct ceph_osd_request, r_node);
@@ -1299,7 +1302,10 @@ static void kick_requests(struct ceph_os
continue;
}
- err = __map_request(osdc, req, force_resend);
+ force_resend_req = force_resend ||
+ (force_resend_writes &&
+ req->r_flags & CEPH_OSD_FLAG_WRITE);
+ err = __map_request(osdc, req, force_resend_req);
if (err < 0)
continue; /* error */
if (req->r_osd == NULL) {
@@ -1319,7 +1325,8 @@ static void kick_requests(struct ceph_os
r_linger_item) {
dout("linger req=%p req->r_osd=%p\n", req, req->r_osd);
- err = __map_request(osdc, req, force_resend);
+ err = __map_request(osdc, req,
+ force_resend || force_resend_writes);
dout("__map_request returned %d\n", err);
if (err == 0)
continue; /* no change and no osd was specified */
@@ -1361,6 +1368,7 @@ void ceph_osdc_handle_map(struct ceph_os
struct ceph_osdmap *newmap = NULL, *oldmap;
int err;
struct ceph_fsid fsid;
+ bool was_full;
dout("handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0);
p = msg->front.iov_base;
@@ -1374,6 +1382,8 @@ void ceph_osdc_handle_map(struct ceph_os
down_write(&osdc->map_sem);
+ was_full = ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL);
+
/* incremental maps */
ceph_decode_32_safe(&p, end, nr_maps, bad);
dout(" %d inc maps\n", nr_maps);
@@ -1398,7 +1408,10 @@ void ceph_osdc_handle_map(struct ceph_os
ceph_osdmap_destroy(osdc->osdmap);
osdc->osdmap = newmap;
}
- kick_requests(osdc, 0);
+ was_full = was_full ||
+ ceph_osdmap_flag(osdc->osdmap,
+ CEPH_OSDMAP_FULL);
+ kick_requests(osdc, 0, was_full);
} else {
dout("ignoring incremental map %u len %d\n",
epoch, maplen);
@@ -1441,7 +1454,10 @@ void ceph_osdc_handle_map(struct ceph_os
skipped_map = 1;
ceph_osdmap_destroy(oldmap);
}
- kick_requests(osdc, skipped_map);
+ was_full = was_full ||
+ ceph_osdmap_flag(osdc->osdmap,
+ CEPH_OSDMAP_FULL);
+ kick_requests(osdc, skipped_map, was_full);
}
p += maplen;
nr_maps--;
next prev parent reply other threads:[~2014-03-28 17:31 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-28 17:31 [PATCH 3.4 00/13] 3.4.85-stable review Greg Kroah-Hartman
2014-03-28 17:31 ` [PATCH 3.4 01/13] ALSA: compress: Pass through return value of open ops callback Greg Kroah-Hartman
2014-03-28 17:31 ` Greg Kroah-Hartman [this message]
2014-03-28 17:31 ` [PATCH 3.4 03/13] iwlwifi: Complete backport of "iwlwifi: always copy first 16 bytes of commands" Greg Kroah-Hartman
2014-03-28 17:31 ` [PATCH 3.4 04/13] x86: bpf_jit: support negative offsets Greg Kroah-Hartman
2014-03-28 17:31 ` [PATCH 3.4 05/13] deb-pkg: Fix cross-building linux-headers package Greg Kroah-Hartman
2014-03-28 17:31 ` [PATCH 3.4 06/13] p54: clamp properly instead of just truncating Greg Kroah-Hartman
2014-03-28 17:31 ` [PATCH 3.4 07/13] i7300_edac: Fix device reference count Greg Kroah-Hartman
2014-03-28 17:31 ` [PATCH 3.4 08/13] ARM: move outer_cache declaration out of ifdef Greg Kroah-Hartman
2014-03-28 17:31 ` [PATCH 3.4 09/13] Input: elantech - improve clickpad detection Greg Kroah-Hartman
2014-03-28 17:32 ` [PATCH 3.4 10/13] KVM: MMU: handle invalid root_hpa at __direct_map Greg Kroah-Hartman
2014-03-28 17:32 ` [PATCH 3.4 11/13] KVM: VMX: fix use after free of vmx->loaded_vmcs Greg Kroah-Hartman
2014-03-28 17:32 ` [PATCH 3.4 12/13] xhci: Fix resume issues on Renesas chips in Samsung laptops Greg Kroah-Hartman
2014-03-28 17:32 ` [PATCH 3.4 13/13] ipc/msg: fix race around refcount Greg Kroah-Hartman
2014-03-29 1:00 ` [PATCH 3.4 00/13] 3.4.85-stable review Guenter Roeck
2014-03-30 1:26 ` Shuah Khan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140328173053.390128975@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=josh.durgin@inktank.com \
--cc=linux-kernel@vger.kernel.org \
--cc=sage@inktank.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).