.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | #include <linux/module.h> |
---|
2 | 3 | #include <linux/types.h> |
---|
3 | 4 | #include <linux/string.h> |
---|
.. | .. |
---|
224 | 225 | * and the door_lock is irrelevant at this point. |
---|
225 | 226 | */ |
---|
226 | 227 | drive->disk_ops->set_doorlock(drive, disk, 1); |
---|
227 | | - drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
---|
228 | | - check_disk_change(bdev); |
---|
| 228 | + if (__invalidate_device(bdev, true)) |
---|
| 229 | + pr_warn("VFS: busy inodes on changed media %s\n", |
---|
| 230 | + bdev->bd_disk->disk_name); |
---|
| 231 | + drive->disk_ops->get_capacity(drive); |
---|
| 232 | + set_capacity(disk, ide_gd_capacity(drive)); |
---|
| 233 | + set_bit(GD_NEED_PART_SCAN, &disk->state); |
---|
229 | 234 | } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) { |
---|
230 | 235 | ret = -EBUSY; |
---|
231 | 236 | goto out_put_idkp; |
---|
.. | .. |
---|
283 | 288 | return 0; |
---|
284 | 289 | } |
---|
285 | 290 | |
---|
286 | | -static unsigned int ide_gd_check_events(struct gendisk *disk, |
---|
287 | | - unsigned int clearing) |
---|
288 | | -{ |
---|
289 | | - struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); |
---|
290 | | - ide_drive_t *drive = idkp->drive; |
---|
291 | | - bool ret; |
---|
292 | | - |
---|
293 | | - /* do not scan partitions twice if this is a removable device */ |
---|
294 | | - if (drive->dev_flags & IDE_DFLAG_ATTACH) { |
---|
295 | | - drive->dev_flags &= ~IDE_DFLAG_ATTACH; |
---|
296 | | - return 0; |
---|
297 | | - } |
---|
298 | | - |
---|
299 | | - /* |
---|
300 | | - * The following is used to force revalidation on the first open on |
---|
301 | | - * removeable devices, and never gets reported to userland as |
---|
302 | | - * genhd->events is 0. This is intended as removeable ide disk |
---|
303 | | - * can't really detect MEDIA_CHANGE events. |
---|
304 | | - */ |
---|
305 | | - ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED; |
---|
306 | | - drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; |
---|
307 | | - |
---|
308 | | - return ret ? DISK_EVENT_MEDIA_CHANGE : 0; |
---|
309 | | -} |
---|
310 | | - |
---|
311 | 291 | static void ide_gd_unlock_native_capacity(struct gendisk *disk) |
---|
312 | 292 | { |
---|
313 | 293 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); |
---|
.. | .. |
---|
316 | 296 | |
---|
317 | 297 | if (disk_ops->unlock_native_capacity) |
---|
318 | 298 | disk_ops->unlock_native_capacity(drive); |
---|
319 | | -} |
---|
320 | | - |
---|
321 | | -static int ide_gd_revalidate_disk(struct gendisk *disk) |
---|
322 | | -{ |
---|
323 | | - struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); |
---|
324 | | - ide_drive_t *drive = idkp->drive; |
---|
325 | | - |
---|
326 | | - if (ide_gd_check_events(disk, 0)) |
---|
327 | | - drive->disk_ops->get_capacity(drive); |
---|
328 | | - |
---|
329 | | - set_capacity(disk, ide_gd_capacity(drive)); |
---|
330 | | - return 0; |
---|
331 | 299 | } |
---|
332 | 300 | |
---|
333 | 301 | static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode, |
---|
.. | .. |
---|
339 | 307 | return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg); |
---|
340 | 308 | } |
---|
341 | 309 | |
---|
| 310 | +#ifdef CONFIG_COMPAT |
---|
| 311 | +static int ide_gd_compat_ioctl(struct block_device *bdev, fmode_t mode, |
---|
| 312 | + unsigned int cmd, unsigned long arg) |
---|
| 313 | +{ |
---|
| 314 | + struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); |
---|
| 315 | + ide_drive_t *drive = idkp->drive; |
---|
| 316 | + |
---|
| 317 | + if (!drive->disk_ops->compat_ioctl) |
---|
| 318 | + return -ENOIOCTLCMD; |
---|
| 319 | + |
---|
| 320 | + return drive->disk_ops->compat_ioctl(drive, bdev, mode, cmd, arg); |
---|
| 321 | +} |
---|
| 322 | +#endif |
---|
| 323 | + |
---|
342 | 324 | static const struct block_device_operations ide_gd_ops = { |
---|
343 | 325 | .owner = THIS_MODULE, |
---|
344 | 326 | .open = ide_gd_unlocked_open, |
---|
345 | 327 | .release = ide_gd_release, |
---|
346 | 328 | .ioctl = ide_gd_ioctl, |
---|
| 329 | +#ifdef CONFIG_COMPAT |
---|
| 330 | + .compat_ioctl = ide_gd_compat_ioctl, |
---|
| 331 | +#endif |
---|
347 | 332 | .getgeo = ide_gd_getgeo, |
---|
348 | | - .check_events = ide_gd_check_events, |
---|
349 | 333 | .unlock_native_capacity = ide_gd_unlock_native_capacity, |
---|
350 | | - .revalidate_disk = ide_gd_revalidate_disk |
---|
351 | 334 | }; |
---|
352 | 335 | |
---|
353 | 336 | static int ide_gd_probe(ide_drive_t *drive) |
---|
.. | .. |
---|
416 | 399 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) |
---|
417 | 400 | g->flags = GENHD_FL_REMOVABLE; |
---|
418 | 401 | g->fops = &ide_gd_ops; |
---|
419 | | - device_add_disk(&drive->gendev, g); |
---|
| 402 | + g->events = DISK_EVENT_MEDIA_CHANGE; |
---|
| 403 | + device_add_disk(&drive->gendev, g, NULL); |
---|
420 | 404 | return 0; |
---|
421 | 405 | |
---|
422 | 406 | out_free_disk: |
---|