gparted/include/fat16.h

53 lines
1.8 KiB
C
Raw Normal View History

/* Copyright (C) 2004 Bart
* Copyright (C) 2008, 2009, 2010 Curtis Gedak
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPARTED_FAT16_H
#define GPARTED_FAT16_H
#include "FileSystem.h"
#include "Partition.h"
namespace GParted
{
class fat16 : public FileSystem
{
const enum FSType specific_type;
Glib::ustring create_cmd ;
Glib::ustring check_cmd ;
public:
fat16( enum FSType type ) : specific_type( type ), create_cmd( "" ), check_cmd( "" ) {};
const Glib::ustring & get_custom_text( CUSTOM_TEXT ttype, int index = 0 ) const;
FS get_filesystem_support() ;
void set_used_sectors( Partition & partition ) ;
void read_label( Partition & partition ) ;
bool write_label( const Partition & partition, OperationDetail & operationdetail ) ;
void read_uuid( Partition & partition ) ;
bool write_uuid( const Partition & partition, OperationDetail & operationdetail ) ;
bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
bool check_repair( const Partition & partition, OperationDetail & operationdetail ) ;
private:
const Glib::ustring sanitize_label( const Glib::ustring & label ) const;
Switch to faster minfo and mdir to read FAT16/32 usage (#569921) A user reported that GParted was slow to refresh on FAT32 file systems: "can take very long, up to several minutes; can be reproduced by running dosfsck manually". This is because the file system was large and almost full, and GParted performs a file system check just to to report the file system usage. Created a 4 GiB FAT32 file system and almost filled it with 4 KiB files, just over 970,000 files. # df -k /mnt/2 Filesystem 1K-blocks Used Available Used% Mounted on /dev/sdb2 4186108 39155384 270724 94% /mnt/2 # df -i /mnt/2 Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sdb2 0 0 0 - /mnt/2 # find /mnt/2 -type f -print | wc -l 971059 # find /mnt/2 -type d -print | wc -l 1949 Testing performance of the current fsck.fat: # time fsck.fat -n -v /dev/sdb2 | \ > egrep 'bytes per logical sector|bytes per cluster|sectors total|clusters$' 512 bytes per logical sector 4096 bytes per cluster 8388608 sectors total /dev/sdb2: 973008 files, 978846/1046527 clusters real 0m11.552s user 0m2.183s sys 0m7.547s Free sectors in the file system according to fsck.fat: (1046527 - 978846) * 4096 / 512 = 541448 sectors Repeating this test while also using 'blktrace /dev/sdb2' and Ctrl-C around the test in a separate terminal, reports these numbers of I/Os being performed: Read requests Read bytes 15,563 165 MiB Prior to this commit [1] from 0.0.9, GParted used libparted's ped_file_system_get_resize_constraint() to report the minimum size to which a FAT* file system can be resized. Use this test program [2] to performance test this method: # time ./fscons /dev/sdb2 dev=/dev/sdb2 sector_size=512 min_size=7909522 max_size=8388608 real 0m2.673s user 0m0.070s sys 0m1.834s Free sectors in the file system according to libparted ped_file_system_get_resize_constraint(): 8388608 - 7909522 = 479086 sectors blktrace reports these numbers of I/Os being performed: Read requests Read bytes 7,821 71 MiB So using libparted resize constraint is a bit faster but is still reading too much data and is really too slow. Also when testing GParted using this libparted method against a corrupted FAT32 file system, on every refresh, one popup dialog is displayed for each error libparted detects with the file system, each of which needs acknowledgement. Example popup: Libparted Error \DIRNAME\FILENAME.EXT is 107724k, but is has 1920 clusters (122880k). [ Cancel ][ Ignore ] There could be a huge number of such errors in a corrupted file system. Not really suitable for use by GParted. Test the performance of mtools' minfo command to report the file system figures: # time minfo -i /dev/sdb2 :: | \ > egrep 'sector size:|cluster size:|small size:|big size:|free clusters=' sector size: 512 bytes cluster size: 8 sectors small size: 0 sectors big size: 8388608 sectors free clusters=67681 real 0m0.013s user 0m0.004s sys 0m0.019s Free sectors in the file system according to minfo: 67681 * 8 = 541448 sectors blktrace reports these numbers of I/Os being performed by minfo: Read requests Read bytes 1 16 KiB This matches with minfo just reading information from the BPB (BIOS Parameter Block) [3] from sector 0 and the FS Information Sector [4] usually in sector 1. Note that the free cluster figure reported by minfo comes from the FS Information Sector because it only reports it for FAT32 file systems, not for FAT16 file systems. Scanning the File Allocation Table (FAT) [5] to count free clusters is exactly what mdir, without the '-f' (fast) flag, does. Test the performance of mdir: # export MTOOLS_SKIP_CHECK=1 # time mdir -i /dev/sdb2 ::/ | fgrep 'bytes free' 277 221 376 bytes free real 0m0.023s user 0m0.011s sys 0m0.023s Free sectors in the file system according to mdir: 277221376 / 512 = 541448 sectors blktrace reports these number of I/Os being performed by mdir: Read requests Read bytes 5 448 KiB So minfo and mdir together provide the needed information and are 2 to 3 orders of magnitude faster because they only read the needed BPB and FAT data from the drive. Use these together to read the file system usage. [1] 61cd0ce77879e4af84280ddcf77959ae55885ba4 lots of stuff and cleanups, including fixing getting used/unused space of hfs/hfs+/fat16/fat32 [2] fscons.c /* FILE: fscons.c * SYNOPSIS: Report libparted's FS resize limits. * BUILD: gcc -o fscons fscons.c -lparted -lparted-fs-resize */ int main(int argc, const char *argv[]) { PedDevice* dev = NULL; PedDisk* tab = NULL; PedPartition* ptn = NULL; PedFileSystem* fs = NULL; PedConstraint* cons = NULL; if (argc != 2) { fprintf(stderr, "Usage: fscons BLOCKDEV\n"); exit(1); } dev = ped_device_get(argv[1]); if (dev == NULL) { fprintf(stderr, "ped_device_get(\"%s\") failed\n", argv[1]); exit(1); } printf("dev=%s\n", dev->path); printf("sector_size=%ld\n", dev->sector_size); tab = ped_disk_new(dev); if (tab == NULL) { fprintf(stderr, "ped_disk_new(dev) failed\n"); exit(1); } ptn = ped_disk_get_partition_by_sector(tab, 0); if (ptn == NULL) { fprintf(stderr, "ped_disk_get_partition(tab, 0) failed\n"); exit(1); } fs = ped_file_system_open(&ptn->geom); if (fs == NULL) { fprintf(stderr, "ped_file_system_open(&ptn->geom) failed\n"); exit(1); } cons = ped_file_system_get_resize_constraint(fs); if (cons == NULL) { fprintf(stderr, "ped_file_system_get_resize_constraint(fs) failed\n"); exit(1); } printf("min_size=%ld\n", cons->min_size); printf("max_size=%ld\n", cons->max_size); ped_constraint_destroy(cons); ped_file_system_close(fs); ped_disk_destroy(tab); ped_device_destroy(dev); return 0; } [3] Design of the FAT file system, BIOS Parameter Block https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#BIOS_Parameter_Block [4] Design of the FAT file system, FS Information Sector https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#FS_Information_Sector [5] Design of the FAT file system, File Allocation Table https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#File_Allocation_Table Bug 569921 - dosfsck -n delays device scan
2019-06-18 17:45:39 +00:00
static Glib::ustring remove_spaces(const Glib::ustring& str);
};
} //GParted
#endif /* GPARTED_FAT16_H */