static ssize_t reset_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
- int ret;
- unsigned short do_reset;
- struct zram *zram;
+ struct zram *zram = dev_to_zram(dev);
struct block_device *bdev;
+ unsigned short do_reset;
+ int ret = 0;
ret = kstrtou16(buf, 10, &do_reset);
if (ret)
return ret;
-
if (!do_reset)
return -EINVAL;
- zram = dev_to_zram(dev);
bdev = bdget_disk(zram->disk, 0);
if (!bdev)
return -ENOMEM;
mutex_lock(&bdev->bd_mutex);
- /* Do not reset an active device or claimed device */
- if (bdev->bd_openers || zram->claim) {
- mutex_unlock(&bdev->bd_mutex);
- bdput(bdev);
- return -EBUSY;
- }
-
- /* From now on, anyone can't open /dev/zram[0-9] */
- zram->claim = true;
+ if (bdev->bd_openers)
+ ret = -EBUSY;
+ else
+ zram_reset_device(zram);
mutex_unlock(&bdev->bd_mutex);
-
- /* Make sure all the pending I/O are finished */
- fsync_bdev(bdev);
- zram_reset_device(zram);
bdput(bdev);
- mutex_lock(&bdev->bd_mutex);
- zram->claim = false;
- mutex_unlock(&bdev->bd_mutex);
-
- return len;
-}
-
-static int zram_open(struct block_device *bdev, fmode_t mode)
-{
- int ret = 0;
- struct zram *zram;
-
- WARN_ON(!mutex_is_locked(&bdev->bd_mutex));
-
- zram = bdev->bd_disk->private_data;
- /* zram was claimed to reset so open request fails */
- if (zram->claim)
- ret = -EBUSY;
-
- return ret;
+ return ret ? ret : len;
}
static const struct block_device_operations zram_devops = {
- .open = zram_open,
.submit_bio = zram_submit_bio,
.swap_slot_free_notify = zram_slot_free_notify,
.rw_page = zram_rw_page,
};
static const struct block_device_operations zram_wb_devops = {
- .open = zram_open,
.submit_bio = zram_submit_bio,
.swap_slot_free_notify = zram_slot_free_notify,
.owner = THIS_MODULE
return ret;
}
-static int zram_remove(struct zram *zram)
+static bool zram_busy(struct zram *zram)
{
struct block_device *bdev;
+ bool busy = false;
bdev = bdget_disk(zram->disk, 0);
- if (!bdev)
- return -ENOMEM;
-
- mutex_lock(&bdev->bd_mutex);
- if (bdev->bd_openers || zram->claim) {
- mutex_unlock(&bdev->bd_mutex);
+ if (bdev) {
+ if (bdev->bd_openers)
+ busy = true;
bdput(bdev);
- return -EBUSY;
}
- zram->claim = true;
- mutex_unlock(&bdev->bd_mutex);
+ return busy;
+}
- zram_debugfs_unregister(zram);
+static int zram_remove(struct zram *zram)
+{
+ if (zram_busy(zram))
+ return -EBUSY;
- /* Make sure all the pending I/O are finished */
- fsync_bdev(bdev);
+ del_gendisk(zram->disk);
+ zram_debugfs_unregister(zram);
zram_reset_device(zram);
- bdput(bdev);
pr_info("Removed device: %s\n", zram->disk->disk_name);
- del_gendisk(zram->disk);
blk_cleanup_queue(zram->disk->queue);
put_disk(zram->disk);
kfree(zram);