aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorSergey Senozhatsky <sergey.senozhatsky@gmail.com>2015-06-25 18:00:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-25 20:00:36 -0400
commit85508ec6cbc21645927b6ac05e3b2748119a3e23 (patch)
tree77eaa8003f4dd6f2aad867c5c54337ee9acc909d /drivers/block
parent3bca3ef7694166b86c91b515818cc5acecd357a7 (diff)
zram: use idr instead of `zram_devices' array
This patch makes some preparations for on-demand device add/remove functionality. Remove `zram_devices' array and switch to id-to-pointer translation (idr). idr doesn't bloat zram struct with additional members, f.e. list_head, yet still provides ability to match the device_id with the device pointer. No user-space visible changes. [Julia.Lawall@lip6.fr: return -ENOMEM when `queue' alloc fails] Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Reported-by: Julia Lawall <Julia.Lawall@lip6.fr> Acked-by: Minchan Kim <minchan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/zram/zram_drv.c86
1 files changed, 49 insertions, 37 deletions
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 7814e686e23c..addb18d1b8d7 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -28,12 +28,12 @@
28#include <linux/string.h> 28#include <linux/string.h>
29#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/idr.h>
31 32
32#include "zram_drv.h" 33#include "zram_drv.h"
33 34
34/* Globals */ 35static DEFINE_IDR(zram_index_idr);
35static int zram_major; 36static int zram_major;
36static struct zram *zram_devices;
37static const char *default_compressor = "lzo"; 37static const char *default_compressor = "lzo";
38 38
39/* Module params (documentation at end) */ 39/* Module params (documentation at end) */
@@ -1154,10 +1154,20 @@ static struct attribute_group zram_disk_attr_group = {
1154 .attrs = zram_disk_attrs, 1154 .attrs = zram_disk_attrs,
1155}; 1155};
1156 1156
1157static int create_device(struct zram *zram, int device_id) 1157static int zram_add(int device_id)
1158{ 1158{
1159 struct zram *zram;
1159 struct request_queue *queue; 1160 struct request_queue *queue;
1160 int ret = -ENOMEM; 1161 int ret;
1162
1163 zram = kzalloc(sizeof(struct zram), GFP_KERNEL);
1164 if (!zram)
1165 return -ENOMEM;
1166
1167 ret = idr_alloc(&zram_index_idr, zram, device_id,
1168 device_id + 1, GFP_KERNEL);
1169 if (ret < 0)
1170 goto out_free_dev;
1161 1171
1162 init_rwsem(&zram->init_lock); 1172 init_rwsem(&zram->init_lock);
1163 1173
@@ -1165,12 +1175,13 @@ static int create_device(struct zram *zram, int device_id)
1165 if (!queue) { 1175 if (!queue) {
1166 pr_err("Error allocating disk queue for device %d\n", 1176 pr_err("Error allocating disk queue for device %d\n",
1167 device_id); 1177 device_id);
1168 goto out; 1178 ret = -ENOMEM;
1179 goto out_free_idr;
1169 } 1180 }
1170 1181
1171 blk_queue_make_request(queue, zram_make_request); 1182 blk_queue_make_request(queue, zram_make_request);
1172 1183
1173 /* gendisk structure */ 1184 /* gendisk structure */
1174 zram->disk = alloc_disk(1); 1185 zram->disk = alloc_disk(1);
1175 if (!zram->disk) { 1186 if (!zram->disk) {
1176 pr_warn("Error allocating disk structure for device %d\n", 1187 pr_warn("Error allocating disk structure for device %d\n",
@@ -1235,34 +1246,42 @@ out_free_disk:
1235 put_disk(zram->disk); 1246 put_disk(zram->disk);
1236out_free_queue: 1247out_free_queue:
1237 blk_cleanup_queue(queue); 1248 blk_cleanup_queue(queue);
1238out: 1249out_free_idr:
1250 idr_remove(&zram_index_idr, device_id);
1251out_free_dev:
1252 kfree(zram);
1239 return ret; 1253 return ret;
1240} 1254}
1241 1255
1242static void destroy_devices(unsigned int nr) 1256static void zram_remove(struct zram *zram)
1243{ 1257{
1244 struct zram *zram; 1258 /*
1245 unsigned int i; 1259 * Remove sysfs first, so no one will perform a disksize
1246 1260 * store while we destroy the devices
1247 for (i = 0; i < nr; i++) { 1261 */
1248 zram = &zram_devices[i]; 1262 sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
1249 /* 1263 &zram_disk_attr_group);
1250 * Remove sysfs first, so no one will perform a disksize
1251 * store while we destroy the devices
1252 */
1253 sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
1254 &zram_disk_attr_group);
1255 1264
1256 zram_reset_device(zram); 1265 zram_reset_device(zram);
1266 idr_remove(&zram_index_idr, zram->disk->first_minor);
1267 blk_cleanup_queue(zram->disk->queue);
1268 del_gendisk(zram->disk);
1269 put_disk(zram->disk);
1270 kfree(zram);
1271}
1257 1272
1258 blk_cleanup_queue(zram->disk->queue); 1273static int zram_remove_cb(int id, void *ptr, void *data)
1259 del_gendisk(zram->disk); 1274{
1260 put_disk(zram->disk); 1275 zram_remove(ptr);
1261 } 1276 return 0;
1277}
1262 1278
1263 kfree(zram_devices); 1279static void destroy_devices(void)
1280{
1281 idr_for_each(&zram_index_idr, &zram_remove_cb, NULL);
1282 idr_destroy(&zram_index_idr);
1264 unregister_blkdev(zram_major, "zram"); 1283 unregister_blkdev(zram_major, "zram");
1265 pr_info("Destroyed %u device(s)\n", nr); 1284 pr_info("Destroyed device(s)\n");
1266} 1285}
1267 1286
1268static int __init zram_init(void) 1287static int __init zram_init(void)
@@ -1281,16 +1300,9 @@ static int __init zram_init(void)
1281 return -EBUSY; 1300 return -EBUSY;
1282 } 1301 }
1283 1302
1284 /* Allocate the device array and initialize each one */
1285 zram_devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL);
1286 if (!zram_devices) {
1287 unregister_blkdev(zram_major, "zram");
1288 return -ENOMEM;
1289 }
1290
1291 for (dev_id = 0; dev_id < num_devices; dev_id++) { 1303 for (dev_id = 0; dev_id < num_devices; dev_id++) {
1292 ret = create_device(&zram_devices[dev_id], dev_id); 1304 ret = zram_add(dev_id);
1293 if (ret) 1305 if (ret != 0)
1294 goto out_error; 1306 goto out_error;
1295 } 1307 }
1296 1308
@@ -1298,13 +1310,13 @@ static int __init zram_init(void)
1298 return 0; 1310 return 0;
1299 1311
1300out_error: 1312out_error:
1301 destroy_devices(dev_id); 1313 destroy_devices();
1302 return ret; 1314 return ret;
1303} 1315}
1304 1316
1305static void __exit zram_exit(void) 1317static void __exit zram_exit(void)
1306{ 1318{
1307 destroy_devices(num_devices); 1319 destroy_devices();
1308} 1320}
1309 1321
1310module_init(zram_init); 1322module_init(zram_init);