* Changelog v2
- replace stat_*() with rzs_stat*() to avoid conflict with core kernel
- split changes across separate patches
ramzswap driver creates virtual block devices which can
be used (only) as swap disks. Pages swapped to these disks
are compressed and stored in memory itself. Project home:
http://code.google.com/p/compcache/
These patches apply to linux-next.
Signed-off-by: Nitin Gupta <[email protected]>
Nitin Gupta (7):
Use lock for 64-bit stats
Flush block device before reset
Set block size to PAGE_SIZE
Return proper error code on device create failure
Remove redundant check for zero page
Handle case for invalid backing swap
Update copyright notice
drivers/staging/ramzswap/ramzswap_drv.c | 148 +++++++++++++++++------------
drivers/staging/ramzswap/ramzswap_drv.h | 61 ++++++++++--
drivers/staging/ramzswap/ramzswap_ioctl.h | 3 +-
drivers/staging/ramzswap/xvmalloc.c | 2 +-
drivers/staging/ramzswap/xvmalloc.h | 2 +-
drivers/staging/ramzswap/xvmalloc_int.h | 2 +-
6 files changed, 141 insertions(+), 77 deletions(-)
64-bit stats corruption was observed when ramzswap was
used on SMP systems. To prevent this, use separate spinlock
to protect these stats.
Also, replace stat_*() with rzs_stat*() to avoid possible
conflict with core kernel code.
Eventually, these will be converted to per-cpu counters
if this driver finds use on large scale systems and this
locking is found to affect scalability.
Signed-off-by: Nitin Gupta <[email protected]>
---
drivers/staging/ramzswap/ramzswap_drv.c | 58 +++++++++++++++--------------
drivers/staging/ramzswap/ramzswap_drv.h | 59 ++++++++++++++++++++++++-----
drivers/staging/ramzswap/ramzswap_ioctl.h | 1 +
3 files changed, 80 insertions(+), 38 deletions(-)
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index baf7572..05273c0 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -24,7 +24,6 @@
#include <linux/genhd.h>
#include <linux/highmem.h>
#include <linux/lzo.h>
-#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/swap.h>
#include <linux/swapops.h>
@@ -239,7 +238,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
mem_used = xv_get_total_size_bytes(rzs->mem_pool)
+ (rs->pages_expand << PAGE_SHIFT);
- succ_writes = rs->num_writes - rs->failed_writes;
+ succ_writes = rzs_stat64_read(rzs, &rs->num_writes) -
+ rzs_stat64_read(rzs, &rs->failed_writes);
if (succ_writes && rs->pages_stored) {
good_compress_perc = rs->good_compress * 100
@@ -248,11 +248,12 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
/ rs->pages_stored;
}
- s->num_reads = rs->num_reads;
- s->num_writes = rs->num_writes;
- s->failed_reads = rs->failed_reads;
- s->failed_writes = rs->failed_writes;
- s->invalid_io = rs->invalid_io;
+ s->num_reads = rzs_stat64_read(rzs, &rs->num_reads);
+ s->num_writes = rzs_stat64_read(rzs, &rs->num_writes);
+ s->failed_reads = rzs_stat64_read(rzs, &rs->failed_reads);
+ s->failed_writes = rzs_stat64_read(rzs, &rs->failed_writes);
+ s->invalid_io = rzs_stat64_read(rzs, &rs->invalid_io);
+ s->notify_free = rzs_stat64_read(rzs, &rs->notify_free);
s->pages_zero = rs->pages_zero;
s->good_compress_pct = good_compress_perc;
@@ -264,8 +265,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
s->compr_data_size = rs->compr_size;
s->mem_used_total = mem_used;
- s->bdev_num_reads = rs->bdev_num_reads;
- s->bdev_num_writes = rs->bdev_num_writes;
+ s->bdev_num_reads = rzs_stat64_read(rzs, &rs->bdev_num_reads);
+ s->bdev_num_writes = rzs_stat64_read(rzs, &rs->bdev_num_writes);
}
#endif /* CONFIG_RAMZSWAP_STATS */
}
@@ -594,7 +595,7 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
if (unlikely(!page)) {
if (rzs_test_flag(rzs, index, RZS_ZERO)) {
rzs_clear_flag(rzs, index, RZS_ZERO);
- stat_dec(rzs->stats.pages_zero);
+ rzs_stat_dec(&rzs->stats.pages_zero);
}
return;
}
@@ -603,7 +604,7 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
clen = PAGE_SIZE;
__free_page(page);
rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED);
- stat_dec(rzs->stats.pages_expand);
+ rzs_stat_dec(&rzs->stats.pages_expand);
goto out;
}
@@ -613,11 +614,11 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
xv_free(rzs->mem_pool, page, offset);
if (clen <= PAGE_SIZE / 2)
- stat_dec(rzs->stats.good_compress);
+ rzs_stat_dec(&rzs->stats.good_compress);
out:
rzs->stats.compr_size -= clen;
- stat_dec(rzs->stats.pages_stored);
+ rzs_stat_dec(&rzs->stats.pages_stored);
rzs->table[index].page = NULL;
rzs->table[index].offset = 0;
@@ -679,8 +680,8 @@ static int handle_ramzswap_fault(struct ramzswap *rzs, struct bio *bio)
*/
if (rzs->backing_swap) {
u32 pagenum;
- stat_dec(rzs->stats.num_reads);
- stat_inc(rzs->stats.bdev_num_reads);
+ rzs_stat64_dec(rzs, &rzs->stats.num_reads);
+ rzs_stat64_inc(rzs, &rzs->stats.bdev_num_reads);
bio->bi_bdev = rzs->backing_swap;
/*
@@ -718,7 +719,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
struct zobj_header *zheader;
unsigned char *user_mem, *cmem;
- stat_inc(rzs->stats.num_reads);
+ rzs_stat64_inc(rzs, &rzs->stats.num_reads);
page = bio->bi_io_vec[0].bv_page;
index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -752,7 +753,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
if (unlikely(ret != LZO_E_OK)) {
pr_err("Decompression failed! err=%d, page=%u\n",
ret, index);
- stat_inc(rzs->stats.failed_reads);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_reads);
goto out;
}
@@ -776,7 +777,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
struct page *page, *page_store;
unsigned char *user_mem, *cmem, *src;
- stat_inc(rzs->stats.num_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.num_writes);
page = bio->bi_io_vec[0].bv_page;
index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -796,7 +797,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
* Simply clear zero page flag.
*/
if (rzs_test_flag(rzs, index, RZS_ZERO)) {
- stat_dec(rzs->stats.pages_zero);
+ rzs_stat_dec(&rzs->stats.pages_zero);
rzs_clear_flag(rzs, index, RZS_ZERO);
}
@@ -806,7 +807,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
if (page_zero_filled(user_mem)) {
kunmap_atomic(user_mem, KM_USER0);
mutex_unlock(&rzs->lock);
- stat_inc(rzs->stats.pages_zero);
+ rzs_stat_inc(&rzs->stats.pages_zero);
rzs_set_flag(rzs, index, RZS_ZERO);
set_bit(BIO_UPTODATE, &bio->bi_flags);
@@ -830,7 +831,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
if (unlikely(ret != LZO_E_OK)) {
mutex_unlock(&rzs->lock);
pr_err("Compression failed! err=%d\n", ret);
- stat_inc(rzs->stats.failed_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
goto out;
}
@@ -853,13 +854,13 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
mutex_unlock(&rzs->lock);
pr_info("Error allocating memory for incompressible "
"page: %u\n", index);
- stat_inc(rzs->stats.failed_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
goto out;
}
offset = 0;
rzs_set_flag(rzs, index, RZS_UNCOMPRESSED);
- stat_inc(rzs->stats.pages_expand);
+ rzs_stat_inc(&rzs->stats.pages_expand);
rzs->table[index].page = page_store;
src = kmap_atomic(page, KM_USER0);
goto memstore;
@@ -871,7 +872,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
mutex_unlock(&rzs->lock);
pr_info("Error allocating memory for compressed "
"page: %u, size=%zu\n", index, clen);
- stat_inc(rzs->stats.failed_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
if (rzs->backing_swap)
fwd_write_request = 1;
goto out;
@@ -900,9 +901,9 @@ memstore:
/* Update stats */
rzs->stats.compr_size += clen;
- stat_inc(rzs->stats.pages_stored);
+ rzs_stat_inc(&rzs->stats.pages_stored);
if (clen <= PAGE_SIZE / 2)
- stat_inc(rzs->stats.good_compress);
+ rzs_stat_inc(&rzs->stats.good_compress);
mutex_unlock(&rzs->lock);
@@ -912,7 +913,7 @@ memstore:
out:
if (fwd_write_request) {
- stat_inc(rzs->stats.bdev_num_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.bdev_num_writes);
bio->bi_bdev = rzs->backing_swap;
#if 0
/*
@@ -974,7 +975,7 @@ static int ramzswap_make_request(struct request_queue *queue, struct bio *bio)
}
if (!valid_swap_request(rzs, bio)) {
- stat_inc(rzs->stats.invalid_io);
+ rzs_stat64_inc(rzs, &rzs->stats.invalid_io);
bio_io_error(bio);
return 0;
}
@@ -1295,6 +1296,7 @@ static struct block_device_operations ramzswap_devops = {
static int create_device(struct ramzswap *rzs, int device_id)
{
mutex_init(&rzs->lock);
+ spin_lock_init(&rzs->stat64_lock);
INIT_LIST_HEAD(&rzs->backing_swap_extent_list);
rzs->queue = blk_alloc_queue(GFP_KERNEL);
diff --git a/drivers/staging/ramzswap/ramzswap_drv.h b/drivers/staging/ramzswap/ramzswap_drv.h
index 7ba98bf..5b67222 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.h
+++ b/drivers/staging/ramzswap/ramzswap_drv.h
@@ -15,6 +15,9 @@
#ifndef _RAMZSWAP_DRV_H_
#define _RAMZSWAP_DRV_H_
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
#include "ramzswap_ioctl.h"
#include "xvmalloc.h"
@@ -71,15 +74,6 @@ static const unsigned max_zpage_size_nobdev = PAGE_SIZE / 4 * 3;
#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT)
-/* Debugging and Stats */
-#if defined(CONFIG_RAMZSWAP_STATS)
-#define stat_inc(stat) ((stat)++)
-#define stat_dec(stat) ((stat)--)
-#else
-#define stat_inc(x)
-#define stat_dec(x)
-#endif
-
/* Flags for ramzswap pages (table[page_no].flags) */
enum rzs_pageflags {
/* Page is stored uncompressed */
@@ -124,6 +118,7 @@ struct ramzswap_stats {
u64 failed_reads; /* should NEVER! happen */
u64 failed_writes; /* can happen when memory is too low */
u64 invalid_io; /* non-swap I/O requests */
+ u64 notify_free; /* no. of swap slot free notifications */
u32 pages_zero; /* no. of zero filled pages */
u32 pages_stored; /* no. of pages currently stored */
u32 good_compress; /* % of pages with compression ratio<=50% */
@@ -138,6 +133,7 @@ struct ramzswap {
void *compress_workmem;
void *compress_buffer;
struct table *table;
+ spinlock_t stat64_lock; /* protect 64-bit stats */
struct mutex lock;
struct request_queue *queue;
struct gendisk *disk;
@@ -167,5 +163,48 @@ struct ramzswap {
/*-- */
-#endif
+/* Debugging and Stats */
+#if defined(CONFIG_RAMZSWAP_STATS)
+static void rzs_stat_inc(u32 *v)
+{
+ *v = *v + 1;
+}
+
+static void rzs_stat_dec(u32 *v)
+{
+ *v = *v - 1;
+}
+
+static void rzs_stat64_inc(struct ramzswap *rzs, u64 *v)
+{
+ spin_lock(&rzs->stat64_lock);
+ *v = *v + 1;
+ spin_unlock(&rzs->stat64_lock);
+}
+
+static void rzs_stat64_dec(struct ramzswap *rzs, u64 *v)
+{
+ spin_lock(&rzs->stat64_lock);
+ *v = *v - 1;
+ spin_unlock(&rzs->stat64_lock);
+}
+
+static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v)
+{
+ u64 val;
+
+ spin_lock(&rzs->stat64_lock);
+ val = *v;
+ spin_unlock(&rzs->stat64_lock);
+
+ return val;
+}
+#else
+#define rzs_stat_inc(v)
+#define rzs_stat_dec(v)
+#define rzs_stat64_inc(r, v)
+#define rzs_stat64_dec(r, v)
+#define rzs_stat64_read(r, v)
+#endif /* CONFIG_RAMZSWAP_STATS */
+#endif
diff --git a/drivers/staging/ramzswap/ramzswap_ioctl.h b/drivers/staging/ramzswap/ramzswap_ioctl.h
index 1bc54e2..1edaeba 100644
--- a/drivers/staging/ramzswap/ramzswap_ioctl.h
+++ b/drivers/staging/ramzswap/ramzswap_ioctl.h
@@ -27,6 +27,7 @@ struct ramzswap_ioctl_stats {
u64 failed_reads; /* should NEVER! happen */
u64 failed_writes; /* can happen when memory is too low */
u64 invalid_io; /* non-swap I/O requests */
+ u64 notify_free; /* no. of swap slot free notifications */
u32 pages_zero; /* no. of zero filled pages */
u32 good_compress_pct; /* no. of pages with compression ratio<=50% */
u32 pages_expand_pct; /* no. of incompressible pages */
--
1.6.2.5
ramzswap block size needs to be set equal to PAGE_SIZE to
avoid receiving any unaligned block I/O requests (happens
due to readahead logic during swapon). These unaligned
accesses produce unnecessary I/O errors, scaring users.
Signed-off-by: Nitin Gupta <[email protected]>
---
drivers/staging/ramzswap/ramzswap_drv.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 3567ee3..2021ad6 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -1335,6 +1335,10 @@ static int create_device(struct ramzswap *rzs, int device_id)
* or set equal to backing swap device (if provided)
*/
set_capacity(rzs->disk, 0);
+
+ blk_queue_physical_block_size(rzs->disk->queue, PAGE_SIZE);
+ blk_queue_logical_block_size(rzs->disk->queue, PAGE_SIZE);
+
add_disk(rzs->disk);
rzs->init_done = 0;
--
1.6.2.5
Currently, we return 0 if create_device() fails and 1 otherwise.
Now, proper error code is returned from create_device() and the
same is propagated as module error code from ramzswap_init().
Also added some cleanups for ramzswap_init(), improving function
structure.
Signed-off-by: Nitin Gupta <[email protected]>
---
drivers/staging/ramzswap/ramzswap_drv.c | 44 +++++++++++++++++++-----------
1 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 2021ad6..3035add 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -1300,6 +1300,8 @@ static struct block_device_operations ramzswap_devops = {
static int create_device(struct ramzswap *rzs, int device_id)
{
+ int ret = 0;
+
mutex_init(&rzs->lock);
spin_lock_init(&rzs->stat64_lock);
INIT_LIST_HEAD(&rzs->backing_swap_extent_list);
@@ -1308,7 +1310,8 @@ static int create_device(struct ramzswap *rzs, int device_id)
if (!rzs->queue) {
pr_err("Error allocating disk queue for device %d\n",
device_id);
- return 0;
+ ret = -ENOMEM;
+ goto out;
}
blk_queue_make_request(rzs->queue, ramzswap_make_request);
@@ -1320,7 +1323,8 @@ static int create_device(struct ramzswap *rzs, int device_id)
blk_cleanup_queue(rzs->queue);
pr_warning("Error allocating disk structure for device %d\n",
device_id);
- return 0;
+ ret = -ENOMEM;
+ goto out;
}
rzs->disk->major = ramzswap_major;
@@ -1342,7 +1346,9 @@ static int create_device(struct ramzswap *rzs, int device_id)
add_disk(rzs->disk);
rzs->init_done = 0;
- return 1;
+
+out:
+ return ret;
}
static void destroy_device(struct ramzswap *rzs)
@@ -1358,18 +1364,20 @@ static void destroy_device(struct ramzswap *rzs)
static int __init ramzswap_init(void)
{
- int i, ret;
+ int ret, dev_id;
if (num_devices > max_num_devices) {
pr_warning("Invalid value for num_devices: %u\n",
num_devices);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
ramzswap_major = register_blkdev(0, "ramzswap");
if (ramzswap_major <= 0) {
pr_warning("Unable to get major number\n");
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
if (!num_devices) {
@@ -1380,21 +1388,25 @@ static int __init ramzswap_init(void)
/* Allocate the device array and initialize each one */
pr_info("Creating %u devices ...\n", num_devices);
devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL);
- if (!devices)
- goto out;
+ if (!devices) {
+ ret = -ENOMEM;
+ goto unregister;
+ }
- for (i = 0; i < num_devices; i++)
- if (!create_device(&devices[i], i)) {
- ret = i;
+ for (dev_id = 0; dev_id < num_devices; dev_id++) {
+ ret = create_device(&devices[dev_id], dev_id);
+ if (ret)
goto free_devices;
- }
+ }
+
return 0;
+
free_devices:
- for (i = 0; i < ret; i++)
- destroy_device(&devices[i]);
-out:
- ret = -ENOMEM;
+ while (dev_id)
+ destroy_device(&devices[--dev_id]);
+unregister:
unregister_blkdev(ramzswap_major, "ramzswap");
+out:
return ret;
}
--
1.6.2.5
ramzswap_free_page() already handles the case for zero filled
pages. So, remove redundant logic for the same in ramzswap_write().
Signed-off-by: Nitin Gupta <[email protected]>
---
drivers/staging/ramzswap/ramzswap_drv.c | 15 +++++----------
1 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 3035add..7e0a3fa 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -593,6 +593,10 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
u32 offset = rzs->table[index].offset;
if (unlikely(!page)) {
+ /*
+ * No memory is allocated for zero filled pages.
+ * Simply clear zero page flag.
+ */
if (rzs_test_flag(rzs, index, RZS_ZERO)) {
rzs_clear_flag(rzs, index, RZS_ZERO);
rzs_stat_dec(&rzs->stats.pages_zero);
@@ -789,18 +793,9 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
* is no longer referenced by any process. So, its now safe
* to free the memory that was allocated for this page.
*/
- if (rzs->table[index].page)
+ if (rzs->table[index].page || rzs_test_flag(rzs, index, RZS_ZERO))
ramzswap_free_page(rzs, index);
- /*
- * No memory is allocated for zero filled pages.
- * Simply clear zero page flag.
- */
- if (rzs_test_flag(rzs, index, RZS_ZERO)) {
- rzs_stat_dec(&rzs->stats.pages_zero);
- rzs_clear_flag(rzs, index, RZS_ZERO);
- }
-
mutex_lock(&rzs->lock);
user_mem = kmap_atomic(page, KM_USER0);
--
1.6.2.5
Make sure we flush block device before freeing all metadata
during reset ioctl.
Signed-off-by: Nitin Gupta <[email protected]>
---
drivers/staging/ramzswap/ramzswap_drv.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 05273c0..3567ee3 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -1000,6 +1000,9 @@ static void reset_device(struct ramzswap *rzs)
unsigned entries_per_page;
unsigned long num_table_pages, entry = 0;
+ /* Do not accept any new I/O request */
+ rzs->init_done = 0;
+
if (rzs->backing_swap && !rzs->num_extents)
is_backing_blkdev = 1;
@@ -1073,9 +1076,6 @@ static void reset_device(struct ramzswap *rzs)
rzs->disksize = 0;
rzs->memlimit = 0;
-
- /* Back to uninitialized state */
- rzs->init_done = 0;
}
static int ramzswap_ioctl_init_device(struct ramzswap *rzs)
@@ -1276,6 +1276,11 @@ static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode,
ret = -EBUSY;
goto out;
}
+
+ /* Make sure all pending I/O is finished */
+ if (bdev)
+ fsync_bdev(bdev);
+
ret = ramzswap_ioctl_reset_device(rzs);
break;
--
1.6.2.5
Currently, we crash (issue BUG_ON) if backing swap
disk size is zero. This can happen is user specified
an extended partition or simply a bad disk as backing
swap. A crash is really an unpleasant surprise to user
for such trivial problems.
Now, we check for this condition and simply fail device
initialization if this is the case.
Additional cleanups:
* use static for all functions
* remove extra newline between functions
* memset backing_swap_name to NULL on device reset
Signed-off-by: Nitin Gupta <[email protected]>
---
drivers/staging/ramzswap/ramzswap_drv.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 7e0a3fa..1bca069 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -220,7 +220,7 @@ out:
return ret;
}
-void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
+static void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
struct ramzswap_ioctl_stats *s)
{
strncpy(s->backing_swap_name, rzs->backing_swap_name,
@@ -502,6 +502,14 @@ static int setup_backing_swap(struct ramzswap *rzs)
goto bad_param;
}
disksize = i_size_read(inode);
+ /*
+ * Can happen if user gives an extended partition as
+ * backing swap or simply a bad disk.
+ */
+ if (!disksize) {
+ pr_err("Error reading backing swap size.\n");
+ goto bad_param;
+ }
} else if (S_ISREG(inode->i_mode)) {
bdev = inode->i_sb->s_bdev;
if (IS_SWAPFILE(inode)) {
@@ -519,7 +527,6 @@ static int setup_backing_swap(struct ramzswap *rzs)
rzs->swap_file = swap_file;
rzs->backing_swap = bdev;
rzs->disksize = disksize;
- BUG_ON(!rzs->disksize);
return 0;
@@ -537,7 +544,7 @@ out:
* Map logical page number 'pagenum' to physical page number
* on backing swap device. For block device, this is a nop.
*/
-u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
+static u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
{
u32 skip_pages, entries_per_page;
size_t delta, se_offset, skipped;
@@ -668,7 +675,6 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio)
return 0;
}
-
/*
* Called when request page is not present in ramzswap.
* Its either in backing swap device (if present) or
@@ -936,7 +942,6 @@ out:
return 0;
}
-
/*
* Check if request is within bounds and page aligned.
*/
@@ -1064,6 +1069,7 @@ static void reset_device(struct ramzswap *rzs)
bd_release(rzs->backing_swap);
filp_close(rzs->swap_file, NULL);
rzs->backing_swap = NULL;
+ memset(rzs->backing_swap_name, 0, MAX_SWAP_NAME_LEN);
}
/* Reset stats */
--
1.6.2.5
Update copyright notice.
Signed-off-by: Nitin Gupta <[email protected]>
---
drivers/staging/ramzswap/ramzswap_drv.c | 2 +-
drivers/staging/ramzswap/ramzswap_drv.h | 2 +-
drivers/staging/ramzswap/ramzswap_ioctl.h | 2 +-
drivers/staging/ramzswap/xvmalloc.c | 2 +-
drivers/staging/ramzswap/xvmalloc.h | 2 +-
drivers/staging/ramzswap/xvmalloc_int.h | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 1bca069..5e422e2 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -1,7 +1,7 @@
/*
* Compressed RAM based swap device
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
diff --git a/drivers/staging/ramzswap/ramzswap_drv.h b/drivers/staging/ramzswap/ramzswap_drv.h
index 5b67222..c7e0e76 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.h
+++ b/drivers/staging/ramzswap/ramzswap_drv.h
@@ -1,7 +1,7 @@
/*
* Compressed RAM based swap device
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
diff --git a/drivers/staging/ramzswap/ramzswap_ioctl.h b/drivers/staging/ramzswap/ramzswap_ioctl.h
index 1edaeba..d26076d 100644
--- a/drivers/staging/ramzswap/ramzswap_ioctl.h
+++ b/drivers/staging/ramzswap/ramzswap_ioctl.h
@@ -1,7 +1,7 @@
/*
* Compressed RAM based swap device
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
diff --git a/drivers/staging/ramzswap/xvmalloc.c b/drivers/staging/ramzswap/xvmalloc.c
index dabd266..3fdbb8a 100644
--- a/drivers/staging/ramzswap/xvmalloc.c
+++ b/drivers/staging/ramzswap/xvmalloc.c
@@ -1,7 +1,7 @@
/*
* xvmalloc memory allocator
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
diff --git a/drivers/staging/ramzswap/xvmalloc.h b/drivers/staging/ramzswap/xvmalloc.h
index 010c6fe..5b1a81a 100644
--- a/drivers/staging/ramzswap/xvmalloc.h
+++ b/drivers/staging/ramzswap/xvmalloc.h
@@ -1,7 +1,7 @@
/*
* xvmalloc memory allocator
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
diff --git a/drivers/staging/ramzswap/xvmalloc_int.h b/drivers/staging/ramzswap/xvmalloc_int.h
index 263c72d..e23ed5c 100644
--- a/drivers/staging/ramzswap/xvmalloc_int.h
+++ b/drivers/staging/ramzswap/xvmalloc_int.h
@@ -1,7 +1,7 @@
/*
* xvmalloc memory allocator
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
--
1.6.2.5