From patchwork Tue Oct 30 21:14:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 1674121 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 5F96CDFF3D for ; Tue, 30 Oct 2012 21:14:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934653Ab2J3VOg (ORCPT ); Tue, 30 Oct 2012 17:14:36 -0400 Received: from mail-ie0-f174.google.com ([209.85.223.174]:65013 "EHLO mail-ie0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934577Ab2J3VOf (ORCPT ); Tue, 30 Oct 2012 17:14:35 -0400 Received: by mail-ie0-f174.google.com with SMTP id k13so1115418iea.19 for ; Tue, 30 Oct 2012 14:14:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding :x-gm-message-state; bh=Ne7BlMRv+S4jlfSl755zc/bOo3Lr3yCi/nlEfRo6w0E=; b=GEzRfSVoornJuZd/OddJIWiRQFv1bDWBSlXFjV/RO/zCCzmKB6gHonbUz3Chvg8BIX 08WYoOwlDxNDndB1sZC9yVIPj4xijWYo0kYZX72JOG4LxATJRgSokW9K/TpG+xg3j8AR rMkiE345a8ceYtzy2675t3UXZLZAP1r7rNe0RXTf3+ouXsrmGyv/D2zy016AmUCr3JRh dS9CQN7vHawspaTz2acSeDlWLRUOYz+EAfHoGIPp7Tp98DjYQaPCSypDaH48cmIv1kDu N4PLqf2AEjJRg1CZezpOE/5Y1WT8fpUDUO+q8GLvj++px284tEk2sySybCT9oEHADvNq 6xnQ== Received: by 10.50.185.230 with SMTP id ff6mr2843998igc.7.1351631674484; Tue, 30 Oct 2012 14:14:34 -0700 (PDT) Received: from [172.22.22.4] (c-24-118-242-216.hsd1.mn.comcast.net. [24.118.242.216]) by mx.google.com with ESMTPS id ez8sm1445535igb.17.2012.10.30.14.14.33 (version=SSLv3 cipher=OTHER); Tue, 30 Oct 2012 14:14:33 -0700 (PDT) Message-ID: <50904337.5090509@inktank.com> Date: Tue, 30 Oct 2012 16:14:31 -0500 From: Alex Elder User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121011 Thunderbird/16.0.1 MIME-Version: 1.0 To: ceph-devel@vger.kernel.org Subject: [PATCH 3/4] rbd: define rbd_dev_{create,destroy}() helpers References: <50904265.2050603@inktank.com> In-Reply-To: <50904265.2050603@inktank.com> X-Gm-Message-State: ALoCoQmsj8QwzClpcg2skHbRfhJaPwbfOXg/qlwH8i1/I2t7jsu7h9LrLJYPFE9vZACSjYiUiok7 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org Encapsulate the creation/initialization and destruction of rbd device structures. The rbd_client and the rbd_spec structures provided on creation hold references whose ownership is transferred to the new rbd_device structure. Signed-off-by: Alex Elder Reviewed-by: Josh Durgin --- drivers/block/rbd.c | 62 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 4771de2..a8ad8f8 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -504,7 +504,8 @@ static void rbd_client_release(struct kref *kref) */ static void rbd_put_client(struct rbd_client *rbdc) { - kref_put(&rbdc->kref, rbd_client_release); + if (rbdc) + kref_put(&rbdc->kref, rbd_client_release); } /* @@ -2166,6 +2167,34 @@ static void rbd_spec_free(struct kref *kref) kfree(spec); } +struct rbd_device *rbd_dev_create(struct rbd_client *rbdc, + struct rbd_spec *spec) +{ + struct rbd_device *rbd_dev; + + rbd_dev = kzalloc(sizeof (*rbd_dev), GFP_KERNEL); + if (!rbd_dev) + return NULL; + + spin_lock_init(&rbd_dev->lock); + INIT_LIST_HEAD(&rbd_dev->node); + INIT_LIST_HEAD(&rbd_dev->snaps); + init_rwsem(&rbd_dev->header_rwsem); + + rbd_dev->spec = spec; + rbd_dev->rbd_client = rbdc; + + return rbd_dev; +} + +static void rbd_dev_destroy(struct rbd_device *rbd_dev) +{ + kfree(rbd_dev->header_name); + rbd_put_client(rbd_dev->rbd_client); + rbd_spec_put(rbd_dev->spec); + kfree(rbd_dev); +} + static bool rbd_snap_registered(struct rbd_snap *snap) { bool ret = snap->dev.type == &rbd_snap_device_type; @@ -3242,7 +3271,7 @@ static ssize_t rbd_add(struct bus_type *bus, rc = PTR_ERR(rbdc); goto err_out_args; } - ceph_opts = NULL; /* ceph_opts now owned by rbd_dev client */ + ceph_opts = NULL; /* rbd_dev client now owns this */ /* pick the pool */ osdc = &rbdc->client->osdc; @@ -3251,22 +3280,19 @@ static ssize_t rbd_add(struct bus_type *bus, goto err_out_client; spec->pool_id = (u64) rc; - rbd_dev = kzalloc(sizeof (*rbd_dev), GFP_KERNEL); + rbd_dev = rbd_dev_create(rbdc, spec); if (!rbd_dev) goto err_out_client; - - spin_lock_init(&rbd_dev->lock); - INIT_LIST_HEAD(&rbd_dev->node); - INIT_LIST_HEAD(&rbd_dev->snaps); - init_rwsem(&rbd_dev->header_rwsem); - rbd_dev->rbd_client = rbdc; - rbd_dev->spec = spec; + rbdc = NULL; /* rbd_dev now owns this */ + spec = NULL; /* rbd_dev now owns this */ rbd_dev->mapping.read_only = rbd_opts->read_only; + kfree(rbd_opts); + rbd_opts = NULL; /* done with this */ rc = rbd_dev_probe(rbd_dev); if (rc < 0) - goto err_out_mem; + goto err_out_rbd_dev; /* no need to lock here, as rbd_dev is not registered yet */ rc = rbd_dev_snaps_update(rbd_dev); @@ -3317,8 +3343,6 @@ static ssize_t rbd_add(struct bus_type *bus, if (rc) goto err_out_bus; - kfree(rbd_opts); - /* Everything's ready. Announce the disk to the world. */ add_disk(rbd_dev->disk); @@ -3332,7 +3356,6 @@ err_out_bus: /* this will also clean up rest of rbd_dev stuff */ rbd_bus_del_dev(rbd_dev); - kfree(rbd_opts); return rc; @@ -3346,9 +3369,8 @@ err_out_snaps: rbd_remove_all_snaps(rbd_dev); err_out_probe: rbd_header_free(&rbd_dev->header); - kfree(rbd_dev->header_name); -err_out_mem: - kfree(rbd_dev); +err_out_rbd_dev: + rbd_dev_destroy(rbd_dev); err_out_client: rbd_put_client(rbdc); err_out_args: @@ -3394,7 +3416,6 @@ static void rbd_dev_release(struct device *dev) if (rbd_dev->watch_event) rbd_req_sync_unwatch(rbd_dev); - rbd_put_client(rbd_dev->rbd_client); /* clean up and free blkdev */ rbd_free_disk(rbd_dev); @@ -3404,10 +3425,9 @@ static void rbd_dev_release(struct device *dev) rbd_header_free(&rbd_dev->header); /* done with the id, and with the rbd_dev */ - kfree(rbd_dev->header_name); rbd_dev_id_put(rbd_dev); - rbd_spec_put(rbd_dev->spec); - kfree(rbd_dev); + rbd_assert(rbd_dev->rbd_client != NULL); + rbd_dev_destroy(rbd_dev); /* release module ref */ module_put(THIS_MODULE);