Allow to open device without read check.

In some specific situation we do not want to read the devices
before initialization.

Here it is integrity checking that will produce warning, because
the device is not yet initialized.

Used only in wipe function (here we must use direct-io anyway)
and expect the device is capable of direct-io.
This commit is contained in:
Milan Broz
2017-07-27 12:56:07 +02:00
parent 5824e8d242
commit 12040570ca
3 changed files with 23 additions and 8 deletions

View File

@@ -65,6 +65,7 @@ void crypt_free_volume_key(struct volume_key *vk);
/* Device backend */ /* Device backend */
struct device; struct device;
int device_alloc(struct device **device, const char *path); int device_alloc(struct device **device, const char *path);
int device_alloc_no_check(struct device **device, const char *path);
void device_free(struct device *device); void device_free(struct device *device);
const char *device_path(const struct device *device); const char *device_path(const struct device *device);
const char *device_block_path(const struct device *device); const char *device_block_path(const struct device *device);

View File

@@ -143,16 +143,16 @@ static int device_read_test(int devfd)
* The read test is needed to detect broken configurations (seen with remote * 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. * block devices) that allow open with direct-io but then fails on read.
*/ */
static int device_ready(struct device *device, int check_directio) static int device_ready(struct device *device)
{ {
int devfd = -1, r = 0; int devfd = -1, r = 0;
struct stat st; struct stat st;
size_t tmp_size; size_t tmp_size;
device->o_direct = 0; if (device->o_direct) {
if (check_directio) {
log_dbg("Trying to open and read device %s with direct-io.", log_dbg("Trying to open and read device %s with direct-io.",
device_path(device)); device_path(device));
device->o_direct = 0;
devfd = open(device_path(device), O_RDONLY | O_DIRECT); devfd = open(device_path(device), O_RDONLY | O_DIRECT);
if (devfd >= 0) { if (devfd >= 0) {
if (device_read_test(devfd) == 0) { if (device_read_test(devfd) == 0) {
@@ -210,10 +210,10 @@ int device_open(struct device *device, int flags)
return devfd; return devfd;
} }
int device_alloc(struct device **device, const char *path) /* Avoid any read from device, expects direct-io to work. */
int device_alloc_no_check(struct device **device, const char *path)
{ {
struct device *dev; struct device *dev;
int r;
if (!path) { if (!path) {
*device = NULL; *device = NULL;
@@ -231,8 +231,22 @@ int device_alloc(struct device **device, const char *path)
return -ENOMEM; return -ENOMEM;
} }
dev->loop_fd = -1; dev->loop_fd = -1;
dev->o_direct = 1;
r = device_ready(dev, 1); *device = dev;
return 0;
}
int device_alloc(struct device **device, const char *path)
{
struct device *dev;
int r;
r = device_alloc_no_check(&dev, path);
if (r < 0)
return r;
r = device_ready(dev);
if (!r) { if (!r) {
dev->init_done = 1; dev->init_done = 1;
} else if (r == -ENOTBLK) { } else if (r == -ENOTBLK) {
@@ -529,7 +543,7 @@ static int device_internal_prepare(struct crypt_device *cd, struct device *devic
file_path = device->path; file_path = device->path;
device->path = loop_device; device->path = loop_device;
r = device_ready(device, device->o_direct); r = device_ready(device);
if (r < 0) { if (r < 0) {
device->path = file_path; device->path = file_path;
crypt_loop_detach(loop_device); crypt_loop_detach(loop_device);

View File

@@ -239,7 +239,7 @@ int crypt_wipe(struct crypt_device *cd,
if (!dev_path) if (!dev_path)
device = crypt_data_device(cd); device = crypt_data_device(cd);
else { else {
r = device_alloc(&device, dev_path); r = device_alloc_no_check(&device, dev_path);
if (r < 0) if (r < 0)
return r; return r;