History

floppy: bail out in open() if drive is not responding to block0 read

In case reading of block 0 during open() fails, it is not the right thing to let open() succeed. Fix this by introducing FD_OPEN_SHOULD_FAIL_BIT flag, and setting it in case the bio callback encounters an error while trying to read block 0. As a bonus, this works around certain broken userspace (blkid), which is not able to properly handle read()s returning IO errors. Hence be nice to those, and bail out during open() already; if block 0 is not readable, read()s are not going to provide any meaningful data anyway.

Jiri Kosina committed 12 years ago

Commit 7b7b68b1 parent 8586ea92 files · +29 −10Browse files

Unified · Split

2 files
  1. drivers/block/floppy.c +27 −9
  2. include/uapi/linux/fd.h +2 −1
drivers/block/floppy.c+27−9
@@ -3691,9 +3691,12 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) · 3690 unmodified lines
36913691 if (!(mode & FMODE_NDELAY)) {
36923692 if (mode & (FMODE_READ|FMODE_WRITE)) {
36933693 UDRS->last_checked = 0;
3694+ clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
36943695 check_disk_change(bdev);
36953696 if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
36963697 goto out;
3698+ if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags))
3699+ goto out;
36973700 }
36983701 res = -EROFS;
36993702 if ((mode & FMODE_WRITE) &&
@@ -3746,17 +3749,29 @@ static unsigned int floppy_check_events(struct gendisk *disk, · 46 unmodified lines
37463749 * a disk in the drive, and whether that disk is writable.
37473750 */
37483751
3749−static void floppy_rb0_complete(struct bio *bio, int err)
3752+struct rb0_cbdata {
3753+ int drive;
3754+ struct completion complete;
3755+};
3756+
3757+static void floppy_rb0_cb(struct bio *bio, int err)
37503758 {
3751− complete((struct completion *)bio->bi_private);
3759+ struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private;
3760+ int drive = cbdata->drive;
3761+
3762+ if (err) {
3763+ pr_info("floppy: error %d while reading block 0", err);
3764+ set_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
3765+ }
3766+ complete(&cbdata->complete);
37523767 }
37533768
3754−static int __floppy_read_block_0(struct block_device *bdev)
3769+static int __floppy_read_block_0(struct block_device *bdev, int drive)
37553770 {
37563771 struct bio bio;
37573772 struct bio_vec bio_vec;
3758− struct completion complete;
37593773 struct page *page;
3774+ struct rb0_cbdata cbdata;
37603775 size_t size;
37613776
37623777 page = alloc_page(GFP_NOIO);
@@ -3769,6 +3784,8 @@ static int __floppy_read_block_0(struct block_device *bdev) · 6 unmodified lines
37693784 if (!size)
37703785 size = 1024;
37713786
3787+ cbdata.drive = drive;
3788+
37723789 bio_init(&bio);
37733790 bio.bi_io_vec = &bio_vec;
37743791 bio_vec.bv_page = page;
@@ -3779,13 +3796,14 @@ static int __floppy_read_block_0(struct block_device *bdev) · 4 unmodified lines
37793796 bio.bi_bdev = bdev;
37803797 bio.bi_iter.bi_sector = 0;
37813798 bio.bi_flags = (1 << BIO_QUIET);
3782− init_completion(&complete);
3783− bio.bi_private = &complete;
3784− bio.bi_end_io = floppy_rb0_complete;
3799+ bio.bi_private = &cbdata;
3800+ bio.bi_end_io = floppy_rb0_cb;
37853801
37863802 submit_bio(READ, &bio);
37873803 process_fd_request();
3788− wait_for_completion(&complete);
3804+
3805+ init_completion(&cbdata.complete);
3806+ wait_for_completion(&cbdata.complete);
37893807
37903808 __free_page(page);
37913809
@@ -3827,7 +3845,7 @@ static int floppy_revalidate(struct gendisk *disk) · 35 unmodified lines
38273845 UDRS->generation++;
38283846 if (drive_no_geom(drive)) {
38293847 /* auto-sensing */
3830− res = __floppy_read_block_0(opened_bdev[drive]);
3848+ res = __floppy_read_block_0(opened_bdev[drive], drive);
38313849 } else {
38323850 if (cf)
38333851 poll_drive(false, FD_RAW_NEED_DISK);
include/uapi/linux/fd.h+2−1
@@ -185,7 +185,8 @@ enum { · 184 unmodified lines
185185 * to clear media change status */
186186 FD_UNUSED_BIT,
187187 FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */
188− FD_DISK_WRITABLE_BIT /* disk is writable */
188+ FD_DISK_WRITABLE_BIT, /* disk is writable */
189+ FD_OPEN_SHOULD_FAIL_BIT
189190 };
190191
191192 #define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t