Browse Source

libblkid: reopen floppy without O_NONBLOCK

Vladimir Sementsov-Ogievskiy wrote:
> The commit "floppy: reintroduce O_NDELAY fix" was removed from kernel,
> so we faced the bug described and discussed here:
> https://bugzilla.suse.com/show_bug.cgi?id=3D1181018
>
> Discussion in kernel list on reverting the commit:
> https://www.spinics.net/lists/stable/msg493061.html
>
> In short, I can quote Jiri Kosina's comment:
>
>   opening floppy device node with O_NONBLOCK is asking for all kinds
>   of trouble
>
> So opening floppy with O_NONBLOCK in blkid leads to failure of blkid,
> probable failure of mount and unpleasant error messages in dmesg (see
> also patch 02 for details).

Based on patch from Vladimir.

CC: Jiri Kosina <jkosina@suse.cz>
Reported-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Tested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
pull/1573/head
Karel Zak 7 months ago
parent
commit
2d24f96399
  1. 3
      include/fileutils.h
  2. 19
      lib/fileutils.c
  3. 33
      libblkid/src/probe.c

3
include/fileutils.h

@ -97,4 +97,7 @@ extern void ul_close_all_fds(unsigned int first, unsigned int last);
#define UL_COPY_WRITE_ERROR (-2)
int ul_copy_file(int from, int to);
extern int ul_reopen(int fd, int flags);
#endif /* UTIL_LINUX_FILEUTILS */

19
lib/fileutils.c

@ -288,3 +288,22 @@ int ul_copy_file(int from, int to)
return copy_file_simple(from, to);
#endif
}
int ul_reopen(int fd, int flags)
{
ssize_t ssz;
char buf[PATH_MAX];
char fdpath[ sizeof(_PATH_PROC_FDDIR) + sizeof(stringify_value(INT_MAX)) ];
snprintf(fdpath, sizeof(fdpath), _PATH_PROC_FDDIR "/%d", fd);
ssz = readlink(fdpath, buf, sizeof(buf) - 1);
if (ssz < 0)
return -errno;
assert(ssz > 0);
buf[ssz] = '\0';
return open(buf, flags);
}

33
libblkid/src/probe.c

@ -103,6 +103,9 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_LINUX_FD_H
#include <linux/fd.h>
#endif
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
@ -113,6 +116,7 @@
#include "sysfs.h"
#include "strutils.h"
#include "list.h"
#include "fileutils.h"
/*
* All supported chains
@ -907,6 +911,35 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
if (fd < 0)
return 1;
#ifdef FDGETFDCSTAT
{
/*
* Re-open without O_NONBLOCK for floppy device.
*
* Since kernel commit c7e9d0020361f4308a70cdfd6d5335e273eb8717
* floppy drive works bad when opened with O_NONBLOCK.
*/
struct floppy_fdc_state flst;
if (ioctl(fd, FDGETFDCSTAT, &flst) >= 0) {
int flags = fcntl(fd, F_GETFL, 0);
if (flags < 0)
goto err;
if (flags & O_NONBLOCK) {
flags &= ~O_NONBLOCK;
fd = ul_reopen(fd, flags | O_CLOEXEC);
if (fd < 0)
goto err;
pr->flags |= BLKID_FL_PRIVATE_FD;
pr->fd = fd;
}
}
}
#endif
#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
/* Disable read-ahead */
posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);

Loading…
Cancel
Save