From 232dbda915dfcfec99e5983b7f53d57d4498a6aa Mon Sep 17 00:00:00 2001 From: Anant Narayanan Date: Thu, 14 Sep 2006 15:18:45 +0000 Subject: Fix ChangeLog git-svn-id: svn://svn.debian.org/svn/parted/upstream/trunk@820 2d424fd7-7fe2-0310-af74-8bc65edeb173 --- libparted/fs/fat/fat.c | 888 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 888 insertions(+) create mode 100644 libparted/fs/fat/fat.c (limited to 'libparted/fs/fat/fat.c') diff --git a/libparted/fs/fat/fat.c b/libparted/fs/fat/fat.c new file mode 100644 index 0000000..ee06f1a --- /dev/null +++ b/libparted/fs/fat/fat.c @@ -0,0 +1,888 @@ +/* + libparted + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include +#include + +#include "fat.h" +#include "calc.h" + +PedFileSystem* +fat_alloc (const PedGeometry* geom) +{ + PedFileSystem* fs; + + fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem)); + if (!fs) + goto error; + + fs->type_specific = (FatSpecific*) ped_malloc (sizeof (FatSpecific)); + if (!fs->type_specific) + goto error_free_fs; + + fs->geom = ped_geometry_duplicate (geom); + if (!fs->geom) + goto error_free_type_specific; + + fs->checked = 0; + return fs; + +error_free_type_specific: + ped_free (fs->type_specific); +error_free_fs: + ped_free (fs); +error: + return NULL; +} + +/* Requires the boot sector to be analysed */ +int +fat_alloc_buffers (PedFileSystem* fs) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + + fs_info->buffer_sectors = BUFFER_SIZE; + fs_info->buffer = ped_malloc (fs_info->buffer_sectors * 512); + if (!fs_info->buffer) + goto error; + + fs_info->cluster_info = ped_malloc (fs_info->cluster_count + 2); + if (!fs_info->cluster_info) + goto error_free_buffer; + + return 1; + +error_free_buffer: + ped_free (fs_info->buffer); +error: + return 0; +}; + +void +fat_free_buffers (PedFileSystem* fs) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + + ped_free (fs_info->cluster_info); + ped_free (fs_info->buffer); +} + +void +fat_free (PedFileSystem* fs) +{ + ped_geometry_destroy (fs->geom); + ped_free (fs->type_specific); + ped_free (fs); +} + +int +fat_set_frag_sectors (PedFileSystem* fs, PedSector frag_sectors) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + + PED_ASSERT (fs_info->cluster_sectors % frag_sectors == 0 + && frag_sectors <= fs_info->cluster_sectors, + return 0); + + fs_info->frag_size = frag_sectors * 512; + fs_info->frag_sectors = frag_sectors; + fs_info->buffer_frags = fs_info->buffer_sectors / frag_sectors; + fs_info->cluster_frags = fs_info->cluster_sectors / frag_sectors; + fs_info->frag_count = fs_info->cluster_count * fs_info->cluster_frags; + + return 1; +} + +PedGeometry* +fat_probe (PedGeometry* geom, FatType* fat_type) +{ + PedFileSystem* fs; + FatSpecific* fs_info; + PedGeometry* result; + + fs = fat_alloc (geom); + if (!fs) + goto error; + fs_info = (FatSpecific*) fs->type_specific; + + if (!fat_boot_sector_read (&fs_info->boot_sector, geom)) + goto error_free_fs; + if (!fat_boot_sector_analyse (&fs_info->boot_sector, fs)) + goto error_free_fs; + + *fat_type = fs_info->fat_type; + result = ped_geometry_new (geom->dev, geom->start, + fs_info->sector_count); + + fat_free (fs); + return result; + +error_free_fs: + fat_free (fs); +error: + return NULL; +} + +PedGeometry* +fat_probe_fat16 (PedGeometry* geom) +{ + FatType fat_type; + PedGeometry* probed_geom = fat_probe (geom, &fat_type); + + if (probed_geom) { + if (fat_type == FAT_TYPE_FAT16) + return probed_geom; + ped_geometry_destroy (probed_geom); + } + return NULL; +} + +PedGeometry* +fat_probe_fat32 (PedGeometry* geom) +{ + FatType fat_type; + PedGeometry* probed_geom = fat_probe (geom, &fat_type); + + if (probed_geom) { + if (fat_type == FAT_TYPE_FAT32) + return probed_geom; + ped_geometry_destroy (probed_geom); + } + return NULL; +} + +#ifndef DISCOVER_ONLY +int +fat_clobber (PedGeometry* geom) +{ + FatBootSector boot_sector; + + if (!fat_boot_sector_read (&boot_sector, geom)) + return 1; + + boot_sector.system_id[0] = 0; + boot_sector.boot_sign = 0; + if (boot_sector.u.fat16.fat_name[0] == 'F') + boot_sector.u.fat16.fat_name[0] = 0; + if (boot_sector.u.fat32.fat_name[0] == 'F') + boot_sector.u.fat32.fat_name[0] = 0; + + return ped_geometry_write (geom, &boot_sector, 0, 1); +} + +static int +_init_fats (PedFileSystem* fs) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + int i; + FatCluster table_size; + + table_size = fs_info->fat_sectors * 512 + / fat_table_entry_size (fs_info->fat_type); + fs_info->fat = fat_table_new (fs_info->fat_type, table_size); + if (!fs_info->fat) + goto error; + + if (!fat_table_read (fs_info->fat, fs, 0)) + goto error_free_fat; + + return 1; + +error_free_fat: + fat_table_destroy (fs_info->fat); +error: + return 0; +} + +PedFileSystem* +fat_open (PedGeometry* geom) +{ + PedFileSystem* fs; + FatSpecific* fs_info; + + fs = fat_alloc (geom); + if (!fs) + goto error; + fs_info = (FatSpecific*) fs->type_specific; + + if (!fat_boot_sector_read (&fs_info->boot_sector, geom)) + goto error_free_fs; + if (!fat_boot_sector_analyse (&fs_info->boot_sector, fs)) + goto error_free_fs; + fs->type = (fs_info->fat_type == FAT_TYPE_FAT16) + ? &fat16_type + : &fat32_type; + if (fs_info->fat_type == FAT_TYPE_FAT32) { + if (!fat_info_sector_read (&fs_info->info_sector, fs)) + goto error_free_fs; + } + + if (!_init_fats (fs)) + goto error_free_fs; + if (!fat_alloc_buffers (fs)) + goto error_free_fat_table; + if (!fat_collect_cluster_info (fs)) + goto error_free_buffers; + + return fs; + +error_free_buffers: + fat_free_buffers (fs); +error_free_fat_table: + fat_table_destroy (fs_info->fat); +error_free_fs: + fat_free (fs); +error: + return NULL; +} + +static int +fat_root_dir_clear (PedFileSystem* fs) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + memset (fs_info->buffer, 0, 512 * fs_info->root_dir_sector_count); + return ped_geometry_write (fs->geom, fs_info->buffer, + fs_info->root_dir_offset, + fs_info->root_dir_sector_count); +} + +/* hack: use the ext2 uuid library to generate a reasonably random (hopefully + * with /dev/random) number. Unfortunately, we can only use 4 bytes of it + */ +static uint32_t +_gen_new_serial_number () +{ + uuid_t uuid; + + uuid_generate (uuid); + return * (uint32_t*) &uuid [0]; +} + +PedFileSystem* +fat_create (PedGeometry* geom, FatType fat_type, PedTimer* timer) +{ + PedFileSystem* fs; + FatSpecific* fs_info; + FatCluster table_size; + + fs = fat_alloc (geom); + if (!fs) + goto error; + fs_info = (FatSpecific*) fs->type_specific; + + fs_info->logical_sector_size = 1; + fs_info->sectors_per_track = geom->dev->bios_geom.sectors; + fs_info->heads = geom->dev->bios_geom.heads; + fs_info->sector_count = fs->geom->length; + fs_info->fat_table_count = 2; +/* some initial values, to be changed later */ + fs_info->root_dir_sector_count = FAT_ROOT_DIR_ENTRY_COUNT + / (512 / sizeof (FatDirEntry)); + fs_info->root_dir_entry_count = FAT_ROOT_DIR_ENTRY_COUNT; + + fs_info->fat_type = fat_type; + if (!fat_calc_sizes (fs->geom->length, 0, + fs_info->fat_type, + fs_info->root_dir_sector_count, + &fs_info->cluster_sectors, + &fs_info->cluster_count, + &fs_info->fat_sectors)) { + ped_exception_throw (PED_EXCEPTION_ERROR, + PED_EXCEPTION_CANCEL, + _("Partition too big/small for a %s file system."), + (fat_type == FAT_TYPE_FAT16) + ? fat16_type.name + : fat32_type.name); + goto error_free_fs; + } + + fs_info->cluster_size = fs_info->cluster_sectors * 512; + + fs_info->fat_offset = fat_min_reserved_sector_count (fs_info->fat_type); + fs_info->dir_entries_per_cluster + = fs_info->cluster_size / sizeof (FatDirEntry); + + if (fs_info->fat_type == FAT_TYPE_FAT16) { + /* FAT16 */ + fs->type = &fat16_type; + + if (fs_info->cluster_count + > fat_max_cluster_count (fs_info->fat_type)) { + fs_info->cluster_count + = fat_max_cluster_count (fs_info->fat_type); + } + + fs_info->root_dir_sector_count + = FAT_ROOT_DIR_ENTRY_COUNT + / (512 / sizeof (FatDirEntry)); + fs_info->root_dir_entry_count = FAT_ROOT_DIR_ENTRY_COUNT; + fs_info->root_dir_offset + = fs_info->fat_offset + + fs_info->fat_sectors * fs_info->fat_table_count; + fs_info->cluster_offset + = fs_info->root_dir_offset + + fs_info->root_dir_sector_count; + } else { + /* FAT32 */ + fs->type = &fat32_type; + + fs_info->info_sector_offset = 1; + fs_info->boot_sector_backup_offset = 6; + + fs_info->root_dir_sector_count = 0; + fs_info->root_dir_entry_count = 0; + fs_info->root_dir_offset = 0; + + fs_info->cluster_offset + = fs_info->fat_offset + + fs_info->fat_sectors * fs_info->fat_table_count; + } + + table_size = fs_info->fat_sectors * 512 + / fat_table_entry_size (fs_info->fat_type); + fs_info->fat = fat_table_new (fs_info->fat_type, table_size); + if (!fs_info->fat) + goto error_free_fs; + fat_table_set_cluster_count (fs_info->fat, fs_info->cluster_count); + if (!fat_alloc_buffers (fs)) + goto error_free_fat_table; + + if (fs_info->fat_type == FAT_TYPE_FAT32) { + fs_info->root_cluster + = fat_table_alloc_cluster (fs_info->fat); + fat_table_set_eof (fs_info->fat, fs_info->root_cluster); + memset (fs_info->buffer, 0, fs_info->cluster_size); + if (!fat_write_cluster (fs, fs_info->buffer, + fs_info->root_cluster)) + return 0; + } + + fs_info->serial_number = _gen_new_serial_number (); + + if (!fat_boot_sector_set_boot_code (&fs_info->boot_sector)) + goto error_free_buffers; + if (!fat_boot_sector_generate (&fs_info->boot_sector, fs)) + goto error_free_buffers; + if (!fat_boot_sector_write (&fs_info->boot_sector, fs)) + goto error_free_buffers; + if (fs_info->fat_type == FAT_TYPE_FAT32) { + if (!fat_info_sector_generate (&fs_info->info_sector, fs)) + goto error_free_buffers; + if (!fat_info_sector_write (&fs_info->info_sector, fs)) + goto error_free_buffers; + } + + if (!fat_table_write_all (fs_info->fat, fs)) + goto error_free_buffers; + + if (fs_info->fat_type == FAT_TYPE_FAT16) { + if (!fat_root_dir_clear (fs)) + goto error_free_buffers; + } + + return fs; + +error_free_buffers: + fat_free_buffers (fs); +error_free_fat_table: + fat_table_destroy (fs_info->fat); +error_free_fs: + fat_free (fs); +error: + return NULL; +} + +PedFileSystem* +fat_create_fat16 (PedGeometry* geom, PedTimer* timer) +{ + return fat_create (geom, FAT_TYPE_FAT16, timer); +} + +PedFileSystem* +fat_create_fat32 (PedGeometry* geom, PedTimer* timer) +{ + return fat_create (geom, FAT_TYPE_FAT32, timer); +} + +int +fat_close (PedFileSystem* fs) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + + fat_free_buffers (fs); + fat_table_destroy (fs_info->fat); + fat_free (fs); + return 1; +} + +/* Hack: just resize the file system outside of its boundaries! */ +PedFileSystem* +fat_copy (const PedFileSystem* fs, PedGeometry* geom, PedTimer* timer) +{ + PedFileSystem* new_fs; + + new_fs = ped_file_system_open (fs->geom); + if (!new_fs) + goto error; + if (!ped_file_system_resize (new_fs, geom, timer)) + goto error_close_new_fs; + return new_fs; + +error_close_new_fs: + ped_file_system_close (new_fs); +error: + return 0; +} + +static int +_compare_fats (PedFileSystem* fs) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + FatTable* table_copy; + FatCluster table_size; + int i; + + table_size = fs_info->fat_sectors * 512 + / fat_table_entry_size (fs_info->fat_type); + + table_copy = fat_table_new (fs_info->fat_type, table_size); + if (!table_copy) + goto error; + + for (i = 1; i < fs_info->fat_table_count; i++) { + if (!fat_table_read (table_copy, fs, i)) + goto error_free_table_copy; + if (!fat_table_compare (fs_info->fat, table_copy)) { + if (ped_exception_throw (PED_EXCEPTION_ERROR, + PED_EXCEPTION_IGNORE_CANCEL, + _("The FATs don't match. If you don't know " + "what this means, then select cancel, run " + "scandisk on the file system, and then come " + "back.")) + != PED_EXCEPTION_IGNORE) + goto error_free_table_copy; + } + } + + fat_table_destroy (table_copy); + return 1; + +error_free_table_copy: + fat_table_destroy (table_copy); +error: + return 0; +} + +int +fat_check (PedFileSystem* fs, PedTimer* timer) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + PedSector cluster_sectors; + FatCluster cluster_count; + PedSector fat_sectors; + PedSector align_sectors; + FatCluster info_free_clusters; + + align_sectors = fs_info->fat_offset + - fat_min_reserved_sector_count (fs_info->fat_type); + + if (!fat_calc_sizes (fs->geom->length, + align_sectors, + fs_info->fat_type, + fs_info->root_dir_sector_count, + &cluster_sectors, + &cluster_count, + &fat_sectors)) { + if (ped_exception_throw (PED_EXCEPTION_BUG, + PED_EXCEPTION_IGNORE_CANCEL, + _("There are no possible configurations for this FAT " + "type.")) + != PED_EXCEPTION_IGNORE) + goto error; + } + + if (fs_info->fat_type == FAT_TYPE_FAT16) { + if (cluster_sectors != fs_info->cluster_sectors + || cluster_count != fs_info->cluster_count + || fat_sectors != fs_info->fat_sectors) { + if (ped_exception_throw (PED_EXCEPTION_WARNING, + PED_EXCEPTION_IGNORE_CANCEL, + _("File system doesn't have expected sizes for " + "Windows to like it. " + "Cluster size is %dk (%dk expected); " + "number of clusters is %d (%d expected); " + "size of FATs is %d sectors (%d expected)."), + (int) fs_info->cluster_sectors / 2, + (int) cluster_sectors / 2, + (int) fs_info->cluster_count, + (int) cluster_count, + (int) fs_info->fat_sectors, + (int) fat_sectors) + != PED_EXCEPTION_IGNORE) + goto error; + } + } + + if (fs_info->fat_type == FAT_TYPE_FAT32) { + info_free_clusters + = PED_LE32_TO_CPU (fs_info->info_sector.free_clusters); + if (info_free_clusters != (FatCluster) -1 + && info_free_clusters != fs_info->fat->free_cluster_count) { + if (ped_exception_throw (PED_EXCEPTION_WARNING, + PED_EXCEPTION_IGNORE_CANCEL, + _("File system is reporting the free space as " + "%d clusters, not %d clusters."), + info_free_clusters, + fs_info->fat->free_cluster_count) + != PED_EXCEPTION_IGNORE) + goto error; + } + } + + if (!_compare_fats (fs)) + goto error; + + fs->checked = 1; + return 1; /* existence of fs implies consistency ;-) */ + +error: + return 0; +} + +/* Calculates how much space there will be in clusters in: + * old_fs intersect the-new-fs + */ +static PedSector +_calc_resize_data_size ( + const PedFileSystem* old_fs, + PedSector new_cluster_sectors, + FatCluster new_cluster_count, + PedSector new_fat_size) +{ + FatSpecific* old_fs_info = FAT_SPECIFIC (old_fs); + PedSector fat_size_delta; + + fat_size_delta = old_fs_info->fat_sectors - new_fat_size; + return new_cluster_sectors * new_cluster_count - fat_size_delta * 2; +} + +static int +_test_resize_size (const PedFileSystem* fs, + PedSector length, PedSector min_data_size) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + PedGeometry geom; + PedSector _cluster_sectors; + FatCluster _cluster_count; + PedSector _fat_size; + + ped_geometry_init (&geom, fs->geom->dev, fs->geom->start, length); + + if (fat_calc_resize_sizes ( + &geom, + fs_info->cluster_sectors, + FAT_TYPE_FAT16, + fs_info->root_dir_sector_count, + fs_info->cluster_sectors, + &_cluster_sectors, + &_cluster_count, + &_fat_size) + && _calc_resize_data_size (fs, _cluster_sectors, _cluster_count, + _fat_size) + >= min_data_size) + return 1; + + if (fat_calc_resize_sizes ( + &geom, + fs_info->cluster_sectors, + FAT_TYPE_FAT32, + 0, + fs_info->cluster_sectors, + &_cluster_sectors, + &_cluster_count, + &_fat_size) + && _calc_resize_data_size (fs, _cluster_sectors, _cluster_count, + _fat_size) + >= min_data_size) + return 1; + + return 0; +} + +/* does a binary search (!) for the mininum size. Too hard to compute directly + * (see calc_sizes() for why!) + */ +static PedSector +_get_min_resize_size (const PedFileSystem* fs, PedSector min_data_size) +{ + PedSector min_length = 0; + PedSector max_length = fs->geom->length; + PedSector length; + + while (min_length < max_length - 1) { + length = (min_length + max_length) / 2; + if (_test_resize_size (fs, length, min_data_size)) + max_length = length; + else + min_length = length; + } + +/* adds a bit of leeway (64 sectors), for resolving extra issues, like root + * directory allocation, that aren't covered here. + */ + return max_length + 64; +} + +PedConstraint* +fat_get_copy_constraint (const PedFileSystem* fs, const PedDevice* dev) +{ + FatSpecific* fs_info = FAT_SPECIFIC (fs); + PedGeometry full_dev; + PedSector min_cluster_count; + FatCluster used_clusters; + PedSector min_data_size; + + if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1)) + return NULL; + + used_clusters = fs_info->fat->cluster_count + - fs_info->fat->free_cluster_count; + min_cluster_count = used_clusters + fs_info->total_dir_clusters; + min_data_size = min_cluster_count * fs_info->cluster_sectors; + + return ped_constraint_new (ped_alignment_any, ped_alignment_any, + &full_dev, &full_dev, + _get_min_resize_size (fs, min_data_size), + dev->length); +} + +PedConstraint* +fat_get_resize_constraint (const PedFileSystem* fs) +{ + return fat_get_copy_constraint (fs, fs->geom->dev); +} + +/* FIXME: fat_calc_sizes() needs to say "too big" or "too small", or + * something. This is a really difficult (maths) problem to do + * nicely... + * So, this algorithm works if dev->length / 2 is a valid fat_type + * size. (Which is how I got the magic numbers below) + */ +#if 0 +/* returns: -1 too small, 0 ok, 1 too big */ +static int +_test_create_size (PedSector length, FatType fat_type, + PedSector cluster_sectors, PedSector cluster_count) +{ + PedSector rootdir_sectors; + PedSector _cluster_sectors; + FatCluster _cluster_count; + PedSector _fat_size; + + rootdir_sectors = (fat_type == FAT_TYPE_FAT16) ? 16 : 0; + + if (!fat_calc_sizes (length, 0, fat_type, rootdir_sectors, + &_cluster_sectors, &_cluster_count, &_fat_size)) + return -1; // XXX: doesn't work... can't see a better way! + + if (_cluster_sectors < cluster_sectors) + return -1; + if (_cluster_sectors > cluster_sectors) + return 1; + + if (_cluster_count < cluster_count) + return -1; + if (_cluster_count > cluster_count) + return 1; + + return 0; +} + +static PedSector +_get_create_size (PedSector upper_bound, FatType fat_type, + PedSector cluster_sectors, FatCluster cluster_count) +{ + PedSector min_length = 0; + PedSector max_length = upper_bound; + PedSector length; + + while (1) { + length = (min_length + max_length) / 2; + switch (_test_create_size (length, fat_type, cluster_sectors, + cluster_count)) { + case -1: min_length = length; break; + case 0: return length; + case 1: max_length = length; break; + } + /* hack... won't always be able to get max cluster count + * with max cluster size, etc. */ + if (max_length - min_length == 1) + return min_length; + } + + return 0; /* shut gcc up */ +} +#endif + +PedConstraint* +fat_get_create_constraint_fat16 (const PedDevice* dev) +{ + PedGeometry full_dev; + PedSector min_size; + PedSector max_size; + + if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1)) + return NULL; + +#if 0 + min_size = _get_create_size (dev->length, FAT_TYPE_FAT16, + fat_min_cluster_size (FAT_TYPE_FAT16), + fat_min_cluster_count (FAT_TYPE_FAT16)); + max_size = _get_create_size (dev->length, FAT_TYPE_FAT16, + fat_max_cluster_size (FAT_TYPE_FAT16), + fat_max_cluster_count (FAT_TYPE_FAT16)); + if (!min_size) + return NULL; +#else + min_size = 65794; + max_size = 2097153; +#endif + + return ped_constraint_new ( + ped_alignment_any, ped_alignment_any, + &full_dev, &full_dev, + min_size, max_size); +} + +PedConstraint* +fat_get_create_constraint_fat32 (const PedDevice* dev) +{ + PedGeometry full_dev; + PedSector min_size; + + if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1)) + return NULL; + +#if 0 + min_size = _get_create_size (dev->length, FAT_TYPE_FAT32, + fat_min_cluster_size (FAT_TYPE_FAT32), + fat_min_cluster_count (FAT_TYPE_FAT32)); + if (!min_size) + return NULL; +#else + min_size = 525224; +#endif + + return ped_constraint_new ( + ped_alignment_any, ped_alignment_any, + &full_dev, &full_dev, + min_size, dev->length); +} +#endif /* !DISCOVER_ONLY */ + +static PedFileSystemOps fat16_ops = { + probe: fat_probe_fat16, +#ifndef DISCOVER_ONLY + clobber: fat_clobber, + open: fat_open, + create: fat_create_fat16, + close: fat_close, + check: fat_check, + resize: fat_resize, + copy: fat_copy, + get_create_constraint: fat_get_create_constraint_fat16, + get_resize_constraint: fat_get_resize_constraint, + get_copy_constraint: fat_get_copy_constraint, +#else /* !DISCOVER_ONLY */ + clobber: NULL, + open: NULL, + create: NULL, + close: NULL, + check: NULL, + resize: NULL, + copy: NULL, + get_create_constraint: NULL, + get_resize_constraint: NULL, + get_copy_constraint: NULL, +#endif /* !DISCOVER_ONLY */ +}; + +static PedFileSystemOps fat32_ops = { + probe: fat_probe_fat32, +#ifndef DISCOVER_ONLY + clobber: fat_clobber, + open: fat_open, + create: fat_create_fat32, + close: fat_close, + check: fat_check, + resize: fat_resize, + copy: fat_copy, + get_create_constraint: fat_get_create_constraint_fat32, + get_resize_constraint: fat_get_resize_constraint, + get_copy_constraint: fat_get_copy_constraint, +#else /* !DISCOVER_ONLY */ + clobber: NULL, + open: NULL, + create: NULL, + close: NULL, + check: NULL, + resize: NULL, + copy: NULL, + get_create_constraint: NULL, + get_resize_constraint: NULL, + get_copy_constraint: NULL, +#endif /* !DISCOVER_ONLY */ +}; + +#define FAT_BLOCK_SIZES ((int[2]){512, 0}) + +PedFileSystemType fat16_type = { + next: NULL, + ops: &fat16_ops, + name: "fat16", + block_sizes: FAT_BLOCK_SIZES +}; + +PedFileSystemType fat32_type = { + next: NULL, + ops: &fat32_ops, + name: "fat32", + block_sizes: FAT_BLOCK_SIZES +}; + +void +ped_file_system_fat_init () +{ + if (sizeof (FatBootSector) != 512) { + ped_exception_throw (PED_EXCEPTION_BUG, PED_EXCEPTION_CANCEL, + _("GNU Parted was miscompiled: the FAT boot sector " + "should be 512 bytes. FAT support will be disabled.")); + } else { + ped_file_system_type_register (&fat16_type); + ped_file_system_type_register (&fat32_type); + } +} + +void +ped_file_system_fat_done () +{ + ped_file_system_type_unregister (&fat16_type); + ped_file_system_type_unregister (&fat32_type); +} + -- cgit v1.2.1