diff options
Diffstat (limited to 'drivers/staging/zram')
-rw-r--r-- | drivers/staging/zram/Kconfig | 7 | ||||
-rw-r--r-- | drivers/staging/zram/zram_drv.c | 53 | ||||
-rw-r--r-- | drivers/staging/zram/zram_drv.h | 2 | ||||
-rw-r--r-- | drivers/staging/zram/zram_sysfs.c | 40 |
4 files changed, 91 insertions, 11 deletions
diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index 3bec4db..06f741a 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -28,3 +28,10 @@ config ZRAM_DEBUG help This option adds additional debugging code to the compressed RAM block device driver. + +config ZRAM_FOR_ANDROID + bool "Optimize zram behavior for android" + depends on ZRAM && ANDROID + default n + help + This option enables modified zram behavior optimized for android diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index aab4ec4..5258c78 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -32,12 +32,16 @@ #include <linux/lzo.h> #include <linux/string.h> #include <linux/vmalloc.h> +#ifdef CONFIG_ZRAM_FOR_ANDROID +#include <linux/swap.h> +#endif /* CONFIG_ZRAM_FOR_ANDROID */ + #include "zram_drv.h" /* Globals */ static int zram_major; -struct zram *devices; +struct zram *zram_devices; /* Module params (documentation at end) */ unsigned int num_devices; @@ -133,6 +137,22 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes) zram->disksize &= PAGE_MASK; } +#ifdef CONFIG_ZRAM_FOR_ANDROID +/* + * Swap header (1st page of swap device) contains information + * about a swap file/partition. Prepare such a header for the + * given ramzswap device so that swapon can identify it as a + * swap partition. + */ +static void setup_swap_header(struct zram *zram, union swap_header *s) +{ + s->info.version = 1; + s->info.last_page = (zram->disksize >> PAGE_SHIFT) - 1; + s->info.nr_badpages = 0; + memcpy(s->magic.magic, "SWAPSPACE2", 10); +} +#endif /* CONFIG_ZRAM_FOR_ANDROID */ + static void zram_free_page(struct zram *zram, size_t index) { u32 clen; @@ -501,6 +521,10 @@ int zram_init_device(struct zram *zram) { int ret; size_t num_pages; +#ifdef CONFIG_ZRAM_FOR_ANDROID + struct page *page; + union swap_header *swap_header; +#endif /* CONFIG_ZRAM_FOR_ANDROID */ mutex_lock(&zram->init_lock); @@ -535,6 +559,19 @@ int zram_init_device(struct zram *zram) goto fail; } +#ifdef CONFIG_ZRAM_FOR_ANDROID + page = alloc_page(__GFP_ZERO); + if (!page) { + pr_err("Error allocating swap header page\n"); + ret = -ENOMEM; + goto fail; + } + zram->table[0].page = page; + zram_set_flag(zram, 0, ZRAM_UNCOMPRESSED); + swap_header = kmap(page); + setup_swap_header(zram, swap_header); + kunmap(page); +#endif /* CONFIG_ZRAM_FOR_ANDROID */ set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); /* zram devices sort of resembles non-rotational disks */ @@ -678,14 +715,14 @@ static int __init zram_init(void) /* Allocate the device array and initialize each one */ pr_info("Creating %u devices ...\n", num_devices); - devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL); - if (!devices) { + zram_devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL); + if (!zram_devices) { ret = -ENOMEM; goto unregister; } for (dev_id = 0; dev_id < num_devices; dev_id++) { - ret = create_device(&devices[dev_id], dev_id); + ret = create_device(&zram_devices[dev_id], dev_id); if (ret) goto free_devices; } @@ -694,8 +731,8 @@ static int __init zram_init(void) free_devices: while (dev_id) - destroy_device(&devices[--dev_id]); - kfree(devices); + destroy_device(&zram_devices[--dev_id]); + kfree(zram_devices); unregister: unregister_blkdev(zram_major, "zram"); out: @@ -708,7 +745,7 @@ static void __exit zram_exit(void) struct zram *zram; for (i = 0; i < num_devices; i++) { - zram = &devices[i]; + zram = &zram_devices[i]; destroy_device(zram); if (zram->init_done) @@ -717,7 +754,7 @@ static void __exit zram_exit(void) unregister_blkdev(zram_major, "zram"); - kfree(devices); + kfree(zram_devices); pr_debug("Cleanup done!\n"); } diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index 408b2c0..3ad9486 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -120,7 +120,7 @@ struct zram { struct zram_stats stats; }; -extern struct zram *devices; +extern struct zram *zram_devices; extern unsigned int num_devices; #ifdef CONFIG_SYSFS extern struct attribute_group zram_disk_attr_group; diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index a70cc01..8a23554 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -35,7 +35,7 @@ static struct zram *dev_to_zram(struct device *dev) struct zram *zram = NULL; for (i = 0; i < num_devices; i++) { - zram = &devices[i]; + zram = &zram_devices[i]; if (disk_to_dev(zram->disk) == dev) break; } @@ -80,6 +80,42 @@ static ssize_t initstate_show(struct device *dev, return sprintf(buf, "%u\n", zram->init_done); } +#ifdef CONFIG_ZRAM_FOR_ANDROID +extern int swapon(const char*specialfile, int swap_flags); + +static ssize_t initstate_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t len) +{ + int ret; + unsigned long do_init; + struct zram *zram = dev_to_zram(dev); + + if (zram->init_done) { + pr_info("the device is initialized device\n"); + return -EBUSY; + } + + ret = strict_strtoul(buf, 10, &do_init); + if (ret) + return ret; + if (!do_init) + return -EINVAL; + + zram_init_device(zram); + swapon("/dev/block/zram0", 0); + return len; +} +#else +static inline ssize_t initstate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + return 0; +} +#endif /* CONFIG_ZRAM_FOR_ANDROID */ + + static ssize_t reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -190,7 +226,7 @@ static ssize_t mem_used_total_show(struct device *dev, static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR, disksize_show, disksize_store); -static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL); +static DEVICE_ATTR(initstate, S_IRUGO | S_IWUSR, initstate_show, initstate_store); static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store); static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL); static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL); |