]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: xpram: per device block request queues | |
3 | References: bnc#434333,LTC#49030 | |
4 | ||
5 | Symptom: With recent kernels removing xpram module fails to clean up all | |
6 | sysfs files. The next time the xpram module is loaded you'll get | |
7 | warnings: | |
8 | ||
9 | WARNING: at fs/sysfs/dir.c:463 sysfs_add_one+0x5e/0x64() | |
10 | sysfs: duplicate filename '35:0' can not be created | |
11 | Modules linked in: xpram(+) [last unloaded: xpram] | |
12 | ||
13 | Followed by the usual WARN_ON output, followed by an error message | |
14 | from kobject_add_internal, followed by a badness in genhd. | |
15 | Problem: The xpram driver uses a single block device queue for all of its | |
16 | devices so far. | |
17 | Solution: Allocating a block queue per device fixes this. | |
18 | ||
19 | Acked-by: John Jolly <jjolly@suse.de> | |
20 | --- | |
21 | ||
22 | drivers/s390/block/xpram.c | 37 +++++++++++++++---------------------- | |
23 | 1 file changed, 15 insertions(+), 22 deletions(-) | |
24 | ||
25 | --- a/drivers/s390/block/xpram.c | |
26 | +++ b/drivers/s390/block/xpram.c | |
27 | @@ -52,6 +52,7 @@ typedef struct { | |
28 | static xpram_device_t xpram_devices[XPRAM_MAX_DEVS]; | |
29 | static unsigned int xpram_sizes[XPRAM_MAX_DEVS]; | |
30 | static struct gendisk *xpram_disks[XPRAM_MAX_DEVS]; | |
31 | +static struct request_queue *xpram_queues[XPRAM_MAX_DEVS]; | |
32 | static unsigned int xpram_pages; | |
33 | static int xpram_devs; | |
34 | ||
35 | @@ -326,18 +327,22 @@ static int __init xpram_setup_sizes(unsi | |
36 | return 0; | |
37 | } | |
38 | ||
39 | -static struct request_queue *xpram_queue; | |
40 | - | |
41 | static int __init xpram_setup_blkdev(void) | |
42 | { | |
43 | unsigned long offset; | |
44 | int i, rc = -ENOMEM; | |
45 | ||
46 | for (i = 0; i < xpram_devs; i++) { | |
47 | - struct gendisk *disk = alloc_disk(1); | |
48 | - if (!disk) | |
49 | + xpram_disks[i] = alloc_disk(1); | |
50 | + if (!xpram_disks[i]) | |
51 | + goto out; | |
52 | + xpram_queues[i] = blk_alloc_queue(GFP_KERNEL); | |
53 | + if (!xpram_queues[i]) { | |
54 | + put_disk(xpram_disks[i]); | |
55 | goto out; | |
56 | - xpram_disks[i] = disk; | |
57 | + } | |
58 | + blk_queue_make_request(xpram_queues[i], xpram_make_request); | |
59 | + blk_queue_hardsect_size(xpram_queues[i], 4096); | |
60 | } | |
61 | ||
62 | /* | |
63 | @@ -348,18 +353,6 @@ static int __init xpram_setup_blkdev(voi | |
64 | goto out; | |
65 | ||
66 | /* | |
67 | - * Assign the other needed values: make request function, sizes and | |
68 | - * hardsect size. All the minor devices feature the same value. | |
69 | - */ | |
70 | - xpram_queue = blk_alloc_queue(GFP_KERNEL); | |
71 | - if (!xpram_queue) { | |
72 | - rc = -ENOMEM; | |
73 | - goto out_unreg; | |
74 | - } | |
75 | - blk_queue_make_request(xpram_queue, xpram_make_request); | |
76 | - blk_queue_hardsect_size(xpram_queue, 4096); | |
77 | - | |
78 | - /* | |
79 | * Setup device structures. | |
80 | */ | |
81 | offset = 0; | |
82 | @@ -373,18 +366,18 @@ static int __init xpram_setup_blkdev(voi | |
83 | disk->first_minor = i; | |
84 | disk->fops = &xpram_devops; | |
85 | disk->private_data = &xpram_devices[i]; | |
86 | - disk->queue = xpram_queue; | |
87 | + disk->queue = xpram_queues[i]; | |
88 | sprintf(disk->disk_name, "slram%d", i); | |
89 | set_capacity(disk, xpram_sizes[i] << 1); | |
90 | add_disk(disk); | |
91 | } | |
92 | ||
93 | return 0; | |
94 | -out_unreg: | |
95 | - unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); | |
96 | out: | |
97 | - while (i--) | |
98 | + while (i--) { | |
99 | + blk_cleanup_queue(xpram_queues[i]); | |
100 | put_disk(xpram_disks[i]); | |
101 | + } | |
102 | return rc; | |
103 | } | |
104 | ||
105 | @@ -396,10 +389,10 @@ static void __exit xpram_exit(void) | |
106 | int i; | |
107 | for (i = 0; i < xpram_devs; i++) { | |
108 | del_gendisk(xpram_disks[i]); | |
109 | + blk_cleanup_queue(xpram_queues[i]); | |
110 | put_disk(xpram_disks[i]); | |
111 | } | |
112 | unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); | |
113 | - blk_cleanup_queue(xpram_queue); | |
114 | } | |
115 | ||
116 | static int __init xpram_init(void) |