mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-20 03:36:50 +00:00
btrfs-progs: open path in non-blocking mode when reading fs id
There's a report that reading properties from a sound device the system is stuck and then gets rebooted by watchdog. Reading from fifo files gets stuck as well, although this would not trigger the watchdog. The reason is that open() on fifo files is blocking until the other end of the pipe is opened. For device nodes it's driver specific, most device nodes fail right away: $ btrfs prop get /dev/tty ERROR: object is not a btrfs object: /dev/tty In case of the sound device the consequences were fatal. We can fix that by opening the path on non-blocking mode. This is only for reading the fsid, the fd is closed right after the ioctl so the non-blocking mode does not affect other operation. The blocking mode must be used for block devices as e.g. loop devices may not be finalized when the open() call returns and get_fsid fails. The known problematic devices are character and fifos. Issue: #699 Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
d185801b45
commit
f240c6114d
@ -22,6 +22,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
@ -337,8 +338,23 @@ int get_fsid(const char *path, u8 *fsid, int silent)
|
||||
{
|
||||
int ret;
|
||||
int fd;
|
||||
int flags = O_RDONLY;
|
||||
struct stat st;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
ret = stat(path, &st);
|
||||
if (ret < 0) {
|
||||
if (!silent)
|
||||
error("failed to stat %s: %m", path);
|
||||
return -errno;
|
||||
}
|
||||
/*
|
||||
* Open in non-blocking mode in case that path is a fifo or a special
|
||||
* character device where opening gets stuck (but is interruptible).
|
||||
*/
|
||||
if ((st.st_mode & S_IFMT) == S_IFCHR || (st.st_mode & S_IFMT) == S_IFIFO)
|
||||
flags |= O_NONBLOCK;
|
||||
|
||||
fd = open(path, flags);
|
||||
if (fd < 0) {
|
||||
if (!silent)
|
||||
error("failed to open %s: %m", path);
|
||||
|
Loading…
Reference in New Issue
Block a user