lkml.org 
[lkml]   [2019]   [Dec]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 068/130] loop: fix no-unmap write-zeroes request behavior
    Date
    From: "Darrick J. Wong" <darrick.wong@oracle.com>

    [ Upstream commit efcfec579f6139528c9e6925eca2bc4a36da65c6 ]

    Currently, if the loop device receives a WRITE_ZEROES request, it asks
    the underlying filesystem to punch out the range. This behavior is
    correct if unmapping is allowed. However, a NOUNMAP request means that
    the caller doesn't want us to free the storage backing the range, so
    punching out the range is incorrect behavior.

    To satisfy a NOUNMAP | WRITE_ZEROES request, loop should ask the
    underlying filesystem to FALLOC_FL_ZERO_RANGE, which is (according to
    the fallocate documentation) required to ensure that the entire range is
    backed by real storage, which suffices for our purposes.

    Fixes: 19372e2769179dd ("loop: implement REQ_OP_WRITE_ZEROES")
    Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/block/loop.c | 26 ++++++++++++++++++--------
    1 file changed, 18 insertions(+), 8 deletions(-)

    diff --git a/drivers/block/loop.c b/drivers/block/loop.c
    index ec61dd873c93d..453e3728e6573 100644
    --- a/drivers/block/loop.c
    +++ b/drivers/block/loop.c
    @@ -414,18 +414,20 @@ static int lo_read_transfer(struct loop_device *lo, struct request *rq,
    return ret;
    }

    -static int lo_discard(struct loop_device *lo, struct request *rq, loff_t pos)
    +static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
    + int mode)
    {
    /*
    - * We use punch hole to reclaim the free space used by the
    - * image a.k.a. discard. However we do not support discard if
    - * encryption is enabled, because it may give an attacker
    - * useful information.
    + * We use fallocate to manipulate the space mappings used by the image
    + * a.k.a. discard/zerorange. However we do not support this if
    + * encryption is enabled, because it may give an attacker useful
    + * information.
    */
    struct file *file = lo->lo_backing_file;
    - int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
    int ret;

    + mode |= FALLOC_FL_KEEP_SIZE;
    +
    if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) {
    ret = -EOPNOTSUPP;
    goto out;
    @@ -565,9 +567,17 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
    switch (req_op(rq)) {
    case REQ_OP_FLUSH:
    return lo_req_flush(lo, rq);
    - case REQ_OP_DISCARD:
    case REQ_OP_WRITE_ZEROES:
    - return lo_discard(lo, rq, pos);
    + /*
    + * If the caller doesn't want deallocation, call zeroout to
    + * write zeroes the range. Otherwise, punch them out.
    + */
    + return lo_fallocate(lo, rq, pos,
    + (rq->cmd_flags & REQ_NOUNMAP) ?
    + FALLOC_FL_ZERO_RANGE :
    + FALLOC_FL_PUNCH_HOLE);
    + case REQ_OP_DISCARD:
    + return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE);
    case REQ_OP_WRITE:
    if (lo->transfer)
    return lo_write_transfer(lo, rq, pos);
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-12-10 23:10    [W:3.477 / U:0.444 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site