diff options
author | Ed Cashin <ecashin@coraid.com> | 2012-10-04 20:16:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-05 14:05:29 -0400 |
commit | 4bcce1a355c8248fb5661cb78bb14b9e19475cd4 (patch) | |
tree | 6a6db4ec3f569bdbbf925d9419d7f89ce7cace34 /drivers/block/aoe/aoedev.c | |
parent | 0c966214589b9767fd8771b71328f83bac58cb25 (diff) |
aoe: retain static block device numbers for backwards compatibility
The old mapping between AoE target shelf and slot addresses and the block
device minor number is retained as a backwards-compatible feature, with a
new "aoe_dyndevs" module parameter available for enabling dynamic block
device minor numbers.
Signed-off-by: Ed Cashin <ecashin@coraid.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block/aoe/aoedev.c')
-rw-r--r-- | drivers/block/aoe/aoedev.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index 68a7a5a9ced0..3d494fdfb43d 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/bitmap.h> | 12 | #include <linux/bitmap.h> |
13 | #include <linux/kdev_t.h> | 13 | #include <linux/kdev_t.h> |
14 | #include <linux/moduleparam.h> | ||
14 | #include "aoe.h" | 15 | #include "aoe.h" |
15 | 16 | ||
16 | static void dummy_timer(ulong); | 17 | static void dummy_timer(ulong); |
@@ -18,6 +19,10 @@ static void aoedev_freedev(struct aoedev *); | |||
18 | static void freetgt(struct aoedev *d, struct aoetgt *t); | 19 | static void freetgt(struct aoedev *d, struct aoetgt *t); |
19 | static void skbpoolfree(struct aoedev *d); | 20 | static void skbpoolfree(struct aoedev *d); |
20 | 21 | ||
22 | static int aoe_dyndevs; | ||
23 | module_param(aoe_dyndevs, int, 0644); | ||
24 | MODULE_PARM_DESC(aoe_dyndevs, "Use dynamic minor numbers for devices."); | ||
25 | |||
21 | static struct aoedev *devlist; | 26 | static struct aoedev *devlist; |
22 | static DEFINE_SPINLOCK(devlist_lock); | 27 | static DEFINE_SPINLOCK(devlist_lock); |
23 | 28 | ||
@@ -34,7 +39,7 @@ static DEFINE_SPINLOCK(used_minors_lock); | |||
34 | static DECLARE_BITMAP(used_minors, N_DEVS); | 39 | static DECLARE_BITMAP(used_minors, N_DEVS); |
35 | 40 | ||
36 | static int | 41 | static int |
37 | minor_get(ulong *minor) | 42 | minor_get_dyn(ulong *sysminor) |
38 | { | 43 | { |
39 | ulong flags; | 44 | ulong flags; |
40 | ulong n; | 45 | ulong n; |
@@ -48,10 +53,53 @@ minor_get(ulong *minor) | |||
48 | error = -1; | 53 | error = -1; |
49 | spin_unlock_irqrestore(&used_minors_lock, flags); | 54 | spin_unlock_irqrestore(&used_minors_lock, flags); |
50 | 55 | ||
51 | *minor = n * AOE_PARTITIONS; | 56 | *sysminor = n * AOE_PARTITIONS; |
52 | return error; | 57 | return error; |
53 | } | 58 | } |
54 | 59 | ||
60 | static int | ||
61 | minor_get_static(ulong *sysminor, ulong aoemaj, int aoemin) | ||
62 | { | ||
63 | ulong flags; | ||
64 | ulong n; | ||
65 | int error = 0; | ||
66 | enum { | ||
67 | /* for backwards compatibility when !aoe_dyndevs, | ||
68 | * a static number of supported slots per shelf */ | ||
69 | NPERSHELF = 16, | ||
70 | }; | ||
71 | |||
72 | n = aoemaj * NPERSHELF + aoemin; | ||
73 | if (aoemin >= NPERSHELF || n >= N_DEVS) { | ||
74 | pr_err("aoe: %s with e%ld.%d\n", | ||
75 | "cannot use static minor device numbers", | ||
76 | aoemaj, aoemin); | ||
77 | error = -1; | ||
78 | } else { | ||
79 | spin_lock_irqsave(&used_minors_lock, flags); | ||
80 | if (test_bit(n, used_minors)) { | ||
81 | pr_err("aoe: %s %lu\n", | ||
82 | "existing device already has static minor number", | ||
83 | n); | ||
84 | error = -1; | ||
85 | } else | ||
86 | set_bit(n, used_minors); | ||
87 | spin_unlock_irqrestore(&used_minors_lock, flags); | ||
88 | } | ||
89 | |||
90 | *sysminor = n; | ||
91 | return error; | ||
92 | } | ||
93 | |||
94 | static int | ||
95 | minor_get(ulong *sysminor, ulong aoemaj, int aoemin) | ||
96 | { | ||
97 | if (aoe_dyndevs) | ||
98 | return minor_get_dyn(sysminor); | ||
99 | else | ||
100 | return minor_get_static(sysminor, aoemaj, aoemin); | ||
101 | } | ||
102 | |||
55 | static void | 103 | static void |
56 | minor_free(ulong minor) | 104 | minor_free(ulong minor) |
57 | { | 105 | { |
@@ -293,7 +341,7 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc) | |||
293 | d->ref++; | 341 | d->ref++; |
294 | break; | 342 | break; |
295 | } | 343 | } |
296 | if (d || !do_alloc || minor_get(&sysminor) < 0) | 344 | if (d || !do_alloc || minor_get(&sysminor, maj, min) < 0) |
297 | goto out; | 345 | goto out; |
298 | d = kcalloc(1, sizeof *d, GFP_ATOMIC); | 346 | d = kcalloc(1, sizeof *d, GFP_ATOMIC); |
299 | if (!d) | 347 | if (!d) |