The zram->stat handling should be procted by init_lock. Otherwise, user could see stale value from the stat. Signed-off-by: Minchan Kim <minchan@xxxxxxxxxx> --- I don't think it's stable material. The race is rare in real practice and this stale stat value read is not a critical. drivers/block/zram/zram_drv.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 0299d82275e7..53f176f590b0 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -48,8 +48,13 @@ static ssize_t name##_show(struct device *d, \ struct device_attribute *attr, char *b) \ { \ struct zram *zram = dev_to_zram(d); \ - return scnprintf(b, PAGE_SIZE, "%llu\n", \ - (u64)atomic64_read(&zram->stats.name)); \ + u64 val = 0; \ + \ + down_read(&zram->init_lock); \ + if (init_done(zram)) \ + val = atomic64_read(&zram->stats.name); \ + up_read(&zram->init_lock); \ + return scnprintf(b, PAGE_SIZE, "%llu\n", val); \ } \ static DEVICE_ATTR_RO(name); @@ -67,8 +72,14 @@ static ssize_t disksize_show(struct device *dev, struct device_attribute *attr, char *buf) { struct zram *zram = dev_to_zram(dev); + u64 val = 0; + + down_read(&zram->init_lock); + if (init_done(zram)) + val = zram->disksize; + up_read(&zram->init_lock); - return scnprintf(buf, PAGE_SIZE, "%llu\n", zram->disksize); + return scnprintf(buf, PAGE_SIZE, "%llu\n", val); } static ssize_t initstate_show(struct device *dev, @@ -88,9 +99,14 @@ static ssize_t orig_data_size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct zram *zram = dev_to_zram(dev); + u64 val = 0; + + down_read(&zram->init_lock); + if (init_done(zram)) + val = atomic64_read(&zram->stats.pages_stored) << PAGE_SHIFT; + up_read(&zram->init_lock); - return scnprintf(buf, PAGE_SIZE, "%llu\n", - (u64)(atomic64_read(&zram->stats.pages_stored)) << PAGE_SHIFT); + return scnprintf(buf, PAGE_SIZE, "%llu\n", val); } static ssize_t mem_used_total_show(struct device *dev, @@ -957,10 +973,6 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, struct bio_vec bv; zram = bdev->bd_disk->private_data; - if (!valid_io_request(zram, sector, PAGE_SIZE)) { - atomic64_inc(&zram->stats.invalid_io); - return -EINVAL; - } down_read(&zram->init_lock); if (unlikely(!init_done(zram))) { @@ -968,6 +980,13 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, goto out_unlock; } + if (!valid_io_request(zram, sector, PAGE_SIZE)) { + atomic64_inc(&zram->stats.invalid_io); + err = -EINVAL; + goto out_unlock; + } + + index = sector >> SECTORS_PER_PAGE_SHIFT; offset = sector & (SECTORS_PER_PAGE - 1) << SECTOR_SHIFT; -- 1.9.1 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>