summaryrefslogtreecommitdiff
path: root/lib/utils_device.c
diff options
context:
space:
mode:
authorKwon <k_c.kwon@samsung.com>2016-05-10 05:13:56 -0700
committerKwon <k_c.kwon@samsung.com>2016-05-10 05:13:56 -0700
commitd0b21614422d7ecd787aeffb894eba1a6973f4fa (patch)
tree07b5f8244b73d0a8840e1f5cac6e51fd4204f852 /lib/utils_device.c
parenta3777a6b2cde2c7133141474dd4c428220a3e9cc (diff)
downloadcryptsetup-d0b21614422d7ecd787aeffb894eba1a6973f4fa.tar.gz
cryptsetup-d0b21614422d7ecd787aeffb894eba1a6973f4fa.tar.bz2
cryptsetup-d0b21614422d7ecd787aeffb894eba1a6973f4fa.zip
Revert "Imported upstream version 1.6.7"
This reverts commit a3777a6b2cde2c7133141474dd4c428220a3e9cc. Change-Id: I5c3c27a5a5677c20afb1a8e69c6ac99785cb37d1
Diffstat (limited to 'lib/utils_device.c')
-rw-r--r--lib/utils_device.c160
1 files changed, 36 insertions, 124 deletions
diff --git a/lib/utils_device.c b/lib/utils_device.c
index 46c2a0f..9b53f1d 100644
--- a/lib/utils_device.c
+++ b/lib/utils_device.c
@@ -1,10 +1,10 @@
/*
* device backend utilities
*
- * Copyright (C) 2004, Jana Saout <jana@saout.de>
+ * Copyright (C) 2004, Christophe Saout <christophe@saout.de>
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2009-2015, Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2015, Milan Broz
+ * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2012, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -38,106 +38,20 @@ struct device {
char *file_path;
int loop_fd;
- int o_direct:1;
int init_done:1;
};
-static int device_block_size_fd(int fd, size_t *min_size)
+static int device_ready(const char *device)
{
+ int devfd, r = 0;
struct stat st;
- int bsize = 0, r = -EINVAL;
-
- if (fstat(fd, &st) < 0)
- return -EINVAL;
-
- if (S_ISREG(st.st_mode))
- r = (int)crypt_getpagesize();
- else if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
- r = bsize;
- else
- r = -EINVAL;
-
- if (r < 0 || !min_size)
- return r;
-
- if (S_ISREG(st.st_mode)) {
- /* file can be empty as well */
- if (st.st_size > bsize)
- *min_size = bsize;
- else
- *min_size = st.st_size;
- } else {
- /* block device must have at least one block */
- *min_size = bsize;
- }
-
- return bsize;
-}
-
-static int device_read_test(int devfd)
-{
- char buffer[512];
- int blocksize, r = -EIO;
- size_t minsize = 0;
-
- blocksize = device_block_size_fd(devfd, &minsize);
-
- if (blocksize < 0)
- return -EINVAL;
-
- if (minsize == 0)
- return 0;
-
- if (minsize > sizeof(buffer))
- minsize = sizeof(buffer);
-
- if (read_blockwise(devfd, blocksize, buffer, minsize) == (ssize_t)minsize)
- r = 0;
-
- crypt_memzero(buffer, sizeof(buffer));
- return r;
-}
-
-/*
- * The direct-io is always preferred. The header is usually mapped to the same
- * device and can be accessed when the rest of device is mapped to data device.
- * Using dirct-io encsures that we do not mess with data in cache.
- * (But proper alignment should prevent this in the first place.)
- * The read test is needed to detect broken configurations (seen with remote
- * block devices) that allow open with direct-io but then fails on read.
- */
-static int device_ready(struct device *device, int check_directio)
-{
- int devfd = -1, r = 0;
- struct stat st;
-
- device->o_direct = 0;
- if (check_directio) {
- log_dbg("Trying to open and read device %s with direct-io.",
- device_path(device));
- devfd = open(device_path(device), O_RDONLY | O_DIRECT);
- if (devfd >= 0) {
- if (device_read_test(devfd) == 0) {
- device->o_direct = 1;
- } else {
- close(devfd);
- devfd = -1;
- }
- }
- }
+ log_dbg("Trying to open and read device %s.", device);
+ devfd = open(device, O_RDONLY);
if (devfd < 0) {
- log_dbg("Trying to open device %s without direct-io.",
- device_path(device));
- devfd = open(device_path(device), O_RDONLY);
- }
-
- if (devfd < 0) {
- log_err(NULL, _("Device %s doesn't exist or access denied.\n"),
- device_path(device));
+ log_err(NULL, _("Device %s doesn't exist or access denied.\n"), device);
return -EINVAL;
}
-
if (fstat(devfd, &st) < 0)
r = -EINVAL;
else if (!S_ISBLK(st.st_mode))
@@ -151,14 +65,12 @@ int device_open(struct device *device, int flags)
{
int devfd;
- flags |= O_SYNC;
- if (device->o_direct)
- flags |= O_DIRECT;
-
- devfd = open(device_path(device), flags);
-
- if (devfd < 0)
- log_dbg("Cannot open device %s.", device_path(device));
+ devfd = open(device_path(device), flags | O_DIRECT | O_SYNC);
+ if (devfd < 0 && errno == EINVAL) {
+ log_dbg("Trying to open device %s without direct-io.",
+ device_path(device));
+ devfd = open(device_path(device), flags | O_SYNC);
+ }
return devfd;
}
@@ -178,24 +90,24 @@ int device_alloc(struct device **device, const char *path)
return -ENOMEM;
memset(dev, 0, sizeof(struct device));
- dev->path = strdup(path);
- if (!dev->path) {
- free(dev);
- return -ENOMEM;
- }
dev->loop_fd = -1;
- r = device_ready(dev, 1);
+ r = device_ready(path);
if (!r) {
dev->init_done = 1;
} else if (r == -ENOTBLK) {
/* alloc loop later */
} else if (r < 0) {
- free(dev->path);
free(dev);
return -ENOTBLK;
}
+ dev->path = strdup(path);
+ if (!dev->path) {
+ free(dev);
+ return -ENOMEM;
+ }
+
*device = dev;
return 0;
}
@@ -296,23 +208,27 @@ out:
int device_block_size(struct device *device)
{
- int fd, r = -EINVAL;
+ struct stat st;
+ int fd, bsize = 0, r = -EINVAL;
if (!device)
return 0;
- if (device->file_path)
- return (int)crypt_getpagesize();
-
fd = open(device->path, O_RDONLY);
if(fd < 0)
return -EINVAL;
- r = device_block_size_fd(fd, NULL);
+ if (fstat(fd, &st) < 0)
+ goto out;
- if (r <= 0)
- log_dbg("Cannot get block size for device %s.", device_path(device));
+ if (S_ISREG(st.st_mode)) {
+ r = (int)crypt_getpagesize();
+ goto out;
+ }
+ if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
+ r = bsize;
+out:
close(fd);
return r;
}
@@ -417,7 +333,7 @@ out:
static int device_internal_prepare(struct crypt_device *cd, struct device *device)
{
- char *loop_device, *file_path = NULL;
+ char *loop_device;
int r, loop_fd, readonly = 0;
if (device->init_done)
@@ -443,19 +359,15 @@ static int device_internal_prepare(struct crypt_device *cd, struct device *devic
return -EINVAL;
}
- file_path = device->path;
- device->path = loop_device;
-
- r = device_ready(device, device->o_direct);
+ r = device_ready(loop_device);
if (r < 0) {
- device->path = file_path;
- crypt_loop_detach(loop_device);
free(loop_device);
return r;
}
device->loop_fd = loop_fd;
- device->file_path = file_path;
+ device->file_path = device->path;
+ device->path = loop_device;
device->init_done = 1;
return 0;