summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/ublk_drv.c6
-rw-r--r--drivers/block/zram/zram_drv.c65
-rw-r--r--drivers/block/zram/zram_drv.h1
3 files changed, 38 insertions, 34 deletions
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 615d3d28e7c6..e7a77f27555e 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -1862,6 +1862,12 @@ static int ublk_ch_mmap(struct file *filp, struct vm_area_struct *vma)
if (vma->vm_flags & VM_WRITE)
return -EPERM;
+ /*
+ * The per-queue command buffer is kernel-written ABI; prevent
+ * the daemon from upgrading to writable via mprotect().
+ */
+ vm_flags_clear(vma, VM_MAYWRITE);
+
end = UBLKSRV_CMD_BUF_OFFSET + ub->dev_info.nr_hw_queues * max_sz;
if (phys_off < UBLKSRV_CMD_BUF_OFFSET || phys_off >= end)
return -EINVAL;
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index f51dd3378429..5a08e8bebd6d 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -501,7 +501,8 @@ out:
#ifdef CONFIG_ZRAM_WRITEBACK
static ssize_t writeback_limit_enable_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct zram *zram = dev_to_zram(dev);
u64 val;
@@ -510,33 +511,31 @@ static ssize_t writeback_limit_enable_store(struct device *dev,
if (kstrtoull(buf, 10, &val))
return ret;
- down_read(&zram->init_lock);
- spin_lock(&zram->wb_limit_lock);
+ down_write(&zram->init_lock);
zram->wb_limit_enable = val;
- spin_unlock(&zram->wb_limit_lock);
- up_read(&zram->init_lock);
+ up_write(&zram->init_lock);
ret = len;
return ret;
}
static ssize_t writeback_limit_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
bool val;
struct zram *zram = dev_to_zram(dev);
down_read(&zram->init_lock);
- spin_lock(&zram->wb_limit_lock);
val = zram->wb_limit_enable;
- spin_unlock(&zram->wb_limit_lock);
up_read(&zram->init_lock);
return sysfs_emit(buf, "%d\n", val);
}
static ssize_t writeback_limit_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct zram *zram = dev_to_zram(dev);
u64 val;
@@ -545,26 +544,32 @@ static ssize_t writeback_limit_store(struct device *dev,
if (kstrtoull(buf, 10, &val))
return ret;
- down_read(&zram->init_lock);
- spin_lock(&zram->wb_limit_lock);
+ /*
+ * When the page size is greater than 4KB, if bd_wb_limit is set to
+ * a value that is not page - size aligned, it will cause value
+ * wrapping. For example, when the page size is set to 16KB and
+ * bd_wb_limit is set to 3, a single write - back operation will
+ * cause bd_wb_limit to become -1. Even more terrifying is that
+ * bd_wb_limit is an unsigned number.
+ */
+ val = rounddown(val, PAGE_SIZE / 4096);
+
+ down_write(&zram->init_lock);
zram->bd_wb_limit = val;
- spin_unlock(&zram->wb_limit_lock);
- up_read(&zram->init_lock);
+ up_write(&zram->init_lock);
ret = len;
return ret;
}
static ssize_t writeback_limit_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
u64 val;
struct zram *zram = dev_to_zram(dev);
down_read(&zram->init_lock);
- spin_lock(&zram->wb_limit_lock);
val = zram->bd_wb_limit;
- spin_unlock(&zram->wb_limit_lock);
up_read(&zram->init_lock);
return sysfs_emit(buf, "%llu\n", val);
@@ -744,18 +749,17 @@ static int zram_writeback_slots(struct zram *zram, struct zram_pp_ctl *ctl)
int ret = 0, err;
u32 index;
+ lockdep_assert_held_read(&zram->init_lock);
+
page = alloc_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
while ((pps = select_pp_slot(ctl))) {
- spin_lock(&zram->wb_limit_lock);
if (zram->wb_limit_enable && !zram->bd_wb_limit) {
- spin_unlock(&zram->wb_limit_lock);
ret = -EIO;
break;
}
- spin_unlock(&zram->wb_limit_lock);
if (!blk_idx) {
blk_idx = alloc_block_bdev(zram);
@@ -821,10 +825,8 @@ static int zram_writeback_slots(struct zram *zram, struct zram_pp_ctl *ctl)
zram_set_handle(zram, index, blk_idx);
blk_idx = 0;
atomic64_inc(&zram->stats.pages_stored);
- spin_lock(&zram->wb_limit_lock);
if (zram->wb_limit_enable && zram->bd_wb_limit > 0)
zram->bd_wb_limit -= 1UL << (PAGE_SHIFT - 12);
- spin_unlock(&zram->wb_limit_lock);
next:
zram_slot_unlock(zram, index);
release_pp_slot(zram, pps);
@@ -1135,8 +1137,7 @@ static ssize_t read_block_state(struct file *file, char __user *buf,
char *kbuf;
ssize_t index, written = 0;
struct zram *zram = file->private_data;
- unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
- struct timespec64 ts;
+ unsigned long nr_pages;
kbuf = kvmalloc(count, GFP_KERNEL);
if (!kbuf)
@@ -1149,8 +1150,11 @@ static ssize_t read_block_state(struct file *file, char __user *buf,
return -EINVAL;
}
+ nr_pages = zram->disksize >> PAGE_SHIFT;
+
for (index = *ppos; index < nr_pages; index++) {
int copied;
+ struct timespec64 ts;
zram_slot_lock(zram, index);
if (!zram_allocated(zram, index))
@@ -1740,14 +1744,14 @@ static int zram_read_page(struct zram *zram, struct page *page, u32 index,
ret = zram_read_from_zspool(zram, page, index);
zram_slot_unlock(zram, index);
} else {
+ unsigned long blk_idx = zram_get_handle(zram, index);
+
/*
* The slot should be unlocked before reading from the backing
* device.
*/
zram_slot_unlock(zram, index);
-
- ret = read_from_bdev(zram, page, zram_get_handle(zram, index),
- parent);
+ ret = read_from_bdev(zram, page, blk_idx, parent);
}
/* Should NEVER happen. Return bio error if it does. */
@@ -2460,11 +2464,12 @@ static void zram_destroy_comps(struct zram *zram)
}
zram_comp_params_reset(zram);
+ comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
}
static void zram_reset_device(struct zram *zram)
{
- down_write(&zram->init_lock);
+ guard(rwsem_write)(&zram->init_lock);
zram->limit_pages = 0;
@@ -2478,9 +2483,6 @@ static void zram_reset_device(struct zram *zram)
memset(&zram->stats, 0, sizeof(zram->stats));
atomic_set(&zram->pp_in_progress, 0);
reset_bdev(zram);
-
- comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
- up_write(&zram->init_lock);
}
static ssize_t disksize_store(struct device *dev,
@@ -2692,9 +2694,6 @@ static int zram_add(void)
device_id = ret;
init_rwsem(&zram->init_lock);
-#ifdef CONFIG_ZRAM_WRITEBACK
- spin_lock_init(&zram->wb_limit_lock);
-#endif
/* gendisk structure */
zram->disk = blk_alloc_disk(&lim, NUMA_NO_NODE);
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 6cee93f9c0d0..8f64317e3b6c 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -127,7 +127,6 @@ struct zram {
bool claim; /* Protected by disk->open_mutex */
#ifdef CONFIG_ZRAM_WRITEBACK
struct file *backing_dev;
- spinlock_t wb_limit_lock;
bool wb_limit_enable;
u64 bd_wb_limit;
struct block_device *bdev;