Reviewed-by: Sage Weil <sage@xxxxxxxxxxx> On Thu, 13 Dec 2012, Alex Elder wrote: > If an osd has no requests and no linger requests, __reset_osd() > will just remove it with a call to __remove_osd(). That drops > a reference to the osd, and therefore the osd may have been free > by the time __reset_osd() returns. That function offers no > indication this may have occurred, and as a result the osd will > continue to be used even when it's no longer valid. > > Change__reset_osd() so it returns an error (ENODEV) when it > deletes the osd being reset. And change __kick_osd_requests() so it > returns immediately (before referencing osd again) if __reset_osd() > returns *any* error. > > Signed-off-by: Alex Elder <elder@xxxxxxxxxxx> > --- > net/ceph/osd_client.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c > index ac7be72..60c74c1 100644 > --- a/net/ceph/osd_client.c > +++ b/net/ceph/osd_client.c > @@ -581,7 +581,7 @@ static void __kick_osd_requests(struct > ceph_osd_client *osdc, > > dout("__kick_osd_requests osd%d\n", osd->o_osd); > err = __reset_osd(osdc, osd); > - if (err == -EAGAIN) > + if (err) > return; > > list_for_each_entry(req, &osd->o_requests, r_osd_item) { > @@ -745,6 +745,7 @@ static int __reset_osd(struct ceph_osd_client *osdc, > struct ceph_osd *osd) > if (list_empty(&osd->o_requests) && > list_empty(&osd->o_linger_requests)) { > __remove_osd(osdc, osd); > + ret = -ENODEV; > } else if (memcmp(&osdc->osdmap->osd_addr[osd->o_osd], > &osd->o_con.peer_addr, > sizeof(osd->o_con.peer_addr)) == 0 && > -- > 1.7.9.5 > > -- > To unsubscribe from this list: send the line "unsubscribe ceph-devel" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html