summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-11-19 18:59:55 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2022-11-19 18:59:55 -0500
commit36db254cec55f7fededa8fb038082ac8de7129a6 (patch)
treed6bcb9b334478c7f2e8212d36094f9cc1746f44d
parent7e196f5399706a411c210169d2e73000a4fd605a (diff)
linux/blkdev.c: Fall back to buffered IO when O_DIRECT fails
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--linux/blkdev.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/linux/blkdev.c b/linux/blkdev.c
index 9b3ea93f..54cd6e9c 100644
--- a/linux/blkdev.c
+++ b/linux/blkdev.c
@@ -180,13 +180,26 @@ struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
if (mode & FMODE_EXCL)
flags |= O_EXCL;
#endif
+ buffered_fd = open(path, flags);
+ if (buffered_fd < 0)
+ return ERR_PTR(-errno);
fd = open(path, flags|O_DIRECT);
if (fd < 0)
+ fd = dup(buffered_fd);
+ if (fd < 0) {
+ close(buffered_fd);
return ERR_PTR(-errno);
+ }
- sync_fd = xopen(path, flags|O_DIRECT|O_SYNC);
- buffered_fd = xopen(path, flags);
+ sync_fd = open(path, flags|O_DIRECT|O_SYNC);
+ if (sync_fd < 0)
+ sync_fd = open(path, flags|O_SYNC);
+ if (sync_fd < 0) {
+ close(fd);
+ close(buffered_fd);
+ return ERR_PTR(-errno);
+ }
bdev = malloc(sizeof(*bdev));
memset(bdev, 0, sizeof(*bdev));