crypt_deactivate: fail earlier when holders detected

crypt_deactivate_* fail earlier without noisy dm retries
when other device holders detected. The early detection
works if:

a) other device-mapper device has a hold reference on the
   device

- or -

b) mounted fs is detected on the device

Any deactivation flag CRYPT_DEACTIVATE_FORCE or
CRYPT_DEACTIVATE_DEFERRED will disable this detection
This commit is contained in:
Ondrej Kozina
2017-10-16 16:41:43 +02:00
parent f901cb7b25
commit 961e65424e
4 changed files with 33 additions and 11 deletions

View File

@@ -3217,6 +3217,7 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
const char *namei = NULL;
struct crypt_dm_active_device dmd = {};
int r;
uint32_t get_flags = DM_ACTIVE_DEVICE | DM_ACTIVE_HOLDERS;
if (!name)
return -EINVAL;
@@ -3230,17 +3231,26 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
cd = fake_cd;
}
/* skip holders detection and early abort when some flags raised */
if (flags & (CRYPT_DEACTIVATE_FORCE | CRYPT_DEACTIVATE_DEFERRED))
get_flags &= ~DM_ACTIVE_HOLDERS;
switch (crypt_status(cd, name)) {
case CRYPT_ACTIVE:
case CRYPT_BUSY:
key_desc = crypt_get_device_key_description(name);
if (crypt_get_integrity_tag_size(cd)) {
r = dm_query_device(cd, name, DM_ACTIVE_DEVICE, &dmd);
if (r >= 0)
r = dm_query_device(cd, name, get_flags, &dmd);
if (r >= 0) {
if (dmd.holders) {
log_err(cd, _("Device %s is still in use.\n"), name);
r = -EBUSY;
break;
}
if (crypt_get_integrity_tag_size(cd))
namei = device_dm_name(dmd.data_device);
}
key_desc = crypt_get_device_key_description(name);
if (isTCRYPT(cd->type))
r = TCRYPT_deactivate(cd, name, flags);
else