--- /dev/null
+From 5f64737fb44ee280362a1be280f26adb38c689e4 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Fri, 14 Dec 2012 16:47:41 -0600
+Subject: libceph: report connection fault with warning
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 28362986f8743124b3a0fda20a8ed3e80309cce1)
+
+When a connection's socket disconnects, or if there's a protocol
+error of some kind on the connection, a fault is signaled and
+the connection is reset (closed and reopened, basically). We
+currently get an error message on the log whenever this occurs.
+
+A ceph connection will attempt to reestablish a socket connection
+repeatedly if a fault occurs. This means that these error messages
+will get repeatedly added to the log, which is undesirable.
+
+Change the error message to be a warning, so they don't get
+logged by default.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -2369,7 +2369,7 @@ fault:
+ static void ceph_fault(struct ceph_connection *con)
+ __releases(con->mutex)
+ {
+- pr_err("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
++ pr_warning("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
+ ceph_pr_addr(&con->peer_addr.in_addr), con->error_msg);
+ dout("fault %p state %lu to peer %s\n",
+ con, con->state, ceph_pr_addr(&con->peer_addr.in_addr));
--- /dev/null
+From d49d943a24d4addbb5c6d1e4feb45bb98b2885fa Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Thu, 6 Dec 2012 07:22:04 -0600
+Subject: libceph: init osd->o_node in create_osd()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit f407731d12214e7686819018f3a1e9d7b6f83a02)
+
+The red-black node node in the ceph osd structure is not initialized
+in create_osd(). Because this node can be the subject of a
+RB_EMPTY_NODE() call later on, we should ensure the node is
+initialized properly for that. Add a call to RB_CLEAR_NODE()
+initialize it.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -647,6 +647,7 @@ static struct ceph_osd *create_osd(struc
+ atomic_set(&osd->o_ref, 1);
+ osd->o_osdc = osdc;
+ osd->o_osd = onum;
++ RB_CLEAR_NODE(&osd->o_node);
+ INIT_LIST_HEAD(&osd->o_requests);
+ INIT_LIST_HEAD(&osd->o_linger_requests);
+ INIT_LIST_HEAD(&osd->o_osd_lru);
--- /dev/null
+From b4c0c6243efad1ae18a8aa17694952fd6c13bbaa Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Mon, 17 Dec 2012 12:23:48 -0600
+Subject: libceph: init event->node in ceph_osdc_create_event()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 3ee5234df68d253c415ba4f2db72ad250d9c21a9)
+
+The red-black node node in the ceph osd event structure is not
+initialized in create_osdc_create_event(). Because this node can
+be the subject of a RB_EMPTY_NODE() call later on, we should ensure
+the node is initialized properly for that.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1600,6 +1600,7 @@ int ceph_osdc_create_event(struct ceph_o
+ event->data = data;
+ event->osdc = osdc;
+ INIT_LIST_HEAD(&event->osd_node);
++ RB_CLEAR_NODE(&event->node);
+ kref_init(&event->kref); /* one ref for us */
+ kref_get(&event->kref); /* one ref for the caller */
+ init_completion(&event->completion);
--- /dev/null
+From f660813d76b3634c39c2b3ed8715af7e9db14f9c Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Mon, 17 Dec 2012 12:23:48 -0600
+Subject: libceph: don't use rb_init_node() in ceph_osdc_alloc_request()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit a978fa20fb657548561dddbfb605fe43654f0825)
+
+The red-black node in the ceph osd request structure is initialized
+in ceph_osdc_alloc_request() using rbd_init_node(). We do need to
+initialize this, because in __unregister_request() we call
+RB_EMPTY_NODE(), which expects the node it's checking to have
+been initialized. But rb_init_node() is apparently overkill, and
+may in fact be on its way out. So use RB_CLEAR_NODE() instead.
+
+For a little more background, see this commit:
+ 4c199a93 rbtree: empty nodes have no color"
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -221,6 +221,7 @@ struct ceph_osd_request *ceph_osdc_alloc
+ kref_init(&req->r_kref);
+ init_completion(&req->r_completion);
+ init_completion(&req->r_safe_completion);
++ RB_CLEAR_NODE(&req->r_node);
+ INIT_LIST_HEAD(&req->r_unsafe_item);
+ INIT_LIST_HEAD(&req->r_linger_item);
+ INIT_LIST_HEAD(&req->r_linger_osd);
--- /dev/null
+From c9ddd2cac5e5e9bf278a9c08976592972a2d15c1 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Thu, 6 Dec 2012 07:22:04 -0600
+Subject: libceph: register request before unregister linger
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit c89ce05e0c5a01a256100ac6a6019f276bdd1ca6)
+
+In kick_requests(), we need to register the request before we
+unregister the linger request. Otherwise the unregister will
+reset the request's osd pointer to NULL.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1366,8 +1366,8 @@ static void kick_requests(struct ceph_os
+
+ dout("kicking lingering %p tid %llu osd%d\n", req, req->r_tid,
+ req->r_osd ? req->r_osd->o_osd : -1);
+- __unregister_linger_request(osdc, req);
+ __register_request(osdc, req);
++ __unregister_linger_request(osdc, req);
+ }
+ mutex_unlock(&osdc->request_mutex);
+
--- /dev/null
+From d92a42b79c755e911495bd36316d2573804293ea Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 19 Dec 2012 15:52:36 -0600
+Subject: libceph: move linger requests sooner in kick_requests()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit ab60b16d3c31b9bd9fd5b39f97dc42c52a50b67d)
+
+The kick_requests() function is called by ceph_osdc_handle_map()
+when an osd map change has been indicated. Its purpose is to
+re-queue any request whose target osd is different from what it
+was when it was originally sent.
+
+It is structured as two loops, one for incomplete but registered
+requests, and a second for handling completed linger requests.
+As a special case, in the first loop if a request marked to linger
+has not yet completed, it is moved from the request list to the
+linger list. This is as a quick and dirty way to have the second
+loop handle sending the request along with all the other linger
+requests.
+
+Because of the way it's done now, however, this quick and dirty
+solution can result in these incomplete linger requests never
+getting re-sent as desired. The problem lies in the fact that
+the second loop only arranges for a linger request to be sent
+if it appears its target osd has changed. This is the proper
+handling for *completed* linger requests (it avoids issuing
+the same linger request twice to the same osd).
+
+But although the linger requests added to the list in the first loop
+may have been sent, they have not yet completed, so they need to be
+re-sent regardless of whether their target osd has changed.
+
+The first required fix is we need to avoid calling __map_request()
+on any incomplete linger request. Otherwise the subsequent
+__map_request() call in the second loop will find the target osd
+has not changed and will therefore not re-send the request.
+
+Second, we need to be sure that a sent but incomplete linger request
+gets re-sent. If the target osd is the same with the new osd map as
+it was when the request was originally sent, this won't happen.
+This can be fixed through careful handling when we move these
+requests from the request list to the linger list, by unregistering
+the request *before* it is registered as a linger request. This
+works because a side-effect of unregistering the request is to make
+the request's r_osd pointer be NULL, and *that* will ensure the
+second loop actually re-sends the linger request.
+
+Processing of such a request is done at that point, so continue with
+the next one once it's been moved.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 30 +++++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 11 deletions(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1322,6 +1322,24 @@ static void kick_requests(struct ceph_os
+ for (p = rb_first(&osdc->requests); p; ) {
+ req = rb_entry(p, struct ceph_osd_request, r_node);
+ p = rb_next(p);
++
++ /*
++ * For linger requests that have not yet been
++ * registered, move them to the linger list; they'll
++ * be sent to the osd in the loop below. Unregister
++ * the request before re-registering it as a linger
++ * request to ensure the __map_request() below
++ * will decide it needs to be sent.
++ */
++ if (req->r_linger && list_empty(&req->r_linger_item)) {
++ dout("%p tid %llu restart on osd%d\n",
++ req, req->r_tid,
++ req->r_osd ? req->r_osd->o_osd : -1);
++ __unregister_request(osdc, req);
++ __register_linger_request(osdc, req);
++ continue;
++ }
++
+ err = __map_request(osdc, req, force_resend);
+ if (err < 0)
+ continue; /* error */
+@@ -1336,17 +1354,6 @@ static void kick_requests(struct ceph_os
+ req->r_flags |= CEPH_OSD_FLAG_RETRY;
+ }
+ }
+- if (req->r_linger && list_empty(&req->r_linger_item)) {
+- /*
+- * register as a linger so that we will
+- * re-submit below and get a new tid
+- */
+- dout("%p tid %llu restart on osd%d\n",
+- req, req->r_tid,
+- req->r_osd ? req->r_osd->o_osd : -1);
+- __register_linger_request(osdc, req);
+- __unregister_request(osdc, req);
+- }
+ }
+
+ list_for_each_entry_safe(req, nreq, &osdc->req_linger,
+@@ -1354,6 +1361,7 @@ static void kick_requests(struct ceph_os
+ dout("linger req=%p req->r_osd=%p\n", req, req->r_osd);
+
+ err = __map_request(osdc, req, force_resend);
++ dout("__map_request returned %d\n", err);
+ if (err == 0)
+ continue; /* no change and no osd was specified */
+ if (err < 0)
--- /dev/null
+From 8cc1491a5d9e720f0b6f69244fc1548597bb868b Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 26 Dec 2012 14:31:40 -0600
+Subject: libceph: always reset osds when kicking
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit e6d50f67a6b1a6252a616e6e629473b5c4277218)
+
+When ceph_osdc_handle_map() is called to process a new osd map,
+kick_requests() is called to ensure all affected requests are
+updated if necessary to reflect changes in the osd map. This
+happens in two cases: whenever an incremental map update is
+processed; and when a full map update (or the last one if there is
+more than one) gets processed.
+
+In the former case, the kick_requests() call is followed immediately
+by a call to reset_changed_osds() to ensure any connections to osds
+affected by the map change are reset. But for full map updates
+this isn't done.
+
+Both cases should be doing this osd reset.
+
+Rather than duplicating the reset_changed_osds() call, move it into
+the end of kick_requests().
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1308,7 +1308,7 @@ static void reset_changed_osds(struct ce
+ * Requeue requests whose mapping to an OSD has changed. If requests map to
+ * no osd, request a new map.
+ *
+- * Caller should hold map_sem for read and request_mutex.
++ * Caller should hold map_sem for read.
+ */
+ static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
+ {
+@@ -1383,6 +1383,7 @@ static void kick_requests(struct ceph_os
+ dout("%d requests for down osds, need new map\n", needmap);
+ ceph_monc_request_next_osdmap(&osdc->client->monc);
+ }
++ reset_changed_osds(osdc);
+ }
+
+
+@@ -1439,7 +1440,6 @@ void ceph_osdc_handle_map(struct ceph_os
+ osdc->osdmap = newmap;
+ }
+ kick_requests(osdc, 0);
+- reset_changed_osds(osdc);
+ } else {
+ dout("ignoring incremental map %u len %d\n",
+ epoch, maplen);
--- /dev/null
+From b95ad0140dc8d2375bff4b0f30f6832cbb29e17c Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 26 Dec 2012 10:43:57 -0600
+Subject: libceph: WARN, don't BUG on unexpected connection states
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 122070a2ffc91f87fe8e8493eb0ac61986c5557c)
+
+A number of assertions in the ceph messenger are implemented with
+BUG_ON(), killing the system if connection's state doesn't match
+what's expected. At this point our state model is (evidently) not
+well understood enough for these assertions to trigger a BUG().
+Convert all BUG_ON(con->state...) calls to be WARN_ON(con->state...)
+so we learn about these issues without killing the machine.
+
+We now recognize that a connection fault can occur due to a socket
+closure at any time, regardless of the state of the connection. So
+there is really nothing we can assert about the state of the
+connection at that point so eliminate that assertion.
+
+Reported-by: Ugis <ugis22@gmail.com>
+Tested-by: Ugis <ugis22@gmail.com>
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -561,7 +561,7 @@ void ceph_con_open(struct ceph_connectio
+ mutex_lock(&con->mutex);
+ dout("con_open %p %s\n", con, ceph_pr_addr(&addr->in_addr));
+
+- BUG_ON(con->state != CON_STATE_CLOSED);
++ WARN_ON(con->state != CON_STATE_CLOSED);
+ con->state = CON_STATE_PREOPEN;
+
+ con->peer_name.type = (__u8) entity_type;
+@@ -1509,7 +1509,7 @@ static int process_banner(struct ceph_co
+ static void fail_protocol(struct ceph_connection *con)
+ {
+ reset_connection(con);
+- BUG_ON(con->state != CON_STATE_NEGOTIATING);
++ WARN_ON(con->state != CON_STATE_NEGOTIATING);
+ con->state = CON_STATE_CLOSED;
+ }
+
+@@ -1635,7 +1635,7 @@ static int process_connect(struct ceph_c
+ return -1;
+ }
+
+- BUG_ON(con->state != CON_STATE_NEGOTIATING);
++ WARN_ON(con->state != CON_STATE_NEGOTIATING);
+ con->state = CON_STATE_OPEN;
+
+ con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
+@@ -2132,7 +2132,6 @@ more:
+ if (ret < 0)
+ goto out;
+
+- BUG_ON(con->state != CON_STATE_CONNECTING);
+ con->state = CON_STATE_NEGOTIATING;
+
+ /*
+@@ -2160,7 +2159,7 @@ more:
+ goto more;
+ }
+
+- BUG_ON(con->state != CON_STATE_OPEN);
++ WARN_ON(con->state != CON_STATE_OPEN);
+
+ if (con->in_base_pos < 0) {
+ /*
+@@ -2374,7 +2373,7 @@ static void ceph_fault(struct ceph_conne
+ dout("fault %p state %lu to peer %s\n",
+ con, con->state, ceph_pr_addr(&con->peer_addr.in_addr));
+
+- BUG_ON(con->state != CON_STATE_CONNECTING &&
++ WARN_ON(con->state != CON_STATE_CONNECTING &&
+ con->state != CON_STATE_NEGOTIATING &&
+ con->state != CON_STATE_OPEN);
+
drm-i915-disable-cpt-phase-pointer-fdi-rx-workaround.patch
kvm-ppc-44x-fix-dcr-read-write.patch
0001-libceph-socket-can-close-in-any-connection-state.patch
+0002-libceph-report-connection-fault-with-warning.patch
+0003-libceph-init-osd-o_node-in-create_osd.patch
+0004-libceph-init-event-node-in-ceph_osdc_create_event.patch
+0005-libceph-don-t-use-rb_init_node-in-ceph_osdc_alloc_re.patch
+0006-libceph-register-request-before-unregister-linger.patch
+0007-libceph-move-linger-requests-sooner-in-kick_requests.patch
+0008-libceph-always-reset-osds-when-kicking.patch
+0009-libceph-WARN-don-t-BUG-on-unexpected-connection-stat.patch