]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - linux/blkdev.c
New upstream release
[bcachefs-tools-debian] / linux / blkdev.c
index 9b3ea93f8c19aecdaa0a6c9bb3e12eda2def00bf..ea901a462494b97fb220b60897d140a0295da3ce 100644 (file)
@@ -118,6 +118,14 @@ int blkdev_issue_discard(struct block_device *bdev,
        return 0;
 }
 
+int blkdev_issue_zeroout(struct block_device *bdev,
+                        sector_t sector, sector_t nr_sects,
+                        gfp_t gfp_mask, unsigned flags)
+{
+       /* Not yet implemented: */
+       BUG();
+}
+
 unsigned bdev_logical_block_size(struct block_device *bdev)
 {
        struct stat statbuf;
@@ -175,18 +183,34 @@ struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
        else if (mode & FMODE_WRITE)
                flags = O_WRONLY;
 
+       if (!(mode & FMODE_BUFFERED))
+               flags |= O_DIRECT;
+
 #if 0
        /* using O_EXCL doesn't work with opening twice for an O_SYNC fd: */
        if (mode & FMODE_EXCL)
                flags |= O_EXCL;
 #endif
+       buffered_fd = open(path, flags & ~O_DIRECT);
+       if (buffered_fd < 0)
+               return ERR_PTR(-errno);
 
-       fd = open(path, flags|O_DIRECT);
+       fd = open(path, flags);
        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_SYNC);
+       if (sync_fd < 0)
+               sync_fd = open(path, (flags & ~O_DIRECT)|O_SYNC);
+       if (sync_fd < 0) {
+               close(fd);
+               close(buffered_fd);
+               return ERR_PTR(-errno);
+       }
 
        bdev = malloc(sizeof(*bdev));
        memset(bdev, 0, sizeof(*bdev));