gparted/include/Partition.h

187 lines
7.1 KiB
C
Raw Normal View History

/* Copyright (C) 2004 Bart
* Copyright (C) 2008, 2009, 2010 Curtis Gedak
2004-09-19 14:24:53 -06:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
2004-09-19 14:24:53 -06:00
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
2004-09-19 14:24:53 -06:00
*/
/* READ THIS!!
2004-10-02 13:30:20 -06:00
* Partition isn't really a partition. It's more like a geometry, a continuous part of the disk.
* I use it to represent partitions as well as unallocated spaces
2004-09-19 14:24:53 -06:00
*/
#ifndef GPARTED_PARTITION_H
#define GPARTED_PARTITION_H
2004-09-19 14:24:53 -06:00
2004-10-06 09:32:40 -06:00
#include "../include/Utils.h"
#include "../include/PartitionVector.h"
2004-09-20 09:46:21 -06:00
#include <glibmm/ustring.h>
2004-09-19 14:24:53 -06:00
namespace GParted
{
2004-09-19 14:24:53 -06:00
enum PartitionType {
TYPE_PRIMARY = 0,
TYPE_LOGICAL = 1,
TYPE_EXTENDED = 2,
TYPE_UNALLOCATED = 3
2004-09-19 14:24:53 -06:00
};
2004-09-25 08:12:07 -06:00
enum PartitionStatus {
STAT_REAL = 0,
STAT_NEW = 1,
STAT_COPY = 2,
STAT_FORMATTED = 3
2004-09-25 08:12:07 -06:00
};
enum PartitionAlignment {
ALIGN_CYLINDER = 0, //Align to nearest cylinder
ALIGN_MEBIBYTE = 1, //Align to nearest mebibyte
ALIGN_STRICT = 2 //Strict alignment - no rounding
// Indicator if start and end sectors must remain unchanged
};
class Partition; // Forward declarations as Partition and PartitionVector are
class PartitionVector; // mutually recursive classes.
// References:
// * Mutually recursive classes
// http://stackoverflow.com/questions/3410637/mutually-recursive-classes
// * recursive definition in CPP
// http://stackoverflow.com/questions/4300420/recursive-definition-in-cpp
2004-09-19 14:24:53 -06:00
class Partition
{
public:
Partition() ;
virtual ~Partition();
virtual Partition * clone() const;
void Reset() ;
2004-09-19 14:24:53 -06:00
//simple Set-functions. only for convenience, since most members are public
void Set( const Glib::ustring & device_path,
const Glib::ustring & partition,
int partition_number,
PartitionType type,
bool whole_device,
FILESYSTEM filesystem,
Sector sector_start,
Sector sector_end,
Byte_Value sector_size,
bool inside_extended,
bool busy );
2004-09-19 14:24:53 -06:00
Record unallocated space within a partition (#499202) Currently GParted assumes that a file system fills its containing partition. This is not always true and can occur when resizing is performed outside of GParted or a resize operation fails. GParted doesn't display any information about unallocated space to the user and in most cases it is simply included in used space. Add partition unallocated space accounting. Make GParted record the unallocated space for mounted file system and display a warning in the Partition Information dialog when too much unallocated space is found. Partition::set_sector_usage( fs_size, fs_unused ), is the new preferred method of recording file system usage because it allows the unallocated space in a partition to be calculated. Partition::Set_Unused() and Partition::set_used() are now deprecated. NOTES: 1) Set the minimum unallocated space to be 5% before considering it significant to avoid false reporting. Worst case found was a mounted xfs file system in a 100MiB partition, which reports as ~4.7% unallocated according to file system size from statvfs(). However, it reports as having no unallocated space using xfs specific tools. 2) Unallocated space is only a graphical representation for the user. GParted must still use relevant tools to resize file systems before shrinking the data and can't assume all unallocated space exists after the file system at the end of the partition. Bug #499202 - gparted does not see the difference if partition size differs from filesystem size
2012-01-10 07:13:41 -07:00
void set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unused ) ;
virtual bool sector_usage_known() const;
virtual Sector estimated_min_size() const;
virtual Sector get_sectors_used() const;
virtual Sector get_sectors_unused() const;
virtual Sector get_sectors_unallocated() const;
void get_usage_triple( int imax, int & i1, int & i2, int & i3 ) const ;
void Set_Unallocated( const Glib::ustring & device_path,
bool whole_device,
Sector sector_start,
Sector sector_end,
Byte_Value sector_size,
bool inside_extended );
2004-09-19 14:24:53 -06:00
//update partition number (used when a logical partition is deleted)
void Update_Number( int new_number );
void add_path( const Glib::ustring & path, bool clear_paths = false ) ;
void add_paths( const std::vector<Glib::ustring> & paths, bool clear_paths = false ) ;
2010-04-27 11:28:36 -06:00
Byte_Value get_byte_length() const ;
Sector get_sector_length() const ;
Glib::ustring get_path() const ;
std::vector<Glib::ustring> get_paths() const ;
void add_mountpoint( const Glib::ustring & mountpoint, bool clear_mountpoints = false ) ;
void add_mountpoints( const std::vector<Glib::ustring> & mountpoints, bool clear_mountpoints = false ) ;
Glib::ustring get_mountpoint() const ;
void clear_mountpoints() ;
std::vector<Glib::ustring> get_mountpoints() const ;
Sector get_sector() const ;
bool test_overlap( const Partition & partition ) const ;
bool filesystem_label_known() const;
virtual Glib::ustring get_filesystem_label() const;
void set_filesystem_label( const Glib::ustring & filesystem_label );
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
// Message accessors. Messages are stored locally and accessed globally.
// Stored locally means the messages are stored in the Partition object to which
// they are added so push_back_messages() and append_messages() are non-virtual.
// Accessed globally means that in the case of derived objects which are composed
// of more that one Partition object, i.e. PartitionLUKS, the messages have to be
// accessible from all copies within the derived object hierarchy. Hence
// have_messages(), get_messages() and clear_messages() are virtual to allow for
// overridden implementations.
virtual bool have_messages() const { return ! messages.empty(); };
virtual std::vector<Glib::ustring> get_messages() const { return messages; };
virtual void clear_messages() { messages.clear(); };
void push_back_message( Glib::ustring msg ) { messages.push_back( msg ); };
void append_messages( const std::vector<Glib::ustring> msgs )
{ messages.insert( messages.end(), msgs.begin(), msgs.end() ); }
bool operator==( const Partition & partition ) const ;
bool operator!=( const Partition & partition ) const ;
2004-09-19 14:24:53 -06:00
//some public members
Glib::ustring device_path ;
2004-09-19 14:24:53 -06:00
int partition_number;
PartitionType type;// UNALLOCATED, PRIMARY, LOGICAL, etc...
bool whole_device; // Is this a virtual partition spanning a whole unpartitioned disk device?
2004-09-25 08:12:07 -06:00
PartitionStatus status; //STAT_REAL, STAT_NEW, etc..
PartitionAlignment alignment; //ALIGN_CYLINDER, ALIGN_STRICT, etc
FILESYSTEM filesystem ;
Glib::ustring uuid ;
Glib::ustring name;
2004-09-19 14:24:53 -06:00
Sector sector_start;
Sector sector_end;
Sector sectors_used;
Sector sectors_unused;
Record unallocated space within a partition (#499202) Currently GParted assumes that a file system fills its containing partition. This is not always true and can occur when resizing is performed outside of GParted or a resize operation fails. GParted doesn't display any information about unallocated space to the user and in most cases it is simply included in used space. Add partition unallocated space accounting. Make GParted record the unallocated space for mounted file system and display a warning in the Partition Information dialog when too much unallocated space is found. Partition::set_sector_usage( fs_size, fs_unused ), is the new preferred method of recording file system usage because it allows the unallocated space in a partition to be calculated. Partition::Set_Unused() and Partition::set_used() are now deprecated. NOTES: 1) Set the minimum unallocated space to be 5% before considering it significant to avoid false reporting. Worst case found was a mounted xfs file system in a 100MiB partition, which reports as ~4.7% unallocated according to file system size from statvfs(). However, it reports as having no unallocated space using xfs specific tools. 2) Unallocated space is only a graphical representation for the user. GParted must still use relevant tools to resize file systems before shrinking the data and can't assume all unallocated space exists after the file system at the end of the partition. Bug #499202 - gparted does not see the difference if partition size differs from filesystem size
2012-01-10 07:13:41 -07:00
Sector sectors_unallocated; //Difference between the size of the partition and the file system
Sector significant_threshold; //Threshold from intrinsic to significant unallocated sectors
bool inside_extended;
2004-09-19 14:24:53 -06:00
bool busy;
std::vector<Glib::ustring> flags ;
PartitionVector logicals;
bool strict_start ; //Indicator if start sector must stay unchanged
Sector free_space_before ; //Free space preceding partition value
Byte_Value sector_size ; //Sector size of the disk device needed for converting to/from sectors and bytes.
Byte_Value fs_block_size; // Block size of of the file system, or -1 when unknown.
2004-09-19 14:24:53 -06:00
private:
Partition & operator=( Partition & rhs ); // Not implemented copy assignment operator
static void get_usage_triple_helper( Sector stot, Sector s1, Sector s2, Sector s3, int imax, int & i1, int & i2, int & i3 ) ;
Fix minor unallocated space display issue in the Info dialog (#499202) For specific partition usage values the right hand border of the partition graphic in the Information dialog would be displayed as grey rather than the color assigned to the partition. Steps to reproduce fault: Create 1024 MiB partition # lvm pvcreate /dev/sda12 # lvm vgcreate GParted-VG1 /dev/sda12 View partition information Fragment from Dialog_Partition_Info::init_drawingarea(): 139 else if ( partition .sector_usage_known() ) 140 { 141 used = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_used() ) ) ; 142 unused = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_unused() ) ) ; 143 unallocated = 400 - BORDER *2 - used - unused ; 144 } For this issue the above values are both exactly x.5 and both round upwards, resulting in unallocated being -1. used = round((400 - 8*2)/(2097152.0/8192)) = round(1.5) unused = round((400 - 8*2)/(2097152.0/2088960)) = round(382.5) unallocated = 400 - 8*2 - 2 - 383 = -1 The simple fix would be to use floor() instead of round() in the calculation of either used or unused. The same fix would also need to be applied in Display_Info() for the calculation of the percentage figures. Unfortunately this simple fix can lead to odd figures when the used or unused is close to zero and floor() or ceil() is effectively applied rather than round(). For example: Size: 227.23 GiB Used: 28.00 KiB ( 1% ) Unused: 180.00 GiB ( 79% ) Unallocated: 47.23 GiB ( 20% ) Used figure of 28 KiB in 227 GiB partition should be rounded to 0% but wasn't. Write Partition::calc_usage_triple() which calculates the "best" figures by rounding the smaller two figures and subtracts them from the desired total for the largest figure. Apply to the calculation of the partition usage percentage figures in the Information dialog and the partition usage graphic in the same dialog and the main window. Bug #499202 - gparted does not see the difference if partition size differs from filesystem size
2012-06-20 16:53:05 -06:00
void sort_paths_and_remove_duplicates() ;
Sector calc_significant_unallocated_sectors() const ;
2004-09-19 14:24:53 -06:00
static bool compare_paths( const Glib::ustring & A, const Glib::ustring & B ) ;
std::vector<Glib::ustring> paths ;
std::vector<Glib::ustring> mountpoints ;
bool have_filesystem_label;
Glib::ustring filesystem_label;
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
std::vector<Glib::ustring> messages;
2004-09-19 14:24:53 -06:00
};
}//GParted
#endif /* GPARTED_PARTITION_H */