[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190617210848.GB57907@jaegeuk-macbookpro.roam.corp.google.com>
Date: Mon, 17 Jun 2019 14:08:48 -0700
From: Jaegeuk Kim <jaegeuk@...nel.org>
To: linux-kernel@...r.kernel.org,
linux-f2fs-devel@...ts.sourceforge.net
Cc: Jens Axboe <axboe@...nel.dk>, linux-block@...r.kernel.org,
Bart Van Assche <bvanassche@....org>, stable@...r.kernel.org
Subject: Re: [f2fs-dev] [PATCH v2] loop: avoid EAGAIN, if offset or
block_size are changed
Jens,
Any chance to get a review for this?
(Added Tested-by:)
On 05/17, Jaegeuk Kim wrote:
> This patch tries to avoid EAGAIN due to nrpages!=0 that was originally trying
> to drop stale pages resulting in wrong data access.
>
> Report: https://bugs.chromium.org/p/chromium/issues/detail?id=938958#c38
>
> Cc: <stable@...r.kernel.org>
> Cc: Jens Axboe <axboe@...nel.dk>
> Cc: linux-block@...r.kernel.org
> Cc: Bart Van Assche <bvanassche@....org>
> Fixes: 5db470e229e2 ("loop: drop caches if offset or block_size are changed")
> Reported-by: Gwendal Grignou <gwendal@...omium.org>
> Reported-by: grygorii tertychnyi <gtertych@...co.com>
Tested-by: Francesco Ruggeri <fruggeri@...sta.com>
> Signed-off-by: Jaegeuk Kim <jaegeuk@...nel.org>
> ---
> v2 from v1:
> - remove obsolete jump
>
> drivers/block/loop.c | 45 +++++++++++++++++---------------------------
> 1 file changed, 17 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> index 102d79575895..42994de2dd12 100644
> --- a/drivers/block/loop.c
> +++ b/drivers/block/loop.c
> @@ -1212,6 +1212,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
> kuid_t uid = current_uid();
> struct block_device *bdev;
> bool partscan = false;
> + bool drop_caches = false;
>
> err = mutex_lock_killable(&loop_ctl_mutex);
> if (err)
> @@ -1232,10 +1233,8 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
> }
>
> if (lo->lo_offset != info->lo_offset ||
> - lo->lo_sizelimit != info->lo_sizelimit) {
> - sync_blockdev(lo->lo_device);
> - kill_bdev(lo->lo_device);
> - }
> + lo->lo_sizelimit != info->lo_sizelimit)
> + drop_caches = true;
>
> /* I/O need to be drained during transfer transition */
> blk_mq_freeze_queue(lo->lo_queue);
> @@ -1265,14 +1264,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
>
> if (lo->lo_offset != info->lo_offset ||
> lo->lo_sizelimit != info->lo_sizelimit) {
> - /* kill_bdev should have truncated all the pages */
> - if (lo->lo_device->bd_inode->i_mapping->nrpages) {
> - err = -EAGAIN;
> - pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
> - __func__, lo->lo_number, lo->lo_file_name,
> - lo->lo_device->bd_inode->i_mapping->nrpages);
> - goto out_unfreeze;
> - }
> if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
> err = -EFBIG;
> goto out_unfreeze;
> @@ -1317,6 +1308,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
> bdev = lo->lo_device;
> partscan = true;
> }
> +
> + /* truncate stale pages cached by previous operations */
> + if (!err && drop_caches) {
> + sync_blockdev(lo->lo_device);
> + kill_bdev(lo->lo_device);
> + }
> out_unlock:
> mutex_unlock(&loop_ctl_mutex);
> if (partscan)
> @@ -1498,6 +1495,7 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg)
>
> static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
> {
> + bool drop_caches = false;
> int err = 0;
>
> if (lo->lo_state != Lo_bound)
> @@ -1506,30 +1504,21 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
> if (arg < 512 || arg > PAGE_SIZE || !is_power_of_2(arg))
> return -EINVAL;
>
> - if (lo->lo_queue->limits.logical_block_size != arg) {
> - sync_blockdev(lo->lo_device);
> - kill_bdev(lo->lo_device);
> - }
> + if (lo->lo_queue->limits.logical_block_size != arg)
> + drop_caches = true;
>
> blk_mq_freeze_queue(lo->lo_queue);
> -
> - /* kill_bdev should have truncated all the pages */
> - if (lo->lo_queue->limits.logical_block_size != arg &&
> - lo->lo_device->bd_inode->i_mapping->nrpages) {
> - err = -EAGAIN;
> - pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
> - __func__, lo->lo_number, lo->lo_file_name,
> - lo->lo_device->bd_inode->i_mapping->nrpages);
> - goto out_unfreeze;
> - }
> -
> blk_queue_logical_block_size(lo->lo_queue, arg);
> blk_queue_physical_block_size(lo->lo_queue, arg);
> blk_queue_io_min(lo->lo_queue, arg);
> loop_update_dio(lo);
> -out_unfreeze:
> blk_mq_unfreeze_queue(lo->lo_queue);
>
> + /* truncate stale pages cached by previous operations */
> + if (drop_caches) {
> + sync_blockdev(lo->lo_device);
> + kill_bdev(lo->lo_device);
> + }
> return err;
> }
>
> --
> 2.19.0.605.g01d371f741-goog
>
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@...ts.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Powered by blists - more mailing lists