Use BlockSpecial in LUKS_Info module cache (#767842)

The LUKS_Info module cache is loaded from "dmsetup" command and compares
block special files, therefore switch to using BlockSpecial objects so
that comparisons are performed by major, minor device number.

Bug 767842 - File system usage missing when tools report alternate block
             device names
This commit is contained in:
Mike Fleetwood 2016-07-04 09:12:51 +01:00 committed by Curtis Gedak
parent e4a8530b14
commit 7cd574cac5
2 changed files with 18 additions and 34 deletions

View File

@ -25,6 +25,7 @@
#ifndef GPARTED_LUKS_INFO_H
#define GPARTED_LUKS_INFO_H
#include "../include/BlockSpecial.h"
#include "../include/Utils.h"
#include <glibmm/ustring.h>
@ -36,9 +37,7 @@ namespace GParted
struct LUKS_Mapping
{
Glib::ustring name; // Name of the dm-crypt mapping
unsigned long major; // Major device number of the underlying block device
unsigned long minor; // Minor device number of the underlying block device
Glib::ustring path; // Path of the underlying block device
BlockSpecial container; // Underlying block device containing the LUKS mapping
Byte_Value offset; // Offset to the start of the mapping in the underlying block device
Byte_Value length; // Length of the mapping in the underlying block device
};

View File

@ -15,6 +15,7 @@
*/
#include "../include/LUKS_Info.h"
#include "../include/BlockSpecial.h"
#include "../include/Utils.h"
#include <stdio.h>
@ -97,18 +98,16 @@ void LUKS_Info::load_cache()
// Extract LUKS underlying device containing the encrypted data. May be
// either a device name (/dev/sda1) or major, minor pair (8:1).
luks_map.major = 0UL;
luks_map.minor = 0UL;
luks_map.path.clear();
luks_map.container = BlockSpecial();
Glib::ustring devpath = fields[DMCRYPT_FIELD_devpath];
unsigned long maj = 0UL;
unsigned long min = 0UL;
if ( devpath.length() > 0 && devpath[0] == '/' )
luks_map.path = devpath;
luks_map.container = BlockSpecial( devpath );
else if ( sscanf( devpath.c_str(), "%lu:%lu", &maj, &min ) == 2 )
{
luks_map.major = maj;
luks_map.minor = min;
luks_map.container.m_major = maj;
luks_map.container.m_minor = min;
}
else
continue;
@ -135,35 +134,21 @@ void LUKS_Info::load_cache()
// or not found substitute when no entry exists.
const LUKS_Mapping & LUKS_Info::get_cache_entry_internal( const Glib::ustring & path )
{
// First scan the cache looking for an underlying block device path match.
// (Totally in memory)
BlockSpecial bs = BlockSpecial( path );
for ( unsigned int i = 0 ; i < luks_mapping_cache.size() ; i ++ )
{
if ( path == luks_mapping_cache[i].path )
return luks_mapping_cache[i];
}
// Second scan the cache looking for an underlying block device major, minor
// match. (Requires single stat(2) call per search)
struct stat sb;
if ( stat( path.c_str(), &sb ) == 0 && S_ISBLK( sb.st_mode ) )
if ( bs == luks_mapping_cache[i].container )
{
unsigned long maj = major( sb.st_rdev );
unsigned long min = minor( sb.st_rdev );
for ( unsigned int i = 0 ; i < luks_mapping_cache.size() ; i ++ )
{
if ( maj == luks_mapping_cache[i].major && min == luks_mapping_cache[i].minor )
{
// Store path in cache to avoid stat() call on subsequent
// query for the same path.
luks_mapping_cache[i].path = path;
// Store underlying block device path in the BlockSpecial object
// if not already known. Not required, just for completeness.
if ( ! luks_mapping_cache[i].container.m_name.length() )
luks_mapping_cache[i].container.m_name = path;
return luks_mapping_cache[i];
}
}
}
static LUKS_Mapping not_found = {"", 0UL, 0UL, "", -1LL, -1LL};
static LUKS_Mapping not_found = {"", BlockSpecial(), -1LL, -1LL};
return not_found;
}