From patchwork Tue Jan 22 22:29:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 2021151 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id D4FD33FD1A for ; Tue, 22 Jan 2013 22:29:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752954Ab3AVW3w (ORCPT ); Tue, 22 Jan 2013 17:29:52 -0500 Received: from mail-ie0-f179.google.com ([209.85.223.179]:63511 "EHLO mail-ie0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752683Ab3AVW3v (ORCPT ); Tue, 22 Jan 2013 17:29:51 -0500 Received: by mail-ie0-f179.google.com with SMTP id k14so12466579iea.38 for ; Tue, 22 Jan 2013 14:29:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:message-id:date:from:user-agent:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding :x-gm-message-state; bh=c5ezUY6W+hTzERD6ad+pZF8L0P4LPMjvGiAHaIXjK6Q=; b=jS32siFkEXHPG1uLEfF92dQ13hvShO/qxhBnhSbE1A1ls8n0MvFicJ7mpaFZBz4gM8 Eu0GdEg1r+lxobapDPxau5vKZhpBnanmRzTHHgt+Ep/QJoV1zu3LFnHIHc5gb4Fbqawk vEXCdOtGXpBEUEa/sCHkpHTbZ6z79P9r2HpeT0T66IHzQ/m15O1X/SdD7vU6rxbBlPnb j0EQFyhC5YnnrjpNzogQpev3WQHAeNFMlLeCtX12AIDHsesLpMMmiO9di2ragEcmvOvH UUHsbNm9uyJqafkjUSbEGqshQ42eiwJHBw0cN7qbA1FQVu1i3jfySoPf9zIqz0Wu7IrA jfHg== X-Received: by 10.43.17.199 with SMTP id qd7mr15850768icb.52.1358893791253; Tue, 22 Jan 2013 14:29:51 -0800 (PST) Received: from [172.22.22.4] (c-71-195-31-37.hsd1.mn.comcast.net. [71.195.31.37]) by mx.google.com with ESMTPS id vq4sm11733055igb.10.2013.01.22.14.29.49 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 22 Jan 2013 14:29:50 -0800 (PST) Message-ID: <50FF12DC.2070609@inktank.com> Date: Tue, 22 Jan 2013 16:29:48 -0600 From: Alex Elder User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2 MIME-Version: 1.0 To: "ceph-devel@vger.kernel.org" Subject: [PATCH 06/12] rbd: implement watch/unwatch with new code References: <50FF11EA.3000808@inktank.com> In-Reply-To: <50FF11EA.3000808@inktank.com> X-Gm-Message-State: ALoCoQnb8t0CDgAxQUC8rFD/bWJLG5+v7bcpQLZiSUbdgVU6r9f8QWSL+hwf5oUu0XasOLIQ5QaZ Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org Implement a new function to set up or tear down a watch event for an mapped rbd image header using the new request code. Create a new object request type "nodata" to handle this. And define rbd_osd_trivial_callback() which simply marks a request done. Signed-off-by: Alex Elder --- drivers/block/rbd.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) return true; @@ -1491,6 +1492,12 @@ static void rbd_osd_write_callback(struct rbd_obj_request *obj_request, atomic_set(&obj_request->done, 1); } +static void rbd_osd_trivial_callback(struct rbd_obj_request *obj_request, + struct ceph_osd_op *op) +{ + atomic_set(&obj_request->done, 1); +} + static void rbd_obj_request_complete(struct rbd_obj_request *obj_request) { if (obj_request->callback) @@ -1527,6 +1534,9 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, case CEPH_OSD_OP_WRITE: rbd_osd_write_callback(obj_request, op); break; + case CEPH_OSD_OP_WATCH: + rbd_osd_trivial_callback(obj_request, op); + break; default: rbd_warn(NULL, "%s: unsupported op %hu\n", obj_request->object_name, (unsigned short) opcode); @@ -1570,6 +1580,8 @@ static struct ceph_osd_request *rbd_osd_req_create( rbd_assert(obj_req_type_valid(obj_request->type)); switch (obj_request->type) { + case obj_req_nodata: + break; /* Nothing to do */ case obj_req_bio: rbd_assert(obj_request->bio_list != NULL); osd_req->r_bio = obj_request->bio_list; @@ -1658,6 +1670,8 @@ static void rbd_obj_request_destroy(struct kref *kref) rbd_assert(obj_req_type_valid(obj_request->type)); switch (obj_request->type) { + case obj_req_nodata: + break; /* Nothing to do */ case obj_req_bio: if (obj_request->bio_list) bio_chain_put(obj_request->bio_list); @@ -1854,6 +1868,72 @@ static int rbd_image_request_submit(struct rbd_image_request *image_request) return ret; } +/* + * Request sync osd watch/unwatch. The value of "start" determines + * whether a watch request is being initiated or torn down. + */ +static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) +{ + struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + struct rbd_obj_request *obj_request; + struct ceph_osd_req_op *op; + int ret; + + rbd_assert(start ^ !!rbd_dev->watch_event); + rbd_assert(start ^ !!rbd_dev->watch_request); + + if (start) { + ret = ceph_osdc_create_event(osdc, rbd_watch_cb, 0, rbd_dev, + &rbd_dev->watch_event); + if (ret < 0) + return ret; + } + + ret = -ENOMEM; + obj_request = rbd_obj_request_create(rbd_dev->header_name, + 0, 0, obj_req_nodata); + if (!obj_request) + goto out_cancel; + + op = rbd_osd_req_op_create(CEPH_OSD_OP_WATCH, + rbd_dev->watch_event->cookie, + rbd_dev->header.obj_version, start); + if (!op) + goto out_cancel; + obj_request->osd_req = rbd_osd_req_create(rbd_dev, true, + obj_request, op); + rbd_osd_req_op_destroy(op); + if (!obj_request->osd_req) + goto out_cancel; + + if (start) { + rbd_dev->watch_request = obj_request->osd_req; + ceph_osdc_set_request_linger(osdc, rbd_dev->watch_request); + } + ret = rbd_obj_request_submit(osdc, obj_request); + if (ret) + goto out_cancel; + ret = rbd_obj_request_wait(obj_request); + if (ret) + goto out_cancel; + + ret = obj_request->result; + if (ret) + goto out_cancel; + + if (start) + goto done; /* Done if setting up the watch request */ +out_cancel: + /* Cancel the event if we're tearing down, or on error */ + ceph_osdc_cancel_event(rbd_dev->watch_event); + rbd_dev->watch_event = NULL; +done: + if (obj_request) + rbd_obj_request_put(obj_request); + + return ret; +} + static void rbd_request_fn(struct request_queue *q) { struct rbd_device *rbd_dev = q->queuedata; @@ -3876,7 +3956,8 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) if (ret) goto err_out_bus; - ret = rbd_req_sync_watch(rbd_dev, 1); + (void) rbd_req_sync_watch; /* avoid a warning */ + ret = rbd_dev_header_watch_sync(rbd_dev, 1); if (ret) goto err_out_bus; @@ -4039,7 +4120,7 @@ static void rbd_dev_release(struct device *dev) rbd_dev->watch_request); } if (rbd_dev->watch_event) - rbd_req_sync_watch(rbd_dev, 0); + rbd_dev_header_watch_sync(rbd_dev, 0); /* clean up and free blkdev */ rbd_free_disk(rbd_dev); diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 6193c69..3c110b3 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -164,7 +164,7 @@ struct rbd_client { struct rbd_image_request; -enum obj_req_type { obj_req_bio, obj_req_pages }; +enum obj_req_type { obj_req_nodata, obj_req_bio, obj_req_pages }; struct rbd_obj_request; typedef void (*rbd_obj_callback_t)(struct rbd_obj_request *); @@ -1071,6 +1071,7 @@ static void rbd_image_request_put(struct rbd_image_request *image_request) static bool obj_req_type_valid(enum obj_req_type type) { switch (type) { + case obj_req_nodata: case obj_req_bio: case obj_req_pages: