From patchwork Wed Sep 5 14:53:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Dryomov X-Patchwork-Id: 10589007 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B87B7920 for ; Wed, 5 Sep 2018 14:53:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9EC842A367 for ; Wed, 5 Sep 2018 14:53:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92D092A373; Wed, 5 Sep 2018 14:53:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0BF2A2A367 for ; Wed, 5 Sep 2018 14:53:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727494AbeIETYX (ORCPT ); Wed, 5 Sep 2018 15:24:23 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:33446 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726463AbeIETYX (ORCPT ); Wed, 5 Sep 2018 15:24:23 -0400 Received: by mail-wr1-f67.google.com with SMTP id v90-v6so8039035wrc.0 for ; Wed, 05 Sep 2018 07:53:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=bgynTZoE0td0R2480qYpHlp8FP775UyP1SRe9kESywk=; b=Vt1RkxJqYoJ87DxukkVtbdETEBDGUJU1h23HrEllij6H7yrgmEtE5NkwomfTsfgG9E R6G2qE4uucxgTBeYHlO+I4+V8N3vhdCKrYo0aywaangVWnNWN//KdgMaBoI00KyNTZle RJxCzQzOqwqdrj8VsUmRN32K3jrbjkD5CKJPEmcKbyQymEzE35NKH8x7x6g7f9jNkXOz bLQis7vr5XlKOJuFUgsgnAoaXf0pnMq3TnQ9VDKI476nyX0+/KgM7LdvVsEfWo08jVNC v+fvtX4O+smwow7+fockmVLPqrmf2VDoqz95hIhMadhDZl8S6Shs3Gux1BFtMM4jY1n3 qOJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=bgynTZoE0td0R2480qYpHlp8FP775UyP1SRe9kESywk=; b=LlIMwDFA0aL1yioObOR4dCzu4bc1NV8rw+W8WuAMcc2Rs04p+43kcB6/fLPsrteQI+ YEmEaTgvWLbjYXEx3dSh7+fTcaTVxF0xObLmm7b95a17b0NVoIeemItbehPAFtryi4QZ XhyMP/kDTFiIOHG8FHm0hers1KdAatiM40FF9Kk4CbNXKcf1EyZQ4G1oExbBRw3GkGu/ 4X2+1X5nKm5E8TNmK/aQ5ALtV1gq9OPxGznNv8VvTpC2VOMcKuhTLR/L29eDw+qGxdGS imEMfLCwPP/F+Afyq5bWm+bFRSrJ5wZbJC0u4x+4u9z+O/jiCCNta+AbGXSexzSZQ0KY mXgQ== X-Gm-Message-State: APzg51BGerdcFQ8EZMSi8sTgAMrDx9GayMORcdgM81wJfL7KKFAuJxMR hkgrzsrLrmbf5VHaQajCg6x5QQHJ X-Google-Smtp-Source: ANB0VdaiAngy9zvmyQhyuKbzD+0Gvseykno2L+OJUXkliVnQ2PrdNxUgEMuMnV9U83UMKm2MpQp9sQ== X-Received: by 2002:adf:9e93:: with SMTP id a19-v6mr27430715wrf.70.1536159228342; Wed, 05 Sep 2018 07:53:48 -0700 (PDT) Received: from orange.redhat.com ([213.175.37.12]) by smtp.gmail.com with ESMTPSA id j44-v6sm2517315wre.40.2018.09.05.07.53.47 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 05 Sep 2018 07:53:47 -0700 (PDT) From: Ilya Dryomov To: ceph-devel@vger.kernel.org Subject: [PATCH v2 1/2] rbd: factor out get_parent_info() Date: Wed, 5 Sep 2018 16:53:21 +0200 Message-Id: <20180905145322.7311-2-idryomov@gmail.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180905145322.7311-1-idryomov@gmail.com> References: <20180905145322.7311-1-idryomov@gmail.com> Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In preparation for the new parent_get and parent_overlap_get class methods, factor out the fetching and decoding of parent data. As a side effect, we now decode all four fields in the "no parent" case. Signed-off-by: Ilya Dryomov --- drivers/block/rbd.c | 134 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 48 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index d4d2e2ed4bd5..6116a2eb7f51 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4584,47 +4584,95 @@ static int rbd_dev_v2_features(struct rbd_device *rbd_dev) &rbd_dev->header.features); } +struct parent_image_info { + u64 pool_id; + const char *image_id; + u64 snap_id; + + u64 overlap; +}; + +/* + * The caller is responsible for @pii. + */ +static int __get_parent_info_legacy(struct rbd_device *rbd_dev, + struct page *req_page, + struct page *reply_page, + struct parent_image_info *pii) +{ + struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + size_t reply_len = PAGE_SIZE; + void *p, *end; + int ret; + + ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, + "rbd", "get_parent", CEPH_OSD_FLAG_READ, + req_page, sizeof(u64), reply_page, &reply_len); + if (ret) + return ret; + + p = page_address(reply_page); + end = p + reply_len; + ceph_decode_64_safe(&p, end, pii->pool_id, e_inval); + pii->image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL); + if (IS_ERR(pii->image_id)) { + ret = PTR_ERR(pii->image_id); + pii->image_id = NULL; + return ret; + } + ceph_decode_64_safe(&p, end, pii->snap_id, e_inval); + ceph_decode_64_safe(&p, end, pii->overlap, e_inval); + + return 0; + +e_inval: + return -EINVAL; +} + +static int get_parent_info(struct rbd_device *rbd_dev, + struct parent_image_info *pii) +{ + struct page *req_page, *reply_page; + void *p; + int ret; + + req_page = alloc_page(GFP_KERNEL); + if (!req_page) + return -ENOMEM; + + reply_page = alloc_page(GFP_KERNEL); + if (!reply_page) { + __free_page(req_page); + return -ENOMEM; + } + + p = page_address(req_page); + ceph_encode_64(&p, rbd_dev->spec->snap_id); + ret = __get_parent_info_legacy(rbd_dev, req_page, reply_page, pii); + + __free_page(req_page); + __free_page(reply_page); + return ret; +} + static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) { struct rbd_spec *parent_spec; - size_t size; - void *reply_buf = NULL; - __le64 snapid; - void *p; - void *end; - u64 pool_id; - char *image_id; - u64 snap_id; - u64 overlap; + struct parent_image_info pii = { 0 }; int ret; parent_spec = rbd_spec_alloc(); if (!parent_spec) return -ENOMEM; - size = sizeof (__le64) + /* pool_id */ - sizeof (__le32) + RBD_IMAGE_ID_LEN_MAX + /* image_id */ - sizeof (__le64) + /* snap_id */ - sizeof (__le64); /* overlap */ - reply_buf = kmalloc(size, GFP_KERNEL); - if (!reply_buf) { - ret = -ENOMEM; + ret = get_parent_info(rbd_dev, &pii); + if (ret) goto out_err; - } - snapid = cpu_to_le64(rbd_dev->spec->snap_id); - ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, - &rbd_dev->header_oloc, "get_parent", - &snapid, sizeof(snapid), reply_buf, size); - dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); - if (ret < 0) - goto out_err; + dout("%s pool_id %llu image_id %s snap_id %llu overlap %llu\n", + __func__, pii.pool_id, pii.image_id, pii.snap_id, pii.overlap); - p = reply_buf; - end = reply_buf + ret; - ret = -ERANGE; - ceph_decode_64_safe(&p, end, pool_id, out_err); - if (pool_id == CEPH_NOPOOL) { + if (pii.pool_id == CEPH_NOPOOL) { /* * Either the parent never existed, or we have * record of it but the image got flattened so it no @@ -4647,19 +4695,11 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) /* The ceph file layout needs to fit pool id in 32 bits */ ret = -EIO; - if (pool_id > (u64)U32_MAX) { + if (pii.pool_id > (u64)U32_MAX) { rbd_warn(NULL, "parent pool id too large (%llu > %u)", - (unsigned long long)pool_id, U32_MAX); - goto out_err; - } - - image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL); - if (IS_ERR(image_id)) { - ret = PTR_ERR(image_id); + (unsigned long long)pii.pool_id, U32_MAX); goto out_err; } - ceph_decode_64_safe(&p, end, snap_id, out_err); - ceph_decode_64_safe(&p, end, overlap, out_err); /* * The parent won't change (except when the clone is @@ -4667,9 +4707,10 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) * record the parent spec we have not already done so. */ if (!rbd_dev->parent_spec) { - parent_spec->pool_id = pool_id; - parent_spec->image_id = image_id; - parent_spec->snap_id = snap_id; + parent_spec->pool_id = pii.pool_id; + parent_spec->image_id = pii.image_id; + pii.image_id = NULL; + parent_spec->snap_id = pii.snap_id; /* TODO: support cloning across namespaces */ if (rbd_dev->spec->pool_ns) { @@ -4683,15 +4724,13 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) rbd_dev->parent_spec = parent_spec; parent_spec = NULL; /* rbd_dev now owns this */ - } else { - kfree(image_id); } /* * We always update the parent overlap. If it's zero we issue * a warning, as we will proceed as if there was no parent. */ - if (!overlap) { + if (!pii.overlap) { if (parent_spec) { /* refresh, careful to warn just once */ if (rbd_dev->parent_overlap) @@ -4702,14 +4741,13 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); } } - rbd_dev->parent_overlap = overlap; + rbd_dev->parent_overlap = pii.overlap; out: ret = 0; out_err: - kfree(reply_buf); + kfree(pii.image_id); rbd_spec_put(parent_spec); - return ret; }