Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 273825
b: refs/heads/master
c: dfaa2ef
h: refs/heads/master
i:
  273823: 9ed03d5
v: v3
  • Loading branch information
Lukas Czerner authored and Jens Axboe committed Aug 19, 2011
1 parent ec44929 commit ef000ad
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 548ef6cc26ca1c81f19855d57d3fb0f9a7ce3385
refs/heads/master: dfaa2ef68e80c378e610e3c8c536f1c239e8d3ef
54 changes: 54 additions & 0 deletions trunk/drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include <linux/kthread.h>
#include <linux/splice.h>
#include <linux/sysfs.h>
#include <linux/falloc.h>

#include <asm/uaccess.h>

Expand Down Expand Up @@ -484,6 +485,29 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
}
}

/*
* We use punch hole to reclaim the free space used by the
* image a.k.a. discard. However we do support discard if
* encryption is enabled, because it may give an attacker
* useful information.
*/
if (bio->bi_rw & REQ_DISCARD) {
struct file *file = lo->lo_backing_file;
int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;

if ((!file->f_op->fallocate) ||
lo->lo_encrypt_key_size) {
ret = -EOPNOTSUPP;
goto out;
}
ret = file->f_op->fallocate(file, mode, pos,
bio->bi_size);
if (unlikely(ret && ret != -EINVAL &&
ret != -EOPNOTSUPP))
ret = -EIO;
goto out;
}

ret = lo_send(lo, bio, pos);

if ((bio->bi_rw & REQ_FUA) && !ret) {
Expand Down Expand Up @@ -814,6 +838,35 @@ static void loop_sysfs_exit(struct loop_device *lo)
&loop_attribute_group);
}

static void loop_config_discard(struct loop_device *lo)
{
struct file *file = lo->lo_backing_file;
struct inode *inode = file->f_mapping->host;
struct request_queue *q = lo->lo_queue;

/*
* We use punch hole to reclaim the free space used by the
* image a.k.a. discard. However we do support discard if
* encryption is enabled, because it may give an attacker
* useful information.
*/
if ((!file->f_op->fallocate) ||
lo->lo_encrypt_key_size) {
q->limits.discard_granularity = 0;
q->limits.discard_alignment = 0;
q->limits.max_discard_sectors = 0;
q->limits.discard_zeroes_data = 0;
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
return;
}

q->limits.discard_granularity = inode->i_sb->s_blocksize;
q->limits.discard_alignment = inode->i_sb->s_blocksize;
q->limits.max_discard_sectors = UINT_MAX >> 9;
q->limits.discard_zeroes_data = 1;
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
}

static int loop_set_fd(struct loop_device *lo, fmode_t mode,
struct block_device *bdev, unsigned int arg)
{
Expand Down Expand Up @@ -1090,6 +1143,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
if (figure_loop_size(lo))
return -EFBIG;
}
loop_config_discard(lo);

memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
Expand Down

0 comments on commit ef000ad

Please sign in to comment.