summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-snap-persistent.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-snap-persistent.c')
-rw-r--r--drivers/md/dm-snap-persistent.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index bf71583296f7..117a05e40090 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -7,6 +7,7 @@
7 7
8#include "dm-exception-store.h" 8#include "dm-exception-store.h"
9 9
10#include <linux/ctype.h>
10#include <linux/mm.h> 11#include <linux/mm.h>
11#include <linux/pagemap.h> 12#include <linux/pagemap.h>
12#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
@@ -843,10 +844,10 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
843 DMWARN("write header failed"); 844 DMWARN("write header failed");
844} 845}
845 846
846static int persistent_ctr(struct dm_exception_store *store, 847static int persistent_ctr(struct dm_exception_store *store, char *options)
847 unsigned argc, char **argv)
848{ 848{
849 struct pstore *ps; 849 struct pstore *ps;
850 int r;
850 851
851 /* allocate the pstore */ 852 /* allocate the pstore */
852 ps = kzalloc(sizeof(*ps), GFP_KERNEL); 853 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
@@ -868,14 +869,32 @@ static int persistent_ctr(struct dm_exception_store *store,
868 869
869 ps->metadata_wq = alloc_workqueue("ksnaphd", WQ_MEM_RECLAIM, 0); 870 ps->metadata_wq = alloc_workqueue("ksnaphd", WQ_MEM_RECLAIM, 0);
870 if (!ps->metadata_wq) { 871 if (!ps->metadata_wq) {
871 kfree(ps);
872 DMERR("couldn't start header metadata update thread"); 872 DMERR("couldn't start header metadata update thread");
873 return -ENOMEM; 873 r = -ENOMEM;
874 goto err_workqueue;
875 }
876
877 if (options) {
878 char overflow = toupper(options[0]);
879 if (overflow == 'O')
880 store->userspace_supports_overflow = true;
881 else {
882 DMERR("Unsupported persistent store option: %s", options);
883 r = -EINVAL;
884 goto err_options;
885 }
874 } 886 }
875 887
876 store->context = ps; 888 store->context = ps;
877 889
878 return 0; 890 return 0;
891
892err_options:
893 destroy_workqueue(ps->metadata_wq);
894err_workqueue:
895 kfree(ps);
896
897 return r;
879} 898}
880 899
881static unsigned persistent_status(struct dm_exception_store *store, 900static unsigned persistent_status(struct dm_exception_store *store,
@@ -888,7 +907,8 @@ static unsigned persistent_status(struct dm_exception_store *store,
888 case STATUSTYPE_INFO: 907 case STATUSTYPE_INFO:
889 break; 908 break;
890 case STATUSTYPE_TABLE: 909 case STATUSTYPE_TABLE:
891 DMEMIT(" P %llu", (unsigned long long)store->chunk_size); 910 DMEMIT(" %s %llu", store->userspace_supports_overflow ? "PO" : "P",
911 (unsigned long long)store->chunk_size);
892 } 912 }
893 913
894 return sz; 914 return sz;