Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759986AbdCVOak (ORCPT ); Wed, 22 Mar 2017 10:30:40 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:36203 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759547AbdCVOae (ORCPT ); Wed, 22 Mar 2017 10:30:34 -0400 From: Dmitry Monakhov To: linux-kernel@vger.kernel.org Cc: hch@lst.de, Dmitry Monakhov Subject: [PATCH] block: Invalidate cache on discard Date: Wed, 22 Mar 2017 18:30:28 +0400 Message-Id: <1490193028-4445-1-git-send-email-dmonakhov@openvz.org> X-Mailer: git-send-email 1.9.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1590 Lines: 53 It is reasonable drop page cache on discard, otherwise that pages may be written by writeback second later, so thin provision devices will not be happy. This seems to be a security leak in case of secure discard case. Also add check for queue_discard flag on early stage. Signed-off-by: Dmitry Monakhov --- block/ioctl.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/block/ioctl.c b/block/ioctl.c index 7b88820..d1fea45 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -202,10 +202,15 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, { uint64_t range[2]; uint64_t start, len; + struct request_queue *q = bdev_get_queue(bdev); + struct address_space *mapping; if (!(mode & FMODE_WRITE)) return -EBADF; + if (!blk_queue_discard(q)) + return -EOPNOTSUPP; + if (copy_from_user(range, (void __user *)arg, sizeof(range))) return -EFAULT; @@ -216,12 +221,15 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, return -EINVAL; if (len & 511) return -EINVAL; - start >>= 9; - len >>= 9; - if (start + len > (i_size_read(bdev->bd_inode) >> 9)) + if (start + len > i_size_read(bdev->bd_inode)) return -EINVAL; - return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags); + + mapping = bdev->bd_inode->i_mapping; + truncate_inode_pages_range(mapping, start, start + len); + + return blkdev_issue_discard(bdev, start >> 9, len >> 9, + GFP_KERNEL, flags); } static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode, -- 2.9.3