diff options
author | Stefan Weinhuber <wein@de.ibm.com> | 2008-01-26 08:11:23 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-01-26 08:11:28 -0500 |
commit | 8e09f21574ea3028d5629e5de759e0b196c690c5 (patch) | |
tree | ced4feb1847ee6c2a7b7b4cec8f3118f83d3a386 /drivers/s390/block/dasd_ioctl.c | |
parent | 0ac30be461084f30ad6e22c6b91347e880ed41aa (diff) |
[S390] dasd: add hyper PAV support to DASD device driver, part 1
Parallel access volumes (PAV) is a storage server feature, that allows
to start multiple channel programs on the same DASD in parallel. It
defines alias devices which can be used as alternative paths to the
same disk. With the old base PAV support we only needed rudimentary
functionality in the DASD device driver. As the mapping between base
and alias devices was static, we just had to export an identifier
(uid) and could leave the combining of devices to external layers
like a device mapper multipath.
Now hyper PAV removes the requirement to dedicate alias devices to
specific base devices. Instead each alias devices can be combined with
multiple base device on a per request basis. This requires full
support by the DASD device driver as now each channel program itself
has to identify the target base device.
The changes to the dasd device driver and the ECKD discipline are:
- Separate subchannel device representation (dasd_device) from block
device representation (dasd_block). Only base devices are block
devices.
- Gather information about base and alias devices and possible
combinations.
- For each request decide which dasd_device should be used (base or
alias) and build specific channel program.
- Support summary unit checks, which allow the storage server to
upgrade / downgrade between base and hyper PAV at runtime (support
is mandatory).
Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_ioctl.c')
-rw-r--r-- | drivers/s390/block/dasd_ioctl.c | 172 |
1 files changed, 84 insertions, 88 deletions
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 672eb0a3dd0b..91a64630cb0f 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -38,15 +38,15 @@ dasd_ioctl_api_version(void __user *argp) | |||
38 | static int | 38 | static int |
39 | dasd_ioctl_enable(struct block_device *bdev) | 39 | dasd_ioctl_enable(struct block_device *bdev) |
40 | { | 40 | { |
41 | struct dasd_device *device = bdev->bd_disk->private_data; | 41 | struct dasd_block *block = bdev->bd_disk->private_data; |
42 | 42 | ||
43 | if (!capable(CAP_SYS_ADMIN)) | 43 | if (!capable(CAP_SYS_ADMIN)) |
44 | return -EACCES; | 44 | return -EACCES; |
45 | 45 | ||
46 | dasd_enable_device(device); | 46 | dasd_enable_device(block->base); |
47 | /* Formatting the dasd device can change the capacity. */ | 47 | /* Formatting the dasd device can change the capacity. */ |
48 | mutex_lock(&bdev->bd_mutex); | 48 | mutex_lock(&bdev->bd_mutex); |
49 | i_size_write(bdev->bd_inode, (loff_t)get_capacity(device->gdp) << 9); | 49 | i_size_write(bdev->bd_inode, (loff_t)get_capacity(block->gdp) << 9); |
50 | mutex_unlock(&bdev->bd_mutex); | 50 | mutex_unlock(&bdev->bd_mutex); |
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
@@ -58,7 +58,7 @@ dasd_ioctl_enable(struct block_device *bdev) | |||
58 | static int | 58 | static int |
59 | dasd_ioctl_disable(struct block_device *bdev) | 59 | dasd_ioctl_disable(struct block_device *bdev) |
60 | { | 60 | { |
61 | struct dasd_device *device = bdev->bd_disk->private_data; | 61 | struct dasd_block *block = bdev->bd_disk->private_data; |
62 | 62 | ||
63 | if (!capable(CAP_SYS_ADMIN)) | 63 | if (!capable(CAP_SYS_ADMIN)) |
64 | return -EACCES; | 64 | return -EACCES; |
@@ -71,7 +71,7 @@ dasd_ioctl_disable(struct block_device *bdev) | |||
71 | * using the BIODASDFMT ioctl. Therefore the correct state for the | 71 | * using the BIODASDFMT ioctl. Therefore the correct state for the |
72 | * device is DASD_STATE_BASIC that allows to do basic i/o. | 72 | * device is DASD_STATE_BASIC that allows to do basic i/o. |
73 | */ | 73 | */ |
74 | dasd_set_target_state(device, DASD_STATE_BASIC); | 74 | dasd_set_target_state(block->base, DASD_STATE_BASIC); |
75 | /* | 75 | /* |
76 | * Set i_size to zero, since read, write, etc. check against this | 76 | * Set i_size to zero, since read, write, etc. check against this |
77 | * value. | 77 | * value. |
@@ -85,19 +85,19 @@ dasd_ioctl_disable(struct block_device *bdev) | |||
85 | /* | 85 | /* |
86 | * Quiesce device. | 86 | * Quiesce device. |
87 | */ | 87 | */ |
88 | static int | 88 | static int dasd_ioctl_quiesce(struct dasd_block *block) |
89 | dasd_ioctl_quiesce(struct dasd_device *device) | ||
90 | { | 89 | { |
91 | unsigned long flags; | 90 | unsigned long flags; |
91 | struct dasd_device *base; | ||
92 | 92 | ||
93 | base = block->base; | ||
93 | if (!capable (CAP_SYS_ADMIN)) | 94 | if (!capable (CAP_SYS_ADMIN)) |
94 | return -EACCES; | 95 | return -EACCES; |
95 | 96 | ||
96 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 97 | DEV_MESSAGE(KERN_DEBUG, base, "%s", "Quiesce IO on device"); |
97 | "Quiesce IO on device"); | 98 | spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); |
98 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 99 | base->stopped |= DASD_STOPPED_QUIESCE; |
99 | device->stopped |= DASD_STOPPED_QUIESCE; | 100 | spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); |
100 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
@@ -105,22 +105,21 @@ dasd_ioctl_quiesce(struct dasd_device *device) | |||
105 | /* | 105 | /* |
106 | * Quiesce device. | 106 | * Quiesce device. |
107 | */ | 107 | */ |
108 | static int | 108 | static int dasd_ioctl_resume(struct dasd_block *block) |
109 | dasd_ioctl_resume(struct dasd_device *device) | ||
110 | { | 109 | { |
111 | unsigned long flags; | 110 | unsigned long flags; |
111 | struct dasd_device *base; | ||
112 | 112 | ||
113 | base = block->base; | ||
113 | if (!capable (CAP_SYS_ADMIN)) | 114 | if (!capable (CAP_SYS_ADMIN)) |
114 | return -EACCES; | 115 | return -EACCES; |
115 | 116 | ||
116 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 117 | DEV_MESSAGE(KERN_DEBUG, base, "%s", "resume IO on device"); |
117 | "resume IO on device"); | 118 | spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); |
118 | 119 | base->stopped &= ~DASD_STOPPED_QUIESCE; | |
119 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 120 | spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); |
120 | device->stopped &= ~DASD_STOPPED_QUIESCE; | ||
121 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
122 | 121 | ||
123 | dasd_schedule_bh (device); | 122 | dasd_schedule_block_bh(block); |
124 | return 0; | 123 | return 0; |
125 | } | 124 | } |
126 | 125 | ||
@@ -130,22 +129,23 @@ dasd_ioctl_resume(struct dasd_device *device) | |||
130 | * commands to format a single unit of the device. In terms of the ECKD | 129 | * commands to format a single unit of the device. In terms of the ECKD |
131 | * devices this means CCWs are generated to format a single track. | 130 | * devices this means CCWs are generated to format a single track. |
132 | */ | 131 | */ |
133 | static int | 132 | static int dasd_format(struct dasd_block *block, struct format_data_t *fdata) |
134 | dasd_format(struct dasd_device * device, struct format_data_t * fdata) | ||
135 | { | 133 | { |
136 | struct dasd_ccw_req *cqr; | 134 | struct dasd_ccw_req *cqr; |
135 | struct dasd_device *base; | ||
137 | int rc; | 136 | int rc; |
138 | 137 | ||
139 | if (device->discipline->format_device == NULL) | 138 | base = block->base; |
139 | if (base->discipline->format_device == NULL) | ||
140 | return -EPERM; | 140 | return -EPERM; |
141 | 141 | ||
142 | if (device->state != DASD_STATE_BASIC) { | 142 | if (base->state != DASD_STATE_BASIC) { |
143 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 143 | DEV_MESSAGE(KERN_WARNING, base, "%s", |
144 | "dasd_format: device is not disabled! "); | 144 | "dasd_format: device is not disabled! "); |
145 | return -EBUSY; | 145 | return -EBUSY; |
146 | } | 146 | } |
147 | 147 | ||
148 | DBF_DEV_EVENT(DBF_NOTICE, device, | 148 | DBF_DEV_EVENT(DBF_NOTICE, base, |
149 | "formatting units %d to %d (%d B blocks) flags %d", | 149 | "formatting units %d to %d (%d B blocks) flags %d", |
150 | fdata->start_unit, | 150 | fdata->start_unit, |
151 | fdata->stop_unit, fdata->blksize, fdata->intensity); | 151 | fdata->stop_unit, fdata->blksize, fdata->intensity); |
@@ -156,20 +156,20 @@ dasd_format(struct dasd_device * device, struct format_data_t * fdata) | |||
156 | * enabling the device later. | 156 | * enabling the device later. |
157 | */ | 157 | */ |
158 | if (fdata->start_unit == 0) { | 158 | if (fdata->start_unit == 0) { |
159 | struct block_device *bdev = bdget_disk(device->gdp, 0); | 159 | struct block_device *bdev = bdget_disk(block->gdp, 0); |
160 | bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize); | 160 | bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize); |
161 | bdput(bdev); | 161 | bdput(bdev); |
162 | } | 162 | } |
163 | 163 | ||
164 | while (fdata->start_unit <= fdata->stop_unit) { | 164 | while (fdata->start_unit <= fdata->stop_unit) { |
165 | cqr = device->discipline->format_device(device, fdata); | 165 | cqr = base->discipline->format_device(base, fdata); |
166 | if (IS_ERR(cqr)) | 166 | if (IS_ERR(cqr)) |
167 | return PTR_ERR(cqr); | 167 | return PTR_ERR(cqr); |
168 | rc = dasd_sleep_on_interruptible(cqr); | 168 | rc = dasd_sleep_on_interruptible(cqr); |
169 | dasd_sfree_request(cqr, cqr->device); | 169 | dasd_sfree_request(cqr, cqr->memdev); |
170 | if (rc) { | 170 | if (rc) { |
171 | if (rc != -ERESTARTSYS) | 171 | if (rc != -ERESTARTSYS) |
172 | DEV_MESSAGE(KERN_ERR, device, | 172 | DEV_MESSAGE(KERN_ERR, base, |
173 | " Formatting of unit %d failed " | 173 | " Formatting of unit %d failed " |
174 | "with rc = %d", | 174 | "with rc = %d", |
175 | fdata->start_unit, rc); | 175 | fdata->start_unit, rc); |
@@ -186,7 +186,7 @@ dasd_format(struct dasd_device * device, struct format_data_t * fdata) | |||
186 | static int | 186 | static int |
187 | dasd_ioctl_format(struct block_device *bdev, void __user *argp) | 187 | dasd_ioctl_format(struct block_device *bdev, void __user *argp) |
188 | { | 188 | { |
189 | struct dasd_device *device = bdev->bd_disk->private_data; | 189 | struct dasd_block *block = bdev->bd_disk->private_data; |
190 | struct format_data_t fdata; | 190 | struct format_data_t fdata; |
191 | 191 | ||
192 | if (!capable(CAP_SYS_ADMIN)) | 192 | if (!capable(CAP_SYS_ADMIN)) |
@@ -194,51 +194,47 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp) | |||
194 | if (!argp) | 194 | if (!argp) |
195 | return -EINVAL; | 195 | return -EINVAL; |
196 | 196 | ||
197 | if (device->features & DASD_FEATURE_READONLY) | 197 | if (block->base->features & DASD_FEATURE_READONLY) |
198 | return -EROFS; | 198 | return -EROFS; |
199 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) | 199 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) |
200 | return -EFAULT; | 200 | return -EFAULT; |
201 | if (bdev != bdev->bd_contains) { | 201 | if (bdev != bdev->bd_contains) { |
202 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 202 | DEV_MESSAGE(KERN_WARNING, block->base, "%s", |
203 | "Cannot low-level format a partition"); | 203 | "Cannot low-level format a partition"); |
204 | return -EINVAL; | 204 | return -EINVAL; |
205 | } | 205 | } |
206 | return dasd_format(device, &fdata); | 206 | return dasd_format(block, &fdata); |
207 | } | 207 | } |
208 | 208 | ||
209 | #ifdef CONFIG_DASD_PROFILE | 209 | #ifdef CONFIG_DASD_PROFILE |
210 | /* | 210 | /* |
211 | * Reset device profile information | 211 | * Reset device profile information |
212 | */ | 212 | */ |
213 | static int | 213 | static int dasd_ioctl_reset_profile(struct dasd_block *block) |
214 | dasd_ioctl_reset_profile(struct dasd_device *device) | ||
215 | { | 214 | { |
216 | memset(&device->profile, 0, sizeof (struct dasd_profile_info_t)); | 215 | memset(&block->profile, 0, sizeof(struct dasd_profile_info_t)); |
217 | return 0; | 216 | return 0; |
218 | } | 217 | } |
219 | 218 | ||
220 | /* | 219 | /* |
221 | * Return device profile information | 220 | * Return device profile information |
222 | */ | 221 | */ |
223 | static int | 222 | static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp) |
224 | dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) | ||
225 | { | 223 | { |
226 | if (dasd_profile_level == DASD_PROFILE_OFF) | 224 | if (dasd_profile_level == DASD_PROFILE_OFF) |
227 | return -EIO; | 225 | return -EIO; |
228 | if (copy_to_user(argp, &device->profile, | 226 | if (copy_to_user(argp, &block->profile, |
229 | sizeof (struct dasd_profile_info_t))) | 227 | sizeof(struct dasd_profile_info_t))) |
230 | return -EFAULT; | 228 | return -EFAULT; |
231 | return 0; | 229 | return 0; |
232 | } | 230 | } |
233 | #else | 231 | #else |
234 | static int | 232 | static int dasd_ioctl_reset_profile(struct dasd_block *block) |
235 | dasd_ioctl_reset_profile(struct dasd_device *device) | ||
236 | { | 233 | { |
237 | return -ENOSYS; | 234 | return -ENOSYS; |
238 | } | 235 | } |
239 | 236 | ||
240 | static int | 237 | static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp) |
241 | dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) | ||
242 | { | 238 | { |
243 | return -ENOSYS; | 239 | return -ENOSYS; |
244 | } | 240 | } |
@@ -247,87 +243,88 @@ dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) | |||
247 | /* | 243 | /* |
248 | * Return dasd information. Used for BIODASDINFO and BIODASDINFO2. | 244 | * Return dasd information. Used for BIODASDINFO and BIODASDINFO2. |
249 | */ | 245 | */ |
250 | static int | 246 | static int dasd_ioctl_information(struct dasd_block *block, |
251 | dasd_ioctl_information(struct dasd_device *device, | 247 | unsigned int cmd, void __user *argp) |
252 | unsigned int cmd, void __user *argp) | ||
253 | { | 248 | { |
254 | struct dasd_information2_t *dasd_info; | 249 | struct dasd_information2_t *dasd_info; |
255 | unsigned long flags; | 250 | unsigned long flags; |
256 | int rc; | 251 | int rc; |
252 | struct dasd_device *base; | ||
257 | struct ccw_device *cdev; | 253 | struct ccw_device *cdev; |
258 | struct ccw_dev_id dev_id; | 254 | struct ccw_dev_id dev_id; |
259 | 255 | ||
260 | if (!device->discipline->fill_info) | 256 | base = block->base; |
257 | if (!base->discipline->fill_info) | ||
261 | return -EINVAL; | 258 | return -EINVAL; |
262 | 259 | ||
263 | dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); | 260 | dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); |
264 | if (dasd_info == NULL) | 261 | if (dasd_info == NULL) |
265 | return -ENOMEM; | 262 | return -ENOMEM; |
266 | 263 | ||
267 | rc = device->discipline->fill_info(device, dasd_info); | 264 | rc = base->discipline->fill_info(base, dasd_info); |
268 | if (rc) { | 265 | if (rc) { |
269 | kfree(dasd_info); | 266 | kfree(dasd_info); |
270 | return rc; | 267 | return rc; |
271 | } | 268 | } |
272 | 269 | ||
273 | cdev = device->cdev; | 270 | cdev = base->cdev; |
274 | ccw_device_get_id(cdev, &dev_id); | 271 | ccw_device_get_id(cdev, &dev_id); |
275 | 272 | ||
276 | dasd_info->devno = dev_id.devno; | 273 | dasd_info->devno = dev_id.devno; |
277 | dasd_info->schid = _ccw_device_get_subchannel_number(device->cdev); | 274 | dasd_info->schid = _ccw_device_get_subchannel_number(base->cdev); |
278 | dasd_info->cu_type = cdev->id.cu_type; | 275 | dasd_info->cu_type = cdev->id.cu_type; |
279 | dasd_info->cu_model = cdev->id.cu_model; | 276 | dasd_info->cu_model = cdev->id.cu_model; |
280 | dasd_info->dev_type = cdev->id.dev_type; | 277 | dasd_info->dev_type = cdev->id.dev_type; |
281 | dasd_info->dev_model = cdev->id.dev_model; | 278 | dasd_info->dev_model = cdev->id.dev_model; |
282 | dasd_info->status = device->state; | 279 | dasd_info->status = base->state; |
283 | /* | 280 | /* |
284 | * The open_count is increased for every opener, that includes | 281 | * The open_count is increased for every opener, that includes |
285 | * the blkdev_get in dasd_scan_partitions. | 282 | * the blkdev_get in dasd_scan_partitions. |
286 | * This must be hidden from user-space. | 283 | * This must be hidden from user-space. |
287 | */ | 284 | */ |
288 | dasd_info->open_count = atomic_read(&device->open_count); | 285 | dasd_info->open_count = atomic_read(&block->open_count); |
289 | if (!device->bdev) | 286 | if (!block->bdev) |
290 | dasd_info->open_count++; | 287 | dasd_info->open_count++; |
291 | 288 | ||
292 | /* | 289 | /* |
293 | * check if device is really formatted | 290 | * check if device is really formatted |
294 | * LDL / CDL was returned by 'fill_info' | 291 | * LDL / CDL was returned by 'fill_info' |
295 | */ | 292 | */ |
296 | if ((device->state < DASD_STATE_READY) || | 293 | if ((base->state < DASD_STATE_READY) || |
297 | (dasd_check_blocksize(device->bp_block))) | 294 | (dasd_check_blocksize(block->bp_block))) |
298 | dasd_info->format = DASD_FORMAT_NONE; | 295 | dasd_info->format = DASD_FORMAT_NONE; |
299 | 296 | ||
300 | dasd_info->features |= | 297 | dasd_info->features |= |
301 | ((device->features & DASD_FEATURE_READONLY) != 0); | 298 | ((base->features & DASD_FEATURE_READONLY) != 0); |
302 | 299 | ||
303 | if (device->discipline) | 300 | if (base->discipline) |
304 | memcpy(dasd_info->type, device->discipline->name, 4); | 301 | memcpy(dasd_info->type, base->discipline->name, 4); |
305 | else | 302 | else |
306 | memcpy(dasd_info->type, "none", 4); | 303 | memcpy(dasd_info->type, "none", 4); |
307 | 304 | ||
308 | if (device->request_queue->request_fn) { | 305 | if (block->request_queue->request_fn) { |
309 | struct list_head *l; | 306 | struct list_head *l; |
310 | #ifdef DASD_EXTENDED_PROFILING | 307 | #ifdef DASD_EXTENDED_PROFILING |
311 | { | 308 | { |
312 | struct list_head *l; | 309 | struct list_head *l; |
313 | spin_lock_irqsave(&device->lock, flags); | 310 | spin_lock_irqsave(&block->lock, flags); |
314 | list_for_each(l, &device->request_queue->queue_head) | 311 | list_for_each(l, &block->request_queue->queue_head) |
315 | dasd_info->req_queue_len++; | 312 | dasd_info->req_queue_len++; |
316 | spin_unlock_irqrestore(&device->lock, flags); | 313 | spin_unlock_irqrestore(&block->lock, flags); |
317 | } | 314 | } |
318 | #endif /* DASD_EXTENDED_PROFILING */ | 315 | #endif /* DASD_EXTENDED_PROFILING */ |
319 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 316 | spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); |
320 | list_for_each(l, &device->ccw_queue) | 317 | list_for_each(l, &base->ccw_queue) |
321 | dasd_info->chanq_len++; | 318 | dasd_info->chanq_len++; |
322 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), | 319 | spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), |
323 | flags); | 320 | flags); |
324 | } | 321 | } |
325 | 322 | ||
326 | rc = 0; | 323 | rc = 0; |
327 | if (copy_to_user(argp, dasd_info, | 324 | if (copy_to_user(argp, dasd_info, |
328 | ((cmd == (unsigned int) BIODASDINFO2) ? | 325 | ((cmd == (unsigned int) BIODASDINFO2) ? |
329 | sizeof (struct dasd_information2_t) : | 326 | sizeof(struct dasd_information2_t) : |
330 | sizeof (struct dasd_information_t)))) | 327 | sizeof(struct dasd_information_t)))) |
331 | rc = -EFAULT; | 328 | rc = -EFAULT; |
332 | kfree(dasd_info); | 329 | kfree(dasd_info); |
333 | return rc; | 330 | return rc; |
@@ -339,7 +336,7 @@ dasd_ioctl_information(struct dasd_device *device, | |||
339 | static int | 336 | static int |
340 | dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | 337 | dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) |
341 | { | 338 | { |
342 | struct dasd_device *device = bdev->bd_disk->private_data; | 339 | struct dasd_block *block = bdev->bd_disk->private_data; |
343 | int intval; | 340 | int intval; |
344 | 341 | ||
345 | if (!capable(CAP_SYS_ADMIN)) | 342 | if (!capable(CAP_SYS_ADMIN)) |
@@ -351,11 +348,10 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | |||
351 | return -EFAULT; | 348 | return -EFAULT; |
352 | 349 | ||
353 | set_disk_ro(bdev->bd_disk, intval); | 350 | set_disk_ro(bdev->bd_disk, intval); |
354 | return dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval); | 351 | return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); |
355 | } | 352 | } |
356 | 353 | ||
357 | static int | 354 | static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, |
358 | dasd_ioctl_readall_cmb(struct dasd_device *device, unsigned int cmd, | ||
359 | unsigned long arg) | 355 | unsigned long arg) |
360 | { | 356 | { |
361 | struct cmbdata __user *argp = (void __user *) arg; | 357 | struct cmbdata __user *argp = (void __user *) arg; |
@@ -363,7 +359,7 @@ dasd_ioctl_readall_cmb(struct dasd_device *device, unsigned int cmd, | |||
363 | struct cmbdata data; | 359 | struct cmbdata data; |
364 | int ret; | 360 | int ret; |
365 | 361 | ||
366 | ret = cmf_readall(device->cdev, &data); | 362 | ret = cmf_readall(block->base->cdev, &data); |
367 | if (!ret && copy_to_user(argp, &data, min(size, sizeof(*argp)))) | 363 | if (!ret && copy_to_user(argp, &data, min(size, sizeof(*argp)))) |
368 | return -EFAULT; | 364 | return -EFAULT; |
369 | return ret; | 365 | return ret; |
@@ -374,10 +370,10 @@ dasd_ioctl(struct inode *inode, struct file *file, | |||
374 | unsigned int cmd, unsigned long arg) | 370 | unsigned int cmd, unsigned long arg) |
375 | { | 371 | { |
376 | struct block_device *bdev = inode->i_bdev; | 372 | struct block_device *bdev = inode->i_bdev; |
377 | struct dasd_device *device = bdev->bd_disk->private_data; | 373 | struct dasd_block *block = bdev->bd_disk->private_data; |
378 | void __user *argp = (void __user *)arg; | 374 | void __user *argp = (void __user *)arg; |
379 | 375 | ||
380 | if (!device) | 376 | if (!block) |
381 | return -ENODEV; | 377 | return -ENODEV; |
382 | 378 | ||
383 | if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { | 379 | if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { |
@@ -391,33 +387,33 @@ dasd_ioctl(struct inode *inode, struct file *file, | |||
391 | case BIODASDENABLE: | 387 | case BIODASDENABLE: |
392 | return dasd_ioctl_enable(bdev); | 388 | return dasd_ioctl_enable(bdev); |
393 | case BIODASDQUIESCE: | 389 | case BIODASDQUIESCE: |
394 | return dasd_ioctl_quiesce(device); | 390 | return dasd_ioctl_quiesce(block); |
395 | case BIODASDRESUME: | 391 | case BIODASDRESUME: |
396 | return dasd_ioctl_resume(device); | 392 | return dasd_ioctl_resume(block); |
397 | case BIODASDFMT: | 393 | case BIODASDFMT: |
398 | return dasd_ioctl_format(bdev, argp); | 394 | return dasd_ioctl_format(bdev, argp); |
399 | case BIODASDINFO: | 395 | case BIODASDINFO: |
400 | return dasd_ioctl_information(device, cmd, argp); | 396 | return dasd_ioctl_information(block, cmd, argp); |
401 | case BIODASDINFO2: | 397 | case BIODASDINFO2: |
402 | return dasd_ioctl_information(device, cmd, argp); | 398 | return dasd_ioctl_information(block, cmd, argp); |
403 | case BIODASDPRRD: | 399 | case BIODASDPRRD: |
404 | return dasd_ioctl_read_profile(device, argp); | 400 | return dasd_ioctl_read_profile(block, argp); |
405 | case BIODASDPRRST: | 401 | case BIODASDPRRST: |
406 | return dasd_ioctl_reset_profile(device); | 402 | return dasd_ioctl_reset_profile(block); |
407 | case BLKROSET: | 403 | case BLKROSET: |
408 | return dasd_ioctl_set_ro(bdev, argp); | 404 | return dasd_ioctl_set_ro(bdev, argp); |
409 | case DASDAPIVER: | 405 | case DASDAPIVER: |
410 | return dasd_ioctl_api_version(argp); | 406 | return dasd_ioctl_api_version(argp); |
411 | case BIODASDCMFENABLE: | 407 | case BIODASDCMFENABLE: |
412 | return enable_cmf(device->cdev); | 408 | return enable_cmf(block->base->cdev); |
413 | case BIODASDCMFDISABLE: | 409 | case BIODASDCMFDISABLE: |
414 | return disable_cmf(device->cdev); | 410 | return disable_cmf(block->base->cdev); |
415 | case BIODASDREADALLCMB: | 411 | case BIODASDREADALLCMB: |
416 | return dasd_ioctl_readall_cmb(device, cmd, arg); | 412 | return dasd_ioctl_readall_cmb(block, cmd, arg); |
417 | default: | 413 | default: |
418 | /* if the discipline has an ioctl method try it. */ | 414 | /* if the discipline has an ioctl method try it. */ |
419 | if (device->discipline->ioctl) { | 415 | if (block->base->discipline->ioctl) { |
420 | int rval = device->discipline->ioctl(device, cmd, argp); | 416 | int rval = block->base->discipline->ioctl(block, cmd, argp); |
421 | if (rval != -ENOIOCTLCMD) | 417 | if (rval != -ENOIOCTLCMD) |
422 | return rval; | 418 | return rval; |
423 | } | 419 | } |