From patchwork Fri Sep 7 21:13:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 1425161 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 AE4D73FC71 for ; Fri, 7 Sep 2012 21:14:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757201Ab2IGVN7 (ORCPT ); Fri, 7 Sep 2012 17:13:59 -0400 Received: from mail-iy0-f174.google.com ([209.85.210.174]:59251 "EHLO mail-iy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757177Ab2IGVN7 (ORCPT ); Fri, 7 Sep 2012 17:13:59 -0400 Received: by mail-iy0-f174.google.com with SMTP id k25so21774iah.19 for ; Fri, 07 Sep 2012 14:13:58 -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=PWuV52A3e/V/u2Un9CeHM5kwnuKHoaZKxgF1YDFFCUI=; b=HTW/IZ8BQ55jkg5strC/1hB34cDB1yKqBUrufApoC8KKGo+CJYYmvrzUeKa7cQXc3R jUxLAzzVzFe/JH30du9uqQHRQAturoHkARuGQpspqtLlEp/ffsvCXQ+kXc6Cxx75QhPk EmBBUVagDZitzm372h09w7/rsWkPmjeoKu5955izuP+XY7DJN3yuaoCN6yY3Ro3H9xGs ksbOsR8PW00Vex20v7vhGGgWKrIXNWUMLPNGKI5xUXFsy2ZSqxVpcr9f3eYBf6sqgHV/ ZosdMxc0QN4PvmqpgIFltPqMXm2STTmb3JZvCEZTMWqw++0kcBoKPXkoM4WEvHwoE0mR 69jA== Received: by 10.50.194.136 with SMTP id hw8mr668560igc.11.1347052438774; Fri, 07 Sep 2012 14:13:58 -0700 (PDT) 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 y9sm857473igm.10.2012.09.07.14.13.56 (version=SSLv3 cipher=OTHER); Fri, 07 Sep 2012 14:13:57 -0700 (PDT) Message-ID: <504A6394.203@inktank.com> Date: Fri, 07 Sep 2012 16:13:56 -0500 From: Alex Elder User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120827 Thunderbird/15.0 MIME-Version: 1.0 To: ceph-devel@vger.kernel.org Subject: [PATCH 5/9] rbd: get the snapshot context for a v2 image References: <504A6273.7030807@inktank.com> In-Reply-To: <504A6273.7030807@inktank.com> X-Gm-Message-State: ALoCoQk4XyNIg1WrCUEhYLVBKYXJrQG5rnnSnq7/GiDRegcZRVif1ov48EH8YLH083BBsvi2cMOC Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org Fetch the snapshot context for an rbd format 2 image by calling the "get_snapcontext" method on its header object. Signed-off-by: Alex Elder Reviewed-by: Josh Durgin --- drivers/block/rbd.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) * newly-received snapshot context. Remove any existing snapshots @@ -2773,6 +2852,12 @@ static int rbd_dev_v2_probe(struct rbd_device *rbd_dev) ret = rbd_dev_v2_features(rbd_dev); if (ret < 0) goto out_err; + + /* Get the snapshot context */ + + ret = rbd_dev_v2_snap_context(rbd_dev); + if (ret) + goto out_err; rbd_dev->image_format = 2; dout("discovered version 2 image, header name is %s\n", diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index d48f025..8ff84fd 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -62,6 +62,7 @@ #define RBD_MINORS_PER_MAJOR 256 /* max minors per blkdev */ #define RBD_MAX_SNAP_NAME_LEN 32 +#define RBD_MAX_SNAP_COUNT 510 /* allows max snapc to fit in 4KB */ #define RBD_MAX_OPT_LEN 1024 #define RBD_SNAP_HEAD_NAME "-" @@ -2234,6 +2235,84 @@ static int rbd_dev_v2_features(struct rbd_device *rbd_dev) &rbd_dev->header.features); } +static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) +{ + size_t size; + int ret; + void *reply_buf; + void *p; + void *end; + u64 seq; + u32 snap_count; + struct ceph_snap_context *snapc; + u32 i; + + /* + * We'll need room for the seq value (maximum snapshot id), + * snapshot count, and array of that many snapshot ids. + * For now we have a fixed upper limit on the number we're + * prepared to receive. + */ + size = sizeof (__le64) + sizeof (__le32) + + RBD_MAX_SNAP_COUNT * sizeof (__le64); + reply_buf = kzalloc(size, GFP_KERNEL); + if (!reply_buf) + return -ENOMEM; + + ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, + "rbd", "get_snapcontext", + NULL, 0, + reply_buf, size, + CEPH_OSD_FLAG_READ, NULL); + dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); + if (ret < 0) + goto out; + + ret = -ERANGE; + p = reply_buf; + end = (char *) reply_buf + size; + ceph_decode_64_safe(&p, end, seq, out); + ceph_decode_32_safe(&p, end, snap_count, out); + + /* + * Make sure the reported number of snapshot ids wouldn't go + * beyond the end of our buffer. But before checking that, + * make sure the computed size of the snapshot context we + * allocate is representable in a size_t. + */ + if (snap_count > (SIZE_MAX - sizeof (struct ceph_snap_context)) + / sizeof (u64)) { + ret = -EINVAL; + goto out; + } + if (!ceph_has_room(&p, end, snap_count * sizeof (__le64))) + goto out; + + size = sizeof (struct ceph_snap_context) + + snap_count * sizeof (snapc->snaps[0]); + snapc = kmalloc(size, GFP_KERNEL); + if (!snapc) { + ret = -ENOMEM; + goto out; + } + + atomic_set(&snapc->nref, 1); + snapc->seq = seq; + snapc->num_snaps = snap_count; + for (i = 0; i < snap_count; i++) + snapc->snaps[i] = ceph_decode_64(&p); + + rbd_dev->header.snapc = snapc; + + dout(" snap context seq = %llu, snap_count = %u\n", + (unsigned long long) seq, (unsigned int) snap_count); + +out: + kfree(reply_buf); + + return 0; +} + /* * Scan the rbd device's current snapshot list and compare it to the