You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-3.2/drivers' of git://git.kernel.dk/linux-block
* 'for-3.2/drivers' of git://git.kernel.dk/linux-block: (30 commits)
virtio-blk: use ida to allocate disk index
hpsa: add small delay when using PCI Power Management to reset for kump
cciss: add small delay when using PCI Power Management to reset for kump
xen/blkback: Fix two races in the handling of barrier requests.
xen/blkback: Check for proper operation.
xen/blkback: Fix the inhibition to map pages when discarding sector ranges.
xen/blkback: Report VBD_WSECT (wr_sect) properly.
xen/blkback: Support 'feature-barrier' aka old-style BARRIER requests.
xen-blkfront: plug device number leak in xlblk_init() error path
xen-blkfront: If no barrier or flush is supported, use invalid operation.
xen-blkback: use kzalloc() in favor of kmalloc()+memset()
xen-blkback: fixed indentation and comments
xen-blkfront: fix a deadlock while handling discard response
xen-blkfront: Handle discard requests.
xen-blkback: Implement discard requests ('feature-discard')
xen-blkfront: add BLKIF_OP_DISCARD and discard request struct
drivers/block/loop.c: remove unnecessary bdev argument from loop_clr_fd()
drivers/block/loop.c: emit uevent on auto release
drivers/block/cpqarray.c: use pci_dev->revision
loop: always allow userspace partitions and optionally support automatic scanning
...
Fic up trivial header file includsion conflict in drivers/block/loop.c
This commit is contained in:
+104
-7
@@ -76,6 +76,8 @@
|
||||
#include <linux/splice.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/falloc.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
static DEFINE_IDR(loop_index_idr);
|
||||
@@ -407,6 +409,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) {
|
||||
@@ -622,7 +647,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
||||
goto out_putf;
|
||||
|
||||
fput(old_file);
|
||||
if (max_part > 0)
|
||||
if (lo->lo_flags & LO_FLAGS_PARTSCAN)
|
||||
ioctl_by_bdev(bdev, BLKRRPART, 0);
|
||||
return 0;
|
||||
|
||||
@@ -699,16 +724,25 @@ static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf)
|
||||
return sprintf(buf, "%s\n", autoclear ? "1" : "0");
|
||||
}
|
||||
|
||||
static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf)
|
||||
{
|
||||
int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN);
|
||||
|
||||
return sprintf(buf, "%s\n", partscan ? "1" : "0");
|
||||
}
|
||||
|
||||
LOOP_ATTR_RO(backing_file);
|
||||
LOOP_ATTR_RO(offset);
|
||||
LOOP_ATTR_RO(sizelimit);
|
||||
LOOP_ATTR_RO(autoclear);
|
||||
LOOP_ATTR_RO(partscan);
|
||||
|
||||
static struct attribute *loop_attrs[] = {
|
||||
&loop_attr_backing_file.attr,
|
||||
&loop_attr_offset.attr,
|
||||
&loop_attr_sizelimit.attr,
|
||||
&loop_attr_autoclear.attr,
|
||||
&loop_attr_partscan.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -729,6 +763,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)
|
||||
{
|
||||
@@ -829,7 +892,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
||||
}
|
||||
lo->lo_state = Lo_bound;
|
||||
wake_up_process(lo->lo_thread);
|
||||
if (max_part > 0)
|
||||
if (part_shift)
|
||||
lo->lo_flags |= LO_FLAGS_PARTSCAN;
|
||||
if (lo->lo_flags & LO_FLAGS_PARTSCAN)
|
||||
ioctl_by_bdev(bdev, BLKRRPART, 0);
|
||||
return 0;
|
||||
|
||||
@@ -890,10 +955,11 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
|
||||
static int loop_clr_fd(struct loop_device *lo)
|
||||
{
|
||||
struct file *filp = lo->lo_backing_file;
|
||||
gfp_t gfp = lo->old_gfp_mask;
|
||||
struct block_device *bdev = lo->lo_device;
|
||||
|
||||
if (lo->lo_state != Lo_bound)
|
||||
return -ENXIO;
|
||||
@@ -922,7 +988,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
|
||||
lo->lo_offset = 0;
|
||||
lo->lo_sizelimit = 0;
|
||||
lo->lo_encrypt_key_size = 0;
|
||||
lo->lo_flags = 0;
|
||||
lo->lo_thread = NULL;
|
||||
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
|
||||
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
|
||||
@@ -940,8 +1005,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
|
||||
lo->lo_state = Lo_unbound;
|
||||
/* This is safe: open() is still holding a reference. */
|
||||
module_put(THIS_MODULE);
|
||||
if (max_part > 0 && bdev)
|
||||
if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev)
|
||||
ioctl_by_bdev(bdev, BLKRRPART, 0);
|
||||
lo->lo_flags = 0;
|
||||
if (!part_shift)
|
||||
lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
|
||||
mutex_unlock(&lo->lo_ctl_mutex);
|
||||
/*
|
||||
* Need not hold lo_ctl_mutex to fput backing file.
|
||||
@@ -995,6 +1063,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);
|
||||
@@ -1010,6 +1079,13 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
(info->lo_flags & LO_FLAGS_AUTOCLEAR))
|
||||
lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
|
||||
|
||||
if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
|
||||
!(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
|
||||
lo->lo_flags |= LO_FLAGS_PARTSCAN;
|
||||
lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
|
||||
ioctl_by_bdev(lo->lo_device, BLKRRPART, 0);
|
||||
}
|
||||
|
||||
lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
|
||||
lo->lo_init[0] = info->lo_init[0];
|
||||
lo->lo_init[1] = info->lo_init[1];
|
||||
@@ -1203,7 +1279,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
break;
|
||||
case LOOP_CLR_FD:
|
||||
/* loop_clr_fd would have unlocked lo_ctl_mutex on success */
|
||||
err = loop_clr_fd(lo, bdev);
|
||||
err = loop_clr_fd(lo);
|
||||
if (!err)
|
||||
goto out_unlocked;
|
||||
break;
|
||||
@@ -1423,7 +1499,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
|
||||
* In autoclear mode, stop the loop thread
|
||||
* and remove configuration after last close.
|
||||
*/
|
||||
err = loop_clr_fd(lo, NULL);
|
||||
err = loop_clr_fd(lo);
|
||||
if (!err)
|
||||
goto out_unlocked;
|
||||
} else {
|
||||
@@ -1545,6 +1621,27 @@ static int loop_add(struct loop_device **l, int i)
|
||||
if (!disk)
|
||||
goto out_free_queue;
|
||||
|
||||
/*
|
||||
* Disable partition scanning by default. The in-kernel partition
|
||||
* scanning can be requested individually per-device during its
|
||||
* setup. Userspace can always add and remove partitions from all
|
||||
* devices. The needed partition minors are allocated from the
|
||||
* extended minor space, the main loop device numbers will continue
|
||||
* to match the loop minors, regardless of the number of partitions
|
||||
* used.
|
||||
*
|
||||
* If max_part is given, partition scanning is globally enabled for
|
||||
* all loop devices. The minors for the main loop devices will be
|
||||
* multiples of max_part.
|
||||
*
|
||||
* Note: Global-for-all-devices, set-only-at-init, read-only module
|
||||
* parameteters like 'max_loop' and 'max_part' make things needlessly
|
||||
* complicated, are too static, inflexible and may surprise
|
||||
* userspace tools. Parameters like this in general should be avoided.
|
||||
*/
|
||||
if (!part_shift)
|
||||
disk->flags |= GENHD_FL_NO_PART_SCAN;
|
||||
disk->flags |= GENHD_FL_EXT_DEVT;
|
||||
mutex_init(&lo->lo_ctl_mutex);
|
||||
lo->lo_number = i;
|
||||
lo->lo_thread = NULL;
|
||||
|
||||
Reference in New Issue
Block a user