From mboxrd@z Thu Jan 1 00:00:00 1970 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 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