aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/zram
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/zram')
-rw-r--r--drivers/staging/zram/Kconfig7
-rw-r--r--drivers/staging/zram/zram_drv.c53
-rw-r--r--drivers/staging/zram/zram_drv.h2
-rw-r--r--drivers/staging/zram/zram_sysfs.c40
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);