Re: [PATCH] floppy: reintroduce O_NDELAY fix

Denis Efremov
2021-01-26T17:48:51Z

On 1/22/21 2:13 PM, Jiri Kosina wrote:
> From: Jiri Kosina <jkosina@suse.cz>
>
> This issue was originally fixed in 09954bad4 ("floppy: refactor open()
> flags handling").
>
> The fix as a side-effect, however, introduce issue for open(O_ACCMODE)
> that is being used for ioctl-only open. I wrote a fix for that, but
> instead of it being merged, full revert of 09954bad4 was performed,
> re-introducing the O_NDELAY / O_NONBLOCK issue, and it strikes again.
>
> This is a forward-port of the original fix to current codebase; the
> original submission had the changelog below:
>
> ====
> Commit 09954bad4 ("floppy: refactor open() flags handling"), as a
> side-effect, causes open(/dev/fdX, O_ACCMODE) to fail. It turns out that
> this is being used setfdprm userspace for ioctl-only open().
>
> Reintroduce back the original behavior wrt !(FMODE_READ|FMODE_WRITE)
> modes, while still keeping the original O_NDELAY bug fixed.
>
> Cc: stable@vger.kernel.org
> Reported-by: Wim Osterholt <wim@djo.tudelft.nl>
> Tested-by: Wim Osterholt <wim@djo.tudelft.nl>
> Reported-and-tested-by: Kurt Garloff <kurt@garloff.de>
> Fixes: 09954bad4 ("floppy: refactor open() flags handling")
> Fixes: f2791e7ead ("Revert "floppy: refactor open() flags handling"")
> Signed-off-by: Jiri Kosina <jkosina@suse.cz>

Applied. I'll send it to Jens soon with a couple of cleanup patches.

https://github.com/evdenis/linux-floppy/commit/e32f6163c47efbdbad06258560aa00d1c7e5b699

Thanks,
Denis

> ---
> drivers/block/floppy.c | 30 +++++++++++++++---------------
> 1 file changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
> index dfe1dfc901cc..0b71292d9d5a 100644
> --- a/drivers/block/floppy.c
> +++ b/drivers/block/floppy.c
> @@ -4121,23 +4121,23 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
> if (fdc_state[FDC(drive)].rawcmd == 1)
> fdc_state[FDC(drive)].rawcmd = 2;
>
> - if (!(mode & FMODE_NDELAY)) {
> - if (mode & (FMODE_READ|FMODE_WRITE)) {
> - drive_state[drive].last_checked = 0;
> - clear_bit(FD_OPEN_SHOULD_FAIL_BIT,
> - &drive_state[drive].flags);
> - if (bdev_check_media_change(bdev))
> - floppy_revalidate(bdev->bd_disk);
> - if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags))
> - goto out;
> - if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags))
> - goto out;
> - }
> - res = -EROFS;
> - if ((mode & FMODE_WRITE) &&
> - !test_bit(FD_DISK_WRITABLE_BIT, &drive_state[drive].flags))
> + if (mode & (FMODE_READ|FMODE_WRITE)) {
> + drive_state[drive].last_checked = 0;
> + clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags);
> + if (bdev_check_media_change(bdev))
> + floppy_revalidate(bdev->bd_disk);
> + if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags))
> + goto out;
> + if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags))
> goto out;
> }
> +
> + res = -EROFS;
> +
> + if ((mode & FMODE_WRITE) &&
> + !test_bit(FD_DISK_WRITABLE_BIT, &drive_state[drive].flags))
> + goto out;
> +
> mutex_unlock(&open_lock);
> mutex_unlock(&floppy_mutex);
> return 0;
>