mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-11 19:00:02 +01:00
Adapt device_open_excl to reusing of fds.
This commit is contained in:
committed by
Milan Broz
parent
83c227d53c
commit
2d0079905e
@@ -123,6 +123,7 @@ int device_read_ahead(struct device *device, uint32_t *read_ahead);
|
||||
int device_size(struct device *device, uint64_t *size);
|
||||
int device_open(struct crypt_device *cd, struct device *device, int flags);
|
||||
int device_open_excl(struct crypt_device *cd, struct device *device, int flags);
|
||||
void device_release_excl(struct crypt_device *cd, struct device *device);
|
||||
void device_disable_direct_io(struct device *device);
|
||||
int device_is_identical(struct device *device1, struct device *device2);
|
||||
int device_is_rotational(struct device *device);
|
||||
|
||||
@@ -2304,11 +2304,12 @@ static int _reencrypt_init(struct crypt_device *cd,
|
||||
log_err(cd, _("Data shift (%" PRIu64 " sectors) is less than future data offset (%" PRIu64 " sectors)."), params->data_shift, LUKS2_get_data_offset(hdr));
|
||||
return -EINVAL;
|
||||
}
|
||||
/* FIXME: This is broken with current commit. Will get fixed with next one */
|
||||
devfd = device_open_excl(cd, crypt_data_device(cd), O_RDWR);
|
||||
if (devfd < 0) {
|
||||
log_err(cd, _("Failed to open %s in exclusive mode (perhaps already mapped or mounted)."),
|
||||
device_path(crypt_data_device(cd)));
|
||||
if (devfd == -EBUSY)
|
||||
log_err(cd,_("Failed to open %s in exclusive mode (already mapped or mounted)."), device_path(crypt_data_device(cd)));
|
||||
else
|
||||
log_err(cd,_("Failed to open %s in exclusive mode."), device_path(crypt_data_device(cd)));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -2348,6 +2349,7 @@ static int _reencrypt_init(struct crypt_device *cd,
|
||||
} else
|
||||
r = reencrypt_keyslot;
|
||||
err:
|
||||
device_release_excl(cd, crypt_data_device(cd));
|
||||
if (r < 0)
|
||||
crypt_load(cd, CRYPT_LUKS2, NULL);
|
||||
|
||||
@@ -2973,7 +2975,7 @@ static int _reencrypt_free(struct crypt_device *cd, struct luks2_hdr *hdr, struc
|
||||
int crypt_reencrypt(struct crypt_device *cd,
|
||||
int (*progress)(uint64_t size, uint64_t offset, void *usrptr))
|
||||
{
|
||||
int r, excl_devfd = -1;
|
||||
int r;
|
||||
crypt_reencrypt_info ri;
|
||||
struct luks2_hdr *hdr;
|
||||
struct luks2_reenc_context *rh;
|
||||
@@ -3008,10 +3010,8 @@ int crypt_reencrypt(struct crypt_device *cd,
|
||||
} else {
|
||||
if (crypt_storage_wrapper_get_type(rh->cw1) != DMCRYPT &&
|
||||
crypt_storage_wrapper_get_type(rh->cw2) != DMCRYPT) {
|
||||
/* FIXME: This is broken with current commit. Will get fixed with next one */
|
||||
excl_devfd = device_open_excl(cd, crypt_data_device(cd), O_RDONLY);
|
||||
if (excl_devfd < 0) {
|
||||
log_err(cd, _("Failed to open device %s in exclusive mode. Already mounted?."), device_path(crypt_data_device(cd)));
|
||||
if (device_open_excl(cd, crypt_data_device(cd), O_RDONLY) < 0) {
|
||||
log_err(cd,_("Failed to open %s in exclusive mode (already mapped or mounted)."), device_path(crypt_data_device(cd)));
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
@@ -3044,6 +3044,7 @@ int crypt_reencrypt(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
r = _reencrypt_free(cd, hdr, rh, rs, progress);
|
||||
device_release_excl(cd, crypt_data_device(cd));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ struct device {
|
||||
|
||||
int ro_dev_fd;
|
||||
int dev_fd;
|
||||
int dev_fd_excl;
|
||||
|
||||
struct crypt_lock_handle *lh;
|
||||
|
||||
@@ -306,17 +307,44 @@ int device_open(struct crypt_device *cd, struct device *device, int flags)
|
||||
|
||||
int device_open_excl(struct crypt_device *cd, struct device *device, int flags)
|
||||
{
|
||||
const char *path;
|
||||
struct stat st;
|
||||
|
||||
if (stat(device_path(device), &st))
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
if (S_ISBLK(st.st_mode))
|
||||
flags |= O_EXCL;
|
||||
|
||||
assert(!device_locked(device->lh));
|
||||
|
||||
if (device->dev_fd_excl < 0) {
|
||||
path = device_path(device);
|
||||
if (stat(path, &st))
|
||||
return -EINVAL;
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
log_dbg(cd, "%s is not a block device. Can't open in exclusive mode.",
|
||||
path);
|
||||
else {
|
||||
device->dev_fd_excl = open(path, O_RDONLY | O_EXCL);
|
||||
if (device->dev_fd_excl < 0)
|
||||
return errno == EBUSY ? -EBUSY : device->dev_fd_excl;
|
||||
log_dbg(cd, "Device %s is blocked for exclusive open.", path);
|
||||
}
|
||||
}
|
||||
|
||||
return device_open_internal(cd, device, flags);
|
||||
}
|
||||
|
||||
void device_release_excl(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
if (device && device->dev_fd_excl >= 0) {
|
||||
if (close(device->dev_fd_excl))
|
||||
log_dbg(cd, "Failed to release exclusive handle on device %s.",
|
||||
device_path(device));
|
||||
else
|
||||
log_dbg(cd, "Closed exclusive fd for %s.", device_path(device));
|
||||
device->dev_fd_excl = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int device_open_locked(struct crypt_device *cd, struct device *device, int flags)
|
||||
{
|
||||
assert(!crypt_metadata_locking_enabled() || device_locked(device->lh));
|
||||
@@ -346,6 +374,7 @@ int device_alloc_no_check(struct device **device, const char *path)
|
||||
dev->loop_fd = -1;
|
||||
dev->ro_dev_fd = -1;
|
||||
dev->dev_fd = -1;
|
||||
dev->dev_fd_excl = -1;
|
||||
dev->o_direct = 1;
|
||||
|
||||
*device = dev;
|
||||
@@ -393,6 +422,11 @@ void device_free(struct crypt_device *cd, struct device *device)
|
||||
close(device->dev_fd);
|
||||
}
|
||||
|
||||
if (device->dev_fd_excl != -1) {
|
||||
log_dbg(cd, "Closed exclusive fd for %s.", device_path(device));
|
||||
close(device->dev_fd_excl);
|
||||
}
|
||||
|
||||
if (device->loop_fd != -1) {
|
||||
log_dbg(cd, "Closed loop %s (%s).", device->path, device->file_path);
|
||||
close(device->loop_fd);
|
||||
|
||||
Reference in New Issue
Block a user