From patchwork Sun Aug 26 10:23:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Dryomov X-Patchwork-Id: 10576257 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 B878E15A7 for ; Sun, 26 Aug 2018 10:23:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A493B29C73 for ; Sun, 26 Aug 2018 10:23:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 98D8F29C7A; Sun, 26 Aug 2018 10:23:48 +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 67F5C29C7B for ; Sun, 26 Aug 2018 10:23:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726643AbeHZOFs (ORCPT ); Sun, 26 Aug 2018 10:05:48 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:35478 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726415AbeHZOFs (ORCPT ); Sun, 26 Aug 2018 10:05:48 -0400 Received: by mail-wm0-f68.google.com with SMTP id o18-v6so5574742wmc.0 for ; Sun, 26 Aug 2018 03:23:38 -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=19N8LgN8+tQm1Fz2WMV21z9+SO0+/lt7msnlu7Cqj6A=; b=lSyEuGTWT+ui1fW5GlH1VsKvBv+njI4SVFgu8VC+4/L3B+3KoRZyQuyv0CHD7wJRYw lsOxM2fBmEvWJAfrAYveuOthsfQbhpatOs8KiL2SgWcaomlewItrpW3Fzw8yLOTKzPcc Uxf145HMk0voYwjXAh8MgKIuw15OXdSzKIy+huhHWonhKms/0/NnNaAiOwUVpAZW+cSz BzNztpdwJs9vfa2whNTeRtLz+gJOeKMFu6zh89EsODkjPE5VEIjxha06xzabByw7oUMx gBgIT8JmXYF0eY4zH6MVOCuWCBArxV++BGEKHBtmBPU81OKjGj3M9moEVGAXOlZ95pvf Bntg== 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=19N8LgN8+tQm1Fz2WMV21z9+SO0+/lt7msnlu7Cqj6A=; b=aUGK3CUWUApzJhj32pp9BJpA5/bCDfUsmEPvjeHAPfVF/v6X/USBxg7ENLg7bwlAwA 0H3ehpIhCmKhZMtNSTmS4VE+hkXME/2ST7UNeESJGcAedPBqhULzxWVftGEDSVG0vVbj X3QU3Atu0XZdyqoDDQhxv+jsz9pivjSnEpTn5dWVUZR3w+RSbl+X2rRxD78a4VCelZNo XmX+1Jrlkp6w2wzohLVSCbJmAwOr6MxkFaVGucEzGZDrCAxOqsNOogMKQGowlkJ+XltE t2Lcb/rFWFgd7pfDVx+9FB09wnQqDWujL+PK93LCjfVheKk6xj1yJEEBBkr7OABBCl/7 btGg== X-Gm-Message-State: APzg51DKiAZrVEaBatVZM4RV6aGM6wtjaGkWXpK3d5Mzl7inJRqWyI/5 jrvzXuypnEzcqdYTGiSfOkwHJOD+ X-Google-Smtp-Source: ANB0VdZWi1ZzwbjPg6pDbNMMUmu7lij0fBOq25f9P9ZNUPwgpI6Im3Oun1UigG5PgpC9millcHU3Uw== X-Received: by 2002:a1c:8e81:: with SMTP id q123-v6mr2934889wmd.56.1535279017215; Sun, 26 Aug 2018 03:23:37 -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.36 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 26 Aug 2018 03:23:36 -0700 (PDT) From: Ilya Dryomov To: ceph-devel@vger.kernel.org Subject: [PATCH 2/2] rbd: support cloning across namespaces Date: Sun, 26 Aug 2018 12:23:12 +0200 Message-Id: <20180826102312.19180-3-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 If parent_get class method is not supported by the OSDs, fall back to the legacy class method and assume that the parent is in the default (i.e. "") namespace. The "use the child's image namespace" workaround is no longer needed because creating images within namespaces will require parent_get aware OSDs. Signed-off-by: Ilya Dryomov Reviewed-by: Jason Dillaman --- drivers/block/rbd.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 13 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index e86ed5ee7337..45e20af8efb6 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4586,10 +4586,99 @@ static int rbd_dev_v2_features(struct rbd_device *rbd_dev) struct parent_image_spec { u64 pool_id; + const char *pool_ns; const char *image_id; u64 snap_id; }; +/* + * The caller is responsible for @pis. + */ +static int decode_parent_image_spec(void **p, void *end, + struct parent_image_spec *pis) +{ + u8 struct_v; + u32 struct_len; + int ret; + + ret = ceph_start_decoding(p, end, 1, "ParentImageSpec", + &struct_v, &struct_len); + if (ret) + return ret; + + ceph_decode_64_safe(p, end, pis->pool_id, e_inval); + pis->pool_ns = ceph_extract_encoded_string(p, end, NULL, GFP_KERNEL); + if (IS_ERR(pis->pool_ns)) { + ret = PTR_ERR(pis->pool_ns); + pis->pool_ns = NULL; + return ret; + } + 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; + return ret; + } + ceph_decode_64_safe(p, end, pis->snap_id, e_inval); + return 0; + +e_inval: + return -EINVAL; +} + +static int get_parent_info(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", "parent_get", 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; + ret = decode_parent_image_spec(&p, end, pis); + if (ret) + goto out; + + ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, + "rbd", "parent_overlap_get", 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, *overlap, e_inval); + +out: + __free_page(req_page); + __free_page(reply_page); + return ret; + +e_inval: + ret = -EINVAL; + goto out; +} + /* * The caller is responsible for @pis. */ @@ -4653,11 +4742,13 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) if (!parent_spec) return -ENOMEM; - ret = get_parent_info_legacy(rbd_dev, &pis, &overlap); + ret = get_parent_info(rbd_dev, &pis, &overlap); + if (ret == -EOPNOTSUPP) + 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, + dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu overlap %llu\n", + __func__, pis.pool_id, pis.pool_ns, pis.image_id, pis.snap_id, overlap); if (pis.pool_id == CEPH_NOPOOL) { @@ -4696,20 +4787,14 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) */ if (!rbd_dev->parent_spec) { parent_spec->pool_id = pis.pool_id; + if (pis.pool_ns && *pis.pool_ns) { + parent_spec->pool_ns = pis.pool_ns; + pis.pool_ns = NULL; + } 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) { - parent_spec->pool_ns = kstrdup(rbd_dev->spec->pool_ns, - GFP_KERNEL); - if (!parent_spec->pool_ns) { - ret = -ENOMEM; - goto out_err; - } - } - rbd_dev->parent_spec = parent_spec; parent_spec = NULL; /* rbd_dev now owns this */ } @@ -4734,6 +4819,7 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) out: ret = 0; out_err: + kfree(pis.pool_ns); kfree(pis.image_id); rbd_spec_put(parent_spec); return ret;