| .. | .. |
|---|
| 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: |
|---|