From patchwork Wed Jan 21 10:10:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 5676191 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 87B019F2ED for ; Wed, 21 Jan 2015 10:11:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 99A2420503 for ; Wed, 21 Jan 2015 10:11:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6E4F8202C8 for ; Wed, 21 Jan 2015 10:11:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752805AbbAUKLD (ORCPT ); Wed, 21 Jan 2015 05:11:03 -0500 Received: from userp1040.oracle.com ([156.151.31.81]:46278 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750916AbbAUKLA (ORCPT ); Wed, 21 Jan 2015 05:11:00 -0500 Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t0LAAw8A009655 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 21 Jan 2015 10:10:59 GMT Received: from userz7021.oracle.com (userz7021.oracle.com [156.151.31.85]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id t0LAAu5E027987 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 21 Jan 2015 10:10:58 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id t0LAAuon027963; Wed, 21 Jan 2015 10:10:56 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 21 Jan 2015 02:10:55 -0800 Date: Wed, 21 Jan 2015 02:10:54 -0800 From: "Darrick J. Wong" To: "Martin K. Petersen" Cc: axboe@kernel.dk, linux-scsi@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH] block: create ioctl to discard-or-zeroout a range of blocks Message-ID: <20150121101054.GA9978@birch.djwong.org> References: <1421802390-7380-1-git-send-email-martin.petersen@oracle.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1421802390-7380-1-git-send-email-martin.petersen@oracle.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: ucsinet21.oracle.com [156.151.31.93] Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Create a new ioctl to expose the block layer's newfound ability to issue either a zeroing discard, a WRITE SAME with a zero page, or a regular write with the zero page. This BLKZEROOUT2 ioctl takes {start, length, flags} as parameters. So far, the only flag available is to enable the zeroing discard part -- without it, the call invokes the old BLKZEROOUT behavior. start and length have the same meaning as in BLKZEROOUT. Furthermore, because BLKZEROOUT2 issues commands directly to the storage device, we must invalidate the page cache (as a regular O_DIRECT write would do) to avoid returning stale cache contents at a later time. Depends on "block: Add discard flag to blkdev_issue_zeroout() function". Signed-off-by: Darrick J. Wong --- block/ioctl.c | 45 ++++++++++++++++++++++++++++++++++++++------- include/uapi/linux/fs.h | 7 +++++++ 2 files changed, 45 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/block/ioctl.c b/block/ioctl.c index 7d8befd..ff623d5 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -186,19 +186,39 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, } static int blk_ioctl_zeroout(struct block_device *bdev, uint64_t start, - uint64_t len) + uint64_t len, uint32_t flags) { + int ret; + struct address_space *mapping; + uint64_t end = start + len - 1; + + if (flags & ~BLKZEROOUT2_DISCARD_OK) + return -EINVAL; if (start & 511) return -EINVAL; if (len & 511) return -EINVAL; - start >>= 9; - len >>= 9; - - if (start + len > (i_size_read(bdev->bd_inode) >> 9)) + if (end >= i_size_read(bdev->bd_inode)) return -EINVAL; - return blkdev_issue_zeroout(bdev, start, len, GFP_KERNEL, false); + /* Invalidate the page cache, including dirty pages */ + mapping = bdev->bd_inode->i_mapping; + truncate_inode_pages_range(mapping, start, end); + + ret = blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL, + flags & BLKZEROOUT2_DISCARD_OK); + if (ret) + goto out; + + /* + * Invalidate again; if someone wandered in and dirtied a page, + * the caller will be given -EBUSY. + */ + ret = invalidate_inode_pages2_range(mapping, + start >> PAGE_CACHE_SHIFT, + end >> PAGE_CACHE_SHIFT); +out: + return ret; } static int put_ushort(unsigned long arg, unsigned short val) @@ -326,7 +346,18 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, if (copy_from_user(range, (void __user *)arg, sizeof(range))) return -EFAULT; - return blk_ioctl_zeroout(bdev, range[0], range[1]); + return blk_ioctl_zeroout(bdev, range[0], range[1], 0); + } + case BLKZEROOUT2: { + struct blkzeroout2 p; + + if (!(mode & FMODE_WRITE)) + return -EBADF; + + if (copy_from_user(&p, (void __user *)arg, sizeof(p))) + return -EFAULT; + + return blk_ioctl_zeroout(bdev, p.start, p.length, p.flags); } case HDIO_GETGEO: { diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 3735fa0..54d24ea 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -150,6 +150,13 @@ struct inodes_stat_t { #define BLKSECDISCARD _IO(0x12,125) #define BLKROTATIONAL _IO(0x12,126) #define BLKZEROOUT _IO(0x12,127) +struct blkzeroout2 { + __u64 start; + __u64 length; + __u32 flags; +}; +#define BLKZEROOUT2_DISCARD_OK 1 +#define BLKZEROOUT2 _IOR(0x12, 127, struct blkzeroout2) #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */