[gparted] Calculate unmounted JFS size accurately (!50)
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Calculate unmounted JFS size accurately (!50)
- Date: Thu, 14 Nov 2019 18:37:44 +0000 (UTC)
commit e55d10b91973e8b73c9a55c6c488d2c79c5718ac
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Tue Nov 5 11:32:05 2019 +0000
Calculate unmounted JFS size accurately (!50)
Create the smallest possible JFS (16 MiB) and GParted will report
1.2 MiB of unallocated space. This is because the size of the Aggregate
Disk Map (dmap) was used as the size of the file system. However after
reading the source code to mkfs.jfs, it separately accounts for the size
of the Log (Journal) and the FSCK Working Space. The size of a JFS is
the sum of these 3 components added together.
Using the minimum 16 MiB JFS as an example:
# jfs_debugfs /dev/sdb1
jfs_debugfs version 1.1.15, 04-Mar-2011
Aggregate Block Size: 4096
> superblock
[1] s_magic: 'JFS1' [15] s_ait2.addr1: 0x00
[2] s_version: 1 [16] s_ait2.addr2: 0x00000018
[3] s_size: 0x0000000000007660 s_ait2.address: 24
[4] s_bsize: 4096 [17] s_logdev: 0x00000000
[5] s_l2bsize: 12 [18] s_logserial: 0x00000000
[6] s_l2bfactor: 3 [19] s_logpxd.len: 256
[7] s_pbsize: 512 [20] s_logpxd.addr1: 0x00
[8] s_l2pbsize: 9 [21] s_logpxd.addr2: 0x00000f00
[9] pad: Not Displayed s_logpxd.address: 3840
[10] s_agsize: 0x00002000 [22] s_fsckpxd.len: 52
[11] s_flag: 0x10200900 [23] s_fsckpxd.addr1: 0x00
JFS_LINUX [24] s_fsckpxd.addr2: 0x00000ecc
JFS_COMMIT JFS_GROUPCOMMIT s_fsckpxd.address: 3788
JFS_INLINELOG [25] s_time.tv_sec: 0x5dbbdfa0
[26] s_time.tv_nsec: 0x00000000
[27] s_fpack: 'small_jfs'
[12] s_state: 0x00000000
FM_CLEAN
[13] s_compress: 0
[14] s_ait2.len: 4
display_super: [m]odify or e[x]it: x
> dmap
Block allocation map control page at block 16
[1] dn_mapsize: 0x00000000ecc [9] dn_agheigth: 0
[2] dn_nfree: 0x00000000eaa [10] dn_agwidth: 1
[3] dn_l2nbperpage: 0 [11] dn_agstart: 341
[4] dn_numag: 1 [12] dn_agl2size: 13
[5] dn_maxlevel: 0 [13] dn_agfree: type 'f'
[6] dn_maxag: 0 [14] dn_agsize: 8192
[7] dn_agpref: 0 [15] pad: Not Displayed
[8] dn_aglevel: 0
display_dbmap: [m]odify, [f]ree count, [t]ree, e[x]it > x
> quit
Values of interest:
s_size - Aggregate size in device (s_pbsize) blocks
s_bsize - Aggregate block (aka file system allocation) size in
bytes
s_pbsize - Physical (device) block size in bytes
s_logpxd.len - Log (Journal) size in Aggregate (s_bsize) blocks
s_fsckpxd.len - FSCK Working Space in Aggregate (s_bsize) blocks
dn_nfree - Number of free (s_bsize) blocks in Aggregate
Calculation:
file system size = s_size * s_pbsize
+ s_logpxd.len * s_bsize
+ s_fsckpxd.len * s_bsize
= 30304 * 512
+ 256 * 4096
+ 52 * 4096
= 16777216
(Exactly 16 MiB. The size of the partition.)
free space = dn_nfree * s_bsize
= 3754 * 4096
= 15376384
Rewrite JFS usage querying code to use this updated calculation.
[1] JFS Overview / How the Journaled File System cuts system restart
times to the quick
http://jfs.sourceforge.net/project/pub/jfs.pdf
[2] JFS Layout / How the Journaled File systems handles the on-disk
layout
http://jfs.sourceforge.net/project/pub/jfslayout.pdf
[3] mkfs.jfs source code
http://jfs.sourceforge.net/project/pub/jfsutils-1.1.15.tar.gz
mkfs/mkfs.c
Selected lines from mkfs/mkfs.c
create_aggregate(..., number_of_blocks, ..., logsize, ...)
number_of_blocks -= fsck_wspace_length;
aggr_superblock.s_size = number_of_blocks * (aggr_block_size / phys_block_size);
aggr_superblock.s_bsize = aggr_block_size;
aggr_superblock.s_pbsize = phys_block_size;
PXDlength(&aggr_superblock.s_logpxd, logsize);
PXDlength(&aggr_superblock.s_fsckpxd, fsck_wspace_length);
main()
number_of_bytes = bytes_on_device;
number_of_blocks = number_of_bytes / agg_block_size;
logsize = logsize_in_bytes / aggr_block_size;
number_of_blocks -= logsize;
create_aggregate(..., number_of_blocks, ..., logsize, ...);
Closes !50 - Calculate JFS size accurately
src/jfs.cc | 89 +++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 56 insertions(+), 33 deletions(-)
---
diff --git a/src/jfs.cc b/src/jfs.cc
index 64643d87..309832be 100644
--- a/src/jfs.cc
+++ b/src/jfs.cc
@@ -78,47 +78,70 @@ FS jfs::get_filesystem_support()
return fs ;
}
+
void jfs::set_used_sectors( Partition & partition )
{
- const Glib::ustring jfs_debug_cmd = "jfs_debugfs " + Glib::shell_quote( partition.get_path() );
- if (! Utils::execute_command(jfs_debug_cmd, "dmap\nx\nquit\n", output, error, true))
+ exit_status = Utils::execute_command("jfs_debugfs " + Glib::shell_quote(partition.get_path()),
+ "superblock\nx\ndmap\nx\nquit\n", output, error, true);
+ if (exit_status != 0)
{
- //blocksize
- Glib::ustring::size_type index = output.find( "Block Size:" );
- if ( index >= output .length() ||
- sscanf( output.substr( index ).c_str(), "Block Size: %lld", &S ) != 1 )
- S = -1 ;
-
- //total blocks
- index = output .find( "dn_mapsize:" ) ;
- if ( index >= output .length() ||
- sscanf( output.substr( index ).c_str(), "dn_mapsize: %llx", &T ) != 1 )
- T = -1 ;
-
- //free blocks
- index = output .find( "dn_nfree:" ) ;
- if ( index >= output .length() ||
- sscanf( output.substr( index ).c_str(), "dn_nfree: %llx", &N ) != 1 )
- N = -1 ;
-
- if ( T > -1 && N > -1 && S > -1 )
- {
- T = Utils::round( T * ( S / double(partition .sector_size) ) ) ;
- N = Utils::round( N * ( S / double(partition .sector_size) ) ) ;
- partition .set_sector_usage( T, N ) ;
- partition.fs_block_size = S;
- }
+ if (! output.empty())
+ partition.push_back_message(output);
+ if (! error.empty())
+ partition.push_back_message(error);
+ return;
}
- else
+
+ // s_size - Aggregate size in device (s_pbsize) blocks
+ long long agg_size = -1;
+ Glib::ustring::size_type index = output.find("s_size:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "s_size: %llx", &agg_size);
+
+ // s_bsize - Aggregate block (aka file system allocation) size in bytes
+ long long agg_block_size = -1;
+ index = output.find("s_bsize:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "s_bsize: %lld", &agg_block_size);
+
+ // s_pbsize - Physical (device) block size in bytes
+ long long phys_block_size = -1;
+ index = output.find("s_pbsize:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "s_pbsize: %lld", &phys_block_size);
+
+ // s_logpxd.len - Log (Journal) size in Aggregate (s_bsize) blocks
+ long long log_len = -1;
+ index = output.find("s_logpxd.len:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "s_logpxd.len: %lld", &log_len);
+
+ // s_fsckpxd.len - FSCK Working Space in Aggregate (s_bsize) blocks
+ long long fsck_len = -1;
+ index = output.find("s_fsckpxd.len:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "s_fsckpxd.len: %lld", &fsck_len);
+
+ // dn_nfree - Number of free (s_bsize) blocks in Aggregate
+ long long free_blocks = -1;
+ index = output.find("dn_nfree:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "dn_nfree: %llx", &free_blocks);
+
+ if (agg_size > -1 && agg_block_size > -1 && phys_block_size > -1 &&
+ log_len > -1 && fsck_len > -1 && free_blocks > -1 )
{
- if ( ! output .empty() )
- partition.push_back_message( output );
-
- if ( ! error .empty() )
- partition.push_back_message( error );
+ Sector fs_size_sectors = ( agg_size * phys_block_size
+ + log_len * agg_block_size
+ + fsck_len * agg_block_size) / partition.sector_size;
+ Sector fs_free_sectors = free_blocks * agg_block_size / partition.sector_size;
+
+ partition.set_sector_usage(fs_size_sectors, fs_free_sectors);
+ partition.fs_block_size = agg_block_size;
}
}
+
void jfs::read_label( Partition & partition )
{
if ( ! Utils::execute_command( "jfs_tune -l " + Glib::shell_quote( partition.get_path() ),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]