Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4195638imu; Tue, 18 Dec 2018 10:32:44 -0800 (PST) X-Google-Smtp-Source: AFSGD/VgSV9pJ+PhSn0j6Hf39F0EXuVtWqqA9uuXZJezrrFL69jqwJAvMWM1YNzmZC0iCjRIecl/ X-Received: by 2002:a62:4c5:: with SMTP id 188mr17839933pfe.130.1545157964670; Tue, 18 Dec 2018 10:32:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545157964; cv=none; d=google.com; s=arc-20160816; b=FablJxbLsv+6mgriYr0PRrXX2K34tM62EjTQKYrAbFXnJMb7uqviRYbecbELixvPKK mOYhD3q7d7YVKywp+qEPvYIhjrgN2IApZqs47Fwba6G3GZW9tibUm4Mhv6+GCg4Tf5Cn VqUKweorO7GA9EijKllJYhvpA/jJhNJK1ZGOxY3fEjeMuVPfgLr9Kg4msmJ65DnJ6dJq KimruuhRB8OFlJvu6QfatoIVcMxUQi3lwiVRmP3sUBucNPN4FfnYG6OCRQgXwsp6ilJj bkc1IBytcoXO3Sk95db+mD3LgBAbAHpi9fcELzRxMQ1SChToU12mhM8jIzL6rcIOjCP9 cQKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=l6YVrIhMREEMrm3h8bkywJNlfp6ts/A1Uv1A35dTWmE=; b=BfT91jFoGOO+H2pkao0d91ciNoiE5Gy0j2DoEdI3gDtN0SO5CPw1fAZCfLOJfJIk+n wng9I663idQmWIeWnocoCfijicCI1tUS+pPwHITaBX1wn0VMJeQvnunI4levrBCecc5F srTdhEwPOdSOY54qCJoSZ9OzonwekPIcMbhd9iDsnPuFKqG1RTM1Se7z/Z3deVwwkcYX GGKddmAyUW3+vgFT0jE0g7XJ55UmgdNXSkA8n185jYChY46V0INOgGnDG3wZGb+SZwfZ liXAQIkMAD9bGxlv8vSRlVbhXfvHQ87nsYFtzEIrfqU+yZa+p++i004rEDyMZ76BESPA 4QDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=m2yeDila; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c9si9777430pll.439.2018.12.18.10.32.25; Tue, 18 Dec 2018 10:32:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=m2yeDila; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727368AbeLRQkt (ORCPT + 99 others); Tue, 18 Dec 2018 11:40:49 -0500 Received: from mail.kernel.org ([198.145.29.99]:37928 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726639AbeLRQkq (ORCPT ); Tue, 18 Dec 2018 11:40:46 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 78BA921873; Tue, 18 Dec 2018 16:40:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1545151245; bh=cnBtbNBkjhT0m/KVc0kjKLdw05HPguOo9EM8isPnMJo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m2yeDilaGyKjJUPC8DSSwgvKGlxMeKTWi93B1e1yK+rNMZc3Lqp0vbRwgNPH5GOPA snKi7A5rEkHb9fu85P35bicke8eMD8NdPsYLVPx0pkTZR6wX0+TNig4EN8hRxoB+Rh r/q5wpeq5JTyw/hodg8Lf2OFN+ROuK+ewTWIyjs8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mike Snitzer Subject: [PATCH 4.19 24/44] dm thin: send event about thin-pool state change _after_ making it Date: Tue, 18 Dec 2018 17:39:36 +0100 Message-Id: <20181218163930.326675612@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20181218163927.119623235@linuxfoundation.org> References: <20181218163927.119623235@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mike Snitzer commit f6c367585d0d851349d3a9e607c43e5bea993fa1 upstream. Sending a DM event before a thin-pool state change is about to happen is a bug. It wasn't realized until it became clear that userspace response to the event raced with the actual state change that the event was meant to notify about. Fix this by first updating internal thin-pool state to reflect what the DM event is being issued about. This fixes a long-standing racey/buggy userspace device-mapper-test-suite 'resize_io' test that would get an event but not find the state it was looking for -- so it would just go on to hang because no other events caused the test to reevaluate the thin-pool's state. Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-thin.c | 68 ++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 33 deletions(-) --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -195,7 +195,7 @@ static void throttle_unlock(struct throt struct dm_thin_new_mapping; /* - * The pool runs in 4 modes. Ordered in degraded order for comparisons. + * The pool runs in various modes. Ordered in degraded order for comparisons. */ enum pool_mode { PM_WRITE, /* metadata may be changed */ @@ -282,9 +282,38 @@ struct pool { mempool_t mapping_pool; }; -static enum pool_mode get_pool_mode(struct pool *pool); static void metadata_operation_failed(struct pool *pool, const char *op, int r); +static enum pool_mode get_pool_mode(struct pool *pool) +{ + return pool->pf.mode; +} + +static void notify_of_pool_mode_change(struct pool *pool) +{ + const char *descs[] = { + "write", + "out-of-data-space", + "read-only", + "read-only", + "fail" + }; + const char *extra_desc = NULL; + enum pool_mode mode = get_pool_mode(pool); + + if (mode == PM_OUT_OF_DATA_SPACE) { + if (!pool->pf.error_if_no_space) + extra_desc = " (queue IO)"; + else + extra_desc = " (error IO)"; + } + + dm_table_event(pool->ti->table); + DMINFO("%s: switching pool to %s%s mode", + dm_device_name(pool->pool_md), + descs[(int)mode], extra_desc ? : ""); +} + /* * Target context for a pool. */ @@ -2351,8 +2380,6 @@ static void do_waker(struct work_struct queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD); } -static void notify_of_pool_mode_change_to_oods(struct pool *pool); - /* * We're holding onto IO to allow userland time to react. After the * timeout either the pool will have been resized (and thus back in @@ -2365,7 +2392,7 @@ static void do_no_space_timeout(struct w if (get_pool_mode(pool) == PM_OUT_OF_DATA_SPACE && !pool->pf.error_if_no_space) { pool->pf.error_if_no_space = true; - notify_of_pool_mode_change_to_oods(pool); + notify_of_pool_mode_change(pool); error_retry_list_with_code(pool, BLK_STS_NOSPC); } } @@ -2433,26 +2460,6 @@ static void noflush_work(struct thin_c * /*----------------------------------------------------------------*/ -static enum pool_mode get_pool_mode(struct pool *pool) -{ - return pool->pf.mode; -} - -static void notify_of_pool_mode_change(struct pool *pool, const char *new_mode) -{ - dm_table_event(pool->ti->table); - DMINFO("%s: switching pool to %s mode", - dm_device_name(pool->pool_md), new_mode); -} - -static void notify_of_pool_mode_change_to_oods(struct pool *pool) -{ - if (!pool->pf.error_if_no_space) - notify_of_pool_mode_change(pool, "out-of-data-space (queue IO)"); - else - notify_of_pool_mode_change(pool, "out-of-data-space (error IO)"); -} - static bool passdown_enabled(struct pool_c *pt) { return pt->adjusted_pf.discard_passdown; @@ -2501,8 +2508,6 @@ static void set_pool_mode(struct pool *p switch (new_mode) { case PM_FAIL: - if (old_mode != new_mode) - notify_of_pool_mode_change(pool, "failure"); dm_pool_metadata_read_only(pool->pmd); pool->process_bio = process_bio_fail; pool->process_discard = process_bio_fail; @@ -2516,8 +2521,6 @@ static void set_pool_mode(struct pool *p case PM_OUT_OF_METADATA_SPACE: case PM_READ_ONLY: - if (!is_read_only_pool_mode(old_mode)) - notify_of_pool_mode_change(pool, "read-only"); dm_pool_metadata_read_only(pool->pmd); pool->process_bio = process_bio_read_only; pool->process_discard = process_bio_success; @@ -2538,8 +2541,6 @@ static void set_pool_mode(struct pool *p * alarming rate. Adjust your low water mark if you're * frequently seeing this mode. */ - if (old_mode != new_mode) - notify_of_pool_mode_change_to_oods(pool); pool->out_of_data_space = true; pool->process_bio = process_bio_read_only; pool->process_discard = process_discard_bio; @@ -2552,8 +2553,6 @@ static void set_pool_mode(struct pool *p break; case PM_WRITE: - if (old_mode != new_mode) - notify_of_pool_mode_change(pool, "write"); if (old_mode == PM_OUT_OF_DATA_SPACE) cancel_delayed_work_sync(&pool->no_space_timeout); pool->out_of_data_space = false; @@ -2573,6 +2572,9 @@ static void set_pool_mode(struct pool *p * doesn't cause an unexpected mode transition on resume. */ pt->adjusted_pf.mode = new_mode; + + if (old_mode != new_mode) + notify_of_pool_mode_change(pool); } static void abort_transaction(struct pool *pool)