From patchwork Tue Apr 17 19:19:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 899597 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=oracle.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="JkWJbt/k"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40QZn85XRZz9s1d for ; Wed, 18 Apr 2018 05:19:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753014AbeDQTTX (ORCPT ); Tue, 17 Apr 2018 15:19:23 -0400 Received: from userp2120.oracle.com ([156.151.31.85]:48820 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752719AbeDQTTW (ORCPT ); Tue, 17 Apr 2018 15:19:22 -0400 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w3HJGmKn155672; Tue, 17 Apr 2018 19:19:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2017-10-26; bh=mHEYEjIcZvBQMiXVCR9RWz0DqRM1wRcD9esoEN5822Q=; b=JkWJbt/kngZTG4hQckPsLzU5kyzO0UQL6qb5wfe1z5jFvPDDN8e+LStTahcW5vDjWhzF 8k/+UBTEQBx0LEbHCRE7ypDlOB+ChEncA1u1P1KvyumfN+ybxPfOlNGLxzTWBz7vJO79 OfOhE4PSkFljahNaonQJ8PgFX00lvYQzPnv7sC32xzFRiYUZbLJCJwwjqTi6m+qiE5iR xV+d8qA3EI59gfNoXWXrvRelfBi3+xIhSYsPRt+Y6Ev/8N971WnCBmLSCTQqkAhPbqxI aj8wTiJ8GxB5+ul/LwAWxfp1cEH4RmGpD5ef2QlWtsVKbA0/65Jms1l4nloCLJL2Kg3d lg== Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp2120.oracle.com with ESMTP id 2hbam5bnvv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 17 Apr 2018 19:19:19 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id w3HJJI9l027028 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 17 Apr 2018 19:19:18 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id w3HJJH2i030391; Tue, 17 Apr 2018 19:19:18 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 17 Apr 2018 12:19:17 -0700 Subject: [PATCH 2/2] libext2fs: try to always use PUNCH_HOLE for unix_discard From: "Darrick J. Wong" To: tytso@mit.edu, darrick.wong@oracle.com Cc: adilger@dilger.ca, linux-ext4@vger.kernel.org Date: Tue, 17 Apr 2018 12:19:10 -0700 Message-ID: <152399275063.4654.12673225054216079609.stgit@magnolia> In-Reply-To: <152399273813.4654.4884342501339028766.stgit@magnolia> References: <152399273813.4654.4884342501339028766.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8866 signatures=668698 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=2 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=728 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1804170167 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Darrick J. Wong Now that block devices support PUNCH_HOLE via fallocate, refactor the unix_discard code into a helper that will always try to use it. For block devices we can fall back to BLKDISCARD, but we prefer to use fallocate because it will always invalidate the page cache of the zeroed region. Signed-off-by: Darrick J. Wong Reviewed-by: Andreas Dilger Reviewed-by: Andreas Dilger --- lib/ext2fs/unix_io.c | 61 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c index 1fb6279..0cf8ca2 100644 --- a/lib/ext2fs/unix_io.c +++ b/lib/ext2fs/unix_io.c @@ -1073,6 +1073,38 @@ static errcode_t unix_set_option(io_channel channel, const char *option, #define BLKDISCARD _IO(0x12,119) #endif +/* + * Try a PUNCH_HOLE to unmap blocks, then BLKDISCARD if that doesn't work. + * We prefer PUNCH_HOLE because it invalidates the page cache, even on block + * devices. + */ +static int __unix_discard(int fd, int is_bdev, off_t offset, off_t len) +{ +#ifdef BLKDISCARD + __u64 range[2]; +#endif + int ret = -1; + +#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE) + ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + offset, len); + if (ret == 0) + return 0; +#endif +#ifdef BLKDISCARD + if (is_bdev) { + range[0] = (__u64)offset; + range[1] = (__u64)len; + + ret = ioctl(fd, BLKDISCARD, &range); + if (ret == 0) + return 0; + } +#endif + errno = EOPNOTSUPP; + return ret; +} + static errcode_t unix_discard(io_channel channel, unsigned long long block, unsigned long long count) { @@ -1083,31 +1115,10 @@ static errcode_t unix_discard(io_channel channel, unsigned long long block, data = (struct unix_private_data *) channel->private_data; EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL); - if (channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE) { -#ifdef BLKDISCARD - __u64 range[2]; - - range[0] = (__u64)(block) * channel->block_size + data->offset; - range[1] = (__u64)(count) * channel->block_size; - - ret = ioctl(data->dev, BLKDISCARD, &range); -#else - goto unimplemented; -#endif - } else { -#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE) - /* - * If we are not on block device, try to use punch hole - * to reclaim free space. - */ - ret = fallocate(data->dev, - FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - (off_t)(block) * channel->block_size + data->offset, - (off_t)(count) * channel->block_size); -#else - goto unimplemented; -#endif - } + ret = __unix_discard(data->dev, + (channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE), + (off_t)(block) * channel->block_size + data->offset, + (off_t)(count) * channel->block_size); if (ret < 0) { if (errno == EOPNOTSUPP) goto unimplemented;