From patchwork Mon Jan 14 18:51:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 1973301 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 B60443FE33 for ; Mon, 14 Jan 2013 18:51:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757641Ab3ANSvH (ORCPT ); Mon, 14 Jan 2013 13:51:07 -0500 Received: from mail-ie0-f176.google.com ([209.85.223.176]:50605 "EHLO mail-ie0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757289Ab3ANSvG (ORCPT ); Mon, 14 Jan 2013 13:51:06 -0500 Received: by mail-ie0-f176.google.com with SMTP id 13so5464704iea.7 for ; Mon, 14 Jan 2013 10:51:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:message-id:date:from:user-agent:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding :x-gm-message-state; bh=XBMRjLoiy9SEZD7Z1sPp0ynUNhjl13/hdbAOWvffh9U=; b=mDoPGeqaKI5ADgFW7VFnyJ1iPoeYKneC8xEMqDgGYe+34uWxUbKWV4h9Py6zjZGwrM KfrVX6u2bf38DEGTRYDwg/aOA4Z8euxZRRy/hKdwV9lX7Ca3Fb5VPt5FyZ2Ks4Y+C2IE 7J3SpqVmMZC2qHu4pfts1Gt9TVrTc3G1MgLvbBQ6nwbZLyQXvxfcbBmPY0MqVhxyloCL mBrqIAHHFYt8Ae26k8yJXDW/HLuBeVgMUNo+QI66rdPX4oRNojRfvTv0mXnB4rslpf4L O72/ui1K6N0KuuEQH98X3lsAMen7ZEH/1i6w7069nFrzJ/L5xtQ5PJRCv3CMMSyhS8bc iPng== X-Received: by 10.50.7.235 with SMTP id m11mr1650267iga.61.1358189465633; Mon, 14 Jan 2013 10:51:05 -0800 (PST) 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 ww6sm7016385igb.2.2013.01.14.10.51.04 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 14 Jan 2013 10:51:04 -0800 (PST) Message-ID: <50F45397.2030905@inktank.com> Date: Mon, 14 Jan 2013 12:51:03 -0600 From: Alex Elder User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2 MIME-Version: 1.0 To: "ceph-devel@vger.kernel.org" Subject: [PATCH 2/2] rbd: prevent open for image being removed References: <50F4535A.6030601@inktank.com> In-Reply-To: <50F4535A.6030601@inktank.com> X-Gm-Message-State: ALoCoQlTvnfipAJ8DwMFJ7T/1/tpqPZYo2V+R+0rBZt8jUCMe0X/Ivbzjmof3rKjeRDqMIGxctEr Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org An open request for a mapped rbd image can arrive while removal of that mapping is underway. The control mutex and an open count is protect a mapped device that's in use from being removed. But it is possible for the removal of the mapping to reach the point of no return *after* a racing open has concluded it is OK to proceed. The result of this is not good. Define and use a flag to indicate a mapping is getting removed to avoid this problem. This addresses http://tracker.newdream.net/issues/3427 Signed-off-by: Alex Elder --- drivers/block/rbd.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) static int rbd_release(struct gendisk *disk, fmode_t mode) @@ -3796,6 +3802,7 @@ static ssize_t rbd_remove(struct bus_type *bus, ret = -EBUSY; goto done; } + set_bit(rbd_dev_flag_removing, &rbd_dev->flags); rbd_remove_all_snaps(rbd_dev); rbd_bus_del_dev(rbd_dev); diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 9eb1631..760f7f7 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -264,6 +264,7 @@ struct rbd_device { enum rbd_dev_flags { rbd_dev_flag_exists, /* mapped snapshot has not been deleted */ + rbd_dev_flag_removing, /* this mapping is being removed */ }; static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ @@ -351,17 +352,22 @@ static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev, u64 *hver); static int rbd_open(struct block_device *bdev, fmode_t mode) { struct rbd_device *rbd_dev = bdev->bd_disk->private_data; + int ret = 0; if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only) return -EROFS; mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); - (void) get_device(&rbd_dev->dev); - set_device_ro(bdev, rbd_dev->mapping.read_only); - rbd_dev->open_count++; + if (!test_bit(rbd_dev_flag_removing, &rbd_dev->flags)) { + (void) get_device(&rbd_dev->dev); + set_device_ro(bdev, rbd_dev->mapping.read_only); + rbd_dev->open_count++; + } else { + ret = -ENOENT; + } mutex_unlock(&ctl_mutex); - return 0; + return ret; }