diff options
author | Kwon <k_c.kwon@samsung.com> | 2016-05-10 05:13:56 -0700 |
---|---|---|
committer | Kwon <k_c.kwon@samsung.com> | 2016-05-10 05:13:56 -0700 |
commit | d0b21614422d7ecd787aeffb894eba1a6973f4fa (patch) | |
tree | 07b5f8244b73d0a8840e1f5cac6e51fd4204f852 /lib/utils_device.c | |
parent | a3777a6b2cde2c7133141474dd4c428220a3e9cc (diff) | |
download | cryptsetup-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.c | 160 |
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; |