From patchwork Sun Aug 26 10:23:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Dryomov X-Patchwork-Id: 10576259 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 2C25A1805 for ; Sun, 26 Aug 2018 10:23:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1832829C73 for ; Sun, 26 Aug 2018 10:23:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0C89429C7A; Sun, 26 Aug 2018 10:23:49 +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 3DB6029C77 for ; Sun, 26 Aug 2018 10:23:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726604AbeHZOFr (ORCPT ); Sun, 26 Aug 2018 10:05:47 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:36059 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726433AbeHZOFr (ORCPT ); Sun, 26 Aug 2018 10:05:47 -0400 Received: by mail-wm0-f66.google.com with SMTP id j192-v6so5575282wmj.1 for ; Sun, 26 Aug 2018 03:23:37 -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=5bprgxI3U3YORL6WGHukNSDfFnsEb24yTLFNpHM3To4=; b=sJLGs0un4qVpTzfoNBGtDygQzM5kiGUfxS+1K+X6K12d1umoqUnjQ8Vp2s/KtbTKNm 0E2eY2XvRkG5bpXFapHXdwwHd+8w9pn2tInJlje1GexaA+9Rdx6F2e1whHmur5Ut87JC LqCbMwyJ0Udqx+jy7DClvSv/Hzb7B8tQQGEksDIHmndiyVEPVrFg2fowijiV9saa0c7Q Cd81idtomCqkufzw6YUnXeIqn2v9yuZgH3u7cnyGnbAUj+MY4kqW470Ad0o9SWpSnmeb W2fcst8WQsS9sITwGMWE/t8dUuMufHUnjMbqKNz3J3zPnLEGwizRNJI0thE68p8uv960 XBVQ== 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=5bprgxI3U3YORL6WGHukNSDfFnsEb24yTLFNpHM3To4=; b=uKMTM/lpjJ7rVULWxYdNDi8MLIkmzGd7G5gehj0eXovSWClr/ZsuRhnK5A+v1t8/D5 GCQgcecp1txMbKQUPqtST0tole5qmk9+fd183ZBq3boc7mw+FJWT8Vsf/vSV37LSn3Ku /SWHGILdmX1wegpZZT71wSkIDW9jqW85933dXDwEN9dz62CGDc5isOr4Us0pHqnYAw6Q B0NTzRS0ZsSPcMkp3k2H1Ebm+vKB1K8mk8wQ2biWLRiXQ7cStStVV0k3rmG05VWByLUl cD2CMuV/AD7M1+hfQ/ORofQvZr0dG8YU+f04PPXY2ADzl5jZ2kCjFvddvhcFglYaaeQV xn+g== X-Gm-Message-State: APzg51BzLrJK2vaLc+f0ZiKePRg8OLfo6BX4Vct+rYXZiS9KfBtopJi4 xpg6RYehDduTluvabR6kAKItse06 X-Google-Smtp-Source: ANB0VdZlJtNBe/5RtsN8gThhAoE4u+aDFqOjZwGGumv3VqMaQhg29bKnDozYjrqKyIN/1ViIdShcPQ== X-Received: by 2002:a1c:d98a:: with SMTP id q132-v6mr3123449wmg.78.1535279016356; Sun, 26 Aug 2018 03:23:36 -0700 (PDT) Received: from orange.local (ip-86-49-115-215.net.upcbroadband.cz. [86.49.115.215]) by smtp.gmail.com with ESMTPSA id r17-v6sm14510061wmb.11.2018.08.26.03.23.35 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 26 Aug 2018 03:23:35 -0700 (PDT) From: Ilya Dryomov To: ceph-devel@vger.kernel.org Subject: [PATCH 1/2] rbd: factor out get_parent_info_legacy() Date: Sun, 26 Aug 2018 12:23:11 +0200 Message-Id: <20180826102312.19180-2-idryomov@gmail.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180826102312.19180-1-idryomov@gmail.com> References: <20180826102312.19180-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 | 120 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 47 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index d4d2e2ed4bd5..e86ed5ee7337 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4584,47 +4584,83 @@ static int rbd_dev_v2_features(struct rbd_device *rbd_dev) &rbd_dev->header.features); } +struct parent_image_spec { + u64 pool_id; + const char *image_id; + u64 snap_id; +}; + +/* + * The caller is responsible for @pis. + */ +static int get_parent_info_legacy(struct rbd_device *rbd_dev, + struct parent_image_spec *pis, u64 *overlap) +{ + struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + struct page *req_page, *reply_page; + size_t reply_len = PAGE_SIZE; + void *p, *end; + 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 = 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) + goto out; + + p = page_address(reply_page); + end = p + reply_len; + ceph_decode_64_safe(&p, end, pis->pool_id, e_inval); + pis->image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL); + if (IS_ERR(pis->image_id)) { + ret = PTR_ERR(pis->image_id); + pis->image_id = NULL; + goto out; + } + ceph_decode_64_safe(&p, end, pis->snap_id, e_inval); + ceph_decode_64_safe(&p, end, *overlap, e_inval); + +out: + __free_page(req_page); + __free_page(reply_page); + return ret; + +e_inval: + ret = -EINVAL; + goto out; +} + 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_spec pis = { 0 }; + u64 uninitialized_var(overlap); 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; - 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) + ret = get_parent_info_legacy(rbd_dev, &pis, &overlap); + if (ret) goto out_err; + dout("%s pool_id %llu image_id %s snap_id %llu overlap %llu\n", + __func__, pis.pool_id, pis.image_id, pis.snap_id, + 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 (pis.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 +4683,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 (pis.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)pis.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 +4695,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 = pis.pool_id; + parent_spec->image_id = pis.image_id; + pis.image_id = NULL; + parent_spec->snap_id = pis.snap_id; /* TODO: support cloning across namespaces */ if (rbd_dev->spec->pool_ns) { @@ -4683,8 +4712,6 @@ 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); } /* @@ -4707,9 +4734,8 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) out: ret = 0; out_err: - kfree(reply_buf); + kfree(pis.image_id); rbd_spec_put(parent_spec); - return ret; }