From patchwork Fri May 19 13:37:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 9737279 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 162C16034C for ; Fri, 19 May 2017 13:38:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E841528815 for ; Fri, 19 May 2017 13:38:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCB672892F; Fri, 19 May 2017 13:38:03 +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=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, 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 0B6E028815 for ; Fri, 19 May 2017 13:38:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755053AbdESNiC (ORCPT ); Fri, 19 May 2017 09:38:02 -0400 Received: from mail-lf0-f46.google.com ([209.85.215.46]:36549 "EHLO mail-lf0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753421AbdESNiB (ORCPT ); Fri, 19 May 2017 09:38:01 -0400 Received: by mail-lf0-f46.google.com with SMTP id h4so1210180lfj.3 for ; Fri, 19 May 2017 06:38:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=orImYDu1V2LCCACrRI/UDIodhkBB7DwM/urezQ0MwFA=; b=GzoCNwERs/dkNoQdRNkFn3OobK/IWEynsfR06vCxWtWpMn7amlVFX5Z2kDnj/NS3Dq HvmC+zv+1Y+DtBpkPct2OUQfVKTHHa7x0HOTpz68m1G47Dt9X0CTCtwplZFiI5pLGR/B MRZ+Ml76jeZiGXgXAnlNdhncNSuNpB2xazQ4o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=orImYDu1V2LCCACrRI/UDIodhkBB7DwM/urezQ0MwFA=; b=JRoA2E3C2dTbWgzWqXzFOnkGZzZxivaglGUdy2DXOivG+74DH7/aiPhmZf5Sg4d11+ JwOSpM/MWCcv/zk5NUdwVykftz/IXPYxnqCMmDlvgXj0pI+F9/Z9wDxSmWPIUPnhGBHf X+rbhVUh4DhvBOtqxeEg9B4DuMmihwsnMcQe0wKZaigYAy3SGtSP8fo2CeaEkWZgrq+D hxBELJnR4cj8mDnRTI1unRwSnE18U4VhrCe7c3JeYsl3wMHPg5irY3rVFbaZpxWghxSn C5Qwa1NuwEjN+4bKk2BAHjpj7xj1x9blAQ0oD5FqkySbxn3Y2A5nxXOLLEhXQR0q6G9o f7KA== X-Gm-Message-State: AODbwcAPYlZ5gFLsbAtRTCbLcf6ft07DGD8kPk6btP+TCW3WPkW9tWpy vXJww3bBpPsQhrGSOQPfSQ== X-Received: by 10.25.181.80 with SMTP id e77mr2089324lff.98.1495201079707; Fri, 19 May 2017 06:37:59 -0700 (PDT) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id 19sm1514130ljf.32.2017.05.19.06.37.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 19 May 2017 06:37:58 -0700 (PDT) From: Linus Walleij To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter Cc: linux-block@vger.kernel.org, Jens Axboe , Christoph Hellwig , Arnd Bergmann , Bartlomiej Zolnierkiewicz , Paolo Valente , Avri Altman , Linus Walleij Subject: [PATCH 4/6] mmc: block: Move boot partition locking into a driver op Date: Fri, 19 May 2017 15:37:30 +0200 Message-Id: <20170519133732.27470-5-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170519133732.27470-1-linus.walleij@linaro.org> References: <20170519133732.27470-1-linus.walleij@linaro.org> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This moves the boot partition lock command (issued from sysfs) into a custom block layer request, just like the ioctl()s, getting rid of yet another instance of mmc_get_card(). Since we now have two operations issuing special DRV_OP's, we rename the result variable ->drv_op_result. Tested by locking the boot partition from userspace: > cd /sys/devices/platform/soc/80114000.sdi4_per2/mmc_host/mmc3/ mmc3:0001/block/mmcblk3/mmcblk3boot0 > echo 1 > ro_lock_until_next_power_on [ 178.645324] mmcblk3boot1: Locking boot partition ro until next power on [ 178.652221] mmcblk3boot0: Locking boot partition ro until next power on Also tested this with a huge dd job in the background: it is now possible to lock the boot partitions on the card even under heavy I/O. Signed-off-by: Linus Walleij --- drivers/mmc/core/block.c | 53 +++++++++++++++++++++++++++--------------------- drivers/mmc/core/queue.h | 4 +++- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 75b1baacf28b..52635120a0a5 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -190,6 +190,8 @@ static ssize_t power_ro_lock_store(struct device *dev, int ret; struct mmc_blk_data *md, *part_md; struct mmc_card *card; + struct mmc_queue *mq; + struct request *req; unsigned long set; if (kstrtoul(buf, 0, &set)) @@ -199,20 +201,14 @@ static ssize_t power_ro_lock_store(struct device *dev, return count; md = mmc_blk_get(dev_to_disk(dev)); + mq = &md->queue; card = md->queue.card; - mmc_get_card(card); - - ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, - card->ext_csd.boot_ro_lock | - EXT_CSD_BOOT_WP_B_PWR_WP_EN, - card->ext_csd.part_time); - if (ret) - pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret); - else - card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN; - - mmc_put_card(card); + /* Dispatch locking to the block layer */ + req = blk_get_request(mq->queue, REQ_OP_DRV_OUT, __GFP_RECLAIM); + req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_BOOT_WP; + blk_execute_rq(mq->queue, NULL, req, 0); + ret = req_to_mmc_queue_req(req)->drv_op_result; if (!ret) { pr_info("%s: Locking boot partition ro until next power on\n", @@ -606,7 +602,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, req_to_mmc_queue_req(req)->idata = idatas; req_to_mmc_queue_req(req)->ioc_count = 1; blk_execute_rq(mq->queue, NULL, req, 0); - ioc_err = req_to_mmc_queue_req(req)->ioc_result; + ioc_err = req_to_mmc_queue_req(req)->drv_op_result; err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata); blk_put_request(req); @@ -682,7 +678,7 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, req_to_mmc_queue_req(req)->idata = idata; req_to_mmc_queue_req(req)->ioc_count = num_of_cmds; blk_execute_rq(mq->queue, NULL, req, 0); - ioc_err = req_to_mmc_queue_req(req)->ioc_result; + ioc_err = req_to_mmc_queue_req(req)->drv_op_result; /* copy to user if data and response */ for (i = 0; i < num_of_cmds && !err; i++) @@ -1195,7 +1191,7 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) struct mmc_queue_req *mq_rq; struct mmc_card *card = mq->card; struct mmc_blk_data *md = mq->blkdata; - int ioc_err; + int ret; int i; mq_rq = req_to_mmc_queue_req(req); @@ -1203,23 +1199,34 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) switch (mq_rq->drv_op) { case MMC_DRV_OP_IOCTL: for (i = 0; i < mq_rq->ioc_count; i++) { - ioc_err = - __mmc_blk_ioctl_cmd(card, md, mq_rq->idata[i]); - if (ioc_err) + ret = __mmc_blk_ioctl_cmd(card, md, mq_rq->idata[i]); + if (ret) break; } - mq_rq->ioc_result = ioc_err; - /* Always switch back to main area after RPMB access */ if (md->area_type & MMC_BLK_DATA_AREA_RPMB) mmc_blk_part_switch(card, dev_get_drvdata(&card->dev)); - - blk_end_request_all(req, ioc_err); + break; + case MMC_DRV_OP_BOOT_WP: + ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, + card->ext_csd.boot_ro_lock | + EXT_CSD_BOOT_WP_B_PWR_WP_EN, + card->ext_csd.part_time); + if (ret) + pr_err("%s: Locking boot partition ro until next power on failed: %d\n", + md->disk->disk_name, ret); + else + card->ext_csd.boot_ro_lock |= + EXT_CSD_BOOT_WP_B_PWR_WP_EN; break; default: - /* Unknown operation */ + pr_err("%s: unknown driver specific operation\n", + md->disk->disk_name); + ret = -EINVAL; break; } + mq_rq->drv_op_result = ret; + blk_end_request_all(req, ret); } static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index 1e6062eb3e07..361b46408e0f 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h @@ -35,9 +35,11 @@ struct mmc_blk_request { /** * enum mmc_drv_op - enumerates the operations in the mmc_queue_req * @MMC_DRV_OP_IOCTL: ioctl operation + * @MMC_DRV_OP_BOOT_WP: write protect boot partitions */ enum mmc_drv_op { MMC_DRV_OP_IOCTL, + MMC_DRV_OP_BOOT_WP, }; struct mmc_queue_req { @@ -48,7 +50,7 @@ struct mmc_queue_req { unsigned int bounce_sg_len; struct mmc_async_req areq; enum mmc_drv_op drv_op; - int ioc_result; + int drv_op_result; struct mmc_blk_ioc_data **idata; unsigned int ioc_count; };