--- old/usr/src/lib/libparted/common/libparted/fs/fat/table.c 2014-07-17 16:13:50.397138128 +0200
+++ /dev/null 2014-07-17 16:13:50.000000000 +0200
@@ -1,481 +0,0 @@
-/*
- libparted
- Copyright (C) 1998, 1999, 2000, 2007 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 3 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 .
-*/
-
-#include
-#include
-#include "fat.h"
-
-#ifndef DISCOVER_ONLY
-
-FatTable*
-fat_table_new (FatType fat_type, FatCluster size)
-{
- FatTable* ft;
- int entry_size = fat_table_entry_size (fat_type);
-
- ft = (FatTable*) ped_malloc (sizeof (FatTable));
- if (!ft) return NULL;
-
- ft->cluster_count = ft->free_cluster_count = size - 2;
-
-/* ensure there's some free room on the end, to finish off the sector */
- ft->size = ped_div_round_up (size * entry_size, 512) * 512 / entry_size;
- ft->fat_type = fat_type;
- ft->raw_size = ft->size * entry_size;
-
- ft->table = ped_malloc (ft->raw_size);
- if (!ft->table) {
- ped_free (ft);
- return NULL;
- }
-
- fat_table_clear (ft);
- return ft;
-}
-
-void
-fat_table_destroy (FatTable* ft)
-{
- ped_free (ft->table);
- ped_free (ft);
-}
-
-FatTable*
-fat_table_duplicate (const FatTable* ft)
-{
- FatTable* dup;
-
- dup = fat_table_new (ft->fat_type, ft->size);
- if (!dup) return NULL;
-
- dup->cluster_count = ft->cluster_count;
- dup->free_cluster_count = ft->free_cluster_count;
- dup->bad_cluster_count = ft->bad_cluster_count;
- dup->last_alloc = ft->last_alloc;
-
- memcpy (dup->table, ft->table, ft->raw_size);
-
- return dup;
-}
-
-void
-fat_table_clear (FatTable* ft)
-{
- memset (ft->table, 0, ft->raw_size);
-
- fat_table_set (ft, 0, 0x0ffffff8);
- fat_table_set (ft, 1, 0x0fffffff);
-
- ft->free_cluster_count = ft->cluster_count;
- ft->bad_cluster_count = 0;
- ft->last_alloc = 1;
-}
-
-int
-fat_table_set_cluster_count (FatTable* ft, FatCluster new_cluster_count)
-{
- PED_ASSERT (new_cluster_count + 2 <= ft->size, return 0);
-
- ft->cluster_count = new_cluster_count;
- return fat_table_count_stats (ft);
-}
-
-int
-fat_table_count_stats (FatTable* ft)
-{
- FatCluster i;
-
- PED_ASSERT (ft->cluster_count + 2 <= ft->size, return 0);
-
- ft->free_cluster_count = 0;
- ft->bad_cluster_count = 0;
-
- for (i=2; i < ft->cluster_count + 2; i++) {
- if (fat_table_is_available (ft, i))
- ft->free_cluster_count++;
- if (fat_table_is_bad (ft, i))
- ft->bad_cluster_count++;
- }
- return 1;
-}
-
-int
-fat_table_read (FatTable* ft, const PedFileSystem* fs, int table_num)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
-
- PED_ASSERT (ft->raw_size >= fs_info->fat_sectors * 512, return 0);
-
- memset (ft->table, 0, ft->raw_size);
-
- if (!ped_geometry_read (fs->geom, (void *) ft->table,
- fs_info->fat_offset
- + table_num * fs_info->fat_sectors,
- fs_info->fat_sectors))
- return 0;
-
- if ( *((unsigned char*) ft->table) != fs_info->boot_sector.media) {
- if (ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_IGNORE_CANCEL,
- _("FAT %d media %x doesn't match the boot sector's "
- "media %x. You should probably run scandisk."),
- (int) table_num + 1,
- (int) *((unsigned char*) ft->table),
- (int) fs_info->boot_sector.media)
- != PED_EXCEPTION_IGNORE)
- return 0;
- }
-
- ft->cluster_count = fs_info->cluster_count;
-
- fat_table_count_stats (ft);
-
- return 1;
-}
-
-int
-fat_table_write (const FatTable* ft, PedFileSystem* fs, int table_num)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
-
- PED_ASSERT (ft->raw_size >= fs_info->fat_sectors * 512, return 0);
-
- if (!ped_geometry_write (fs->geom, (void *) ft->table,
- fs_info->fat_offset
- + table_num * fs_info->fat_sectors,
- fs_info->fat_sectors))
- return 0;
- if (!ped_geometry_sync (fs->geom))
- return 0;
-
- return 1;
-}
-
-int
-fat_table_write_all (const FatTable* ft, PedFileSystem* fs)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
- int i;
-
- for (i = 0; i < fs_info->fat_table_count; i++) {
- if (!fat_table_write (ft, fs, i))
- return 0;
- }
-
- return 1;
-}
-
-int
-fat_table_compare (const FatTable* a, const FatTable* b)
-{
- FatCluster i;
-
- if (a->cluster_count != b->cluster_count)
- return 0;
-
- for (i = 0; i < a->cluster_count + 2; i++) {
- if (fat_table_get (a, i) != fat_table_get (b, i))
- return 0;
- }
-
- return 1;
-}
-
-static int
-_test_code_available (const FatTable* ft, FatCluster code)
-{
- return code == 0;
-}
-
-static int
-_test_code_bad (const FatTable* ft, FatCluster code)
-{
- switch (ft->fat_type) {
- case FAT_TYPE_FAT12:
- if (code == 0xff7) return 1;
- break;
-
- case FAT_TYPE_FAT16:
- if (code == 0xfff7) return 1;
- break;
-
- case FAT_TYPE_FAT32:
- if (code == 0x0ffffff7) return 1;
- break;
- }
- return 0;
-}
-
-static int
-_test_code_eof (const FatTable* ft, FatCluster code)
-{
- switch (ft->fat_type) {
- case FAT_TYPE_FAT12:
- if (code >= 0xff7) return 1;
- break;
-
- case FAT_TYPE_FAT16:
- if (code >= 0xfff7) return 1;
- break;
-
- case FAT_TYPE_FAT32:
- if (code >= 0x0ffffff7) return 1;
- break;
- }
- return 0;
-}
-
-void
-_update_stats (FatTable* ft, FatCluster cluster, FatCluster value)
-{
- if (_test_code_available (ft, value)
- && !fat_table_is_available (ft, cluster)) {
- ft->free_cluster_count++;
- if (fat_table_is_bad (ft, cluster))
- ft->bad_cluster_count--;
- }
-
- if (!_test_code_available (ft, value)
- && fat_table_is_available (ft, cluster)) {
- ft->free_cluster_count--;
- if (_test_code_bad (ft, cluster))
- ft->bad_cluster_count--;
- }
-}
-
-int
-fat_table_set (FatTable* ft, FatCluster cluster, FatCluster value)
-{
- if (cluster >= ft->cluster_count + 2) {
- ped_exception_throw (PED_EXCEPTION_BUG,
- PED_EXCEPTION_CANCEL,
- _("fat_table_set: cluster %ld outside "
- "file system"),
- (long) cluster);
- return 0;
- }
-
- _update_stats (ft, cluster, value);
-
- switch (ft->fat_type) {
- case FAT_TYPE_FAT12:
- PED_ASSERT (0, (void) 0);
- break;
-
- case FAT_TYPE_FAT16:
- ((unsigned short *) ft->table) [cluster]
- = PED_CPU_TO_LE16 (value);
- break;
-
- case FAT_TYPE_FAT32:
- ((unsigned int *) ft->table) [cluster]
- = PED_CPU_TO_LE32 (value);
- break;
- }
- return 1;
-}
-
-FatCluster
-fat_table_get (const FatTable* ft, FatCluster cluster)
-{
- if (cluster >= ft->cluster_count + 2) {
- ped_exception_throw (PED_EXCEPTION_BUG,
- PED_EXCEPTION_CANCEL,
- _("fat_table_get: cluster %ld outside "
- "file system"),
- (long) cluster);
- exit (1); /* FIXME */
- }
-
- switch (ft->fat_type) {
- case FAT_TYPE_FAT12:
- PED_ASSERT (0, (void) 0);
- break;
-
- case FAT_TYPE_FAT16:
- return PED_LE16_TO_CPU
- (((unsigned short *) ft->table) [cluster]);
-
- case FAT_TYPE_FAT32:
- return PED_LE32_TO_CPU
- (((unsigned int *) ft->table) [cluster]);
- }
-
- return 0;
-}
-
-FatCluster
-fat_table_alloc_cluster (FatTable* ft)
-{
- FatCluster i;
- FatCluster cluster;
-
-/* hack: assumes the first two FAT entries are marked as used (which they
- * always should be)
- */
- for (i=1; i < ft->cluster_count + 1; i++) {
- cluster = (i + ft->last_alloc) % ft->cluster_count;
- if (fat_table_is_available (ft, cluster)) {
- ft->last_alloc = cluster;
- return cluster;
- }
- }
-
- ped_exception_throw (PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("fat_table_alloc_cluster: no free clusters"));
- return 0;
-}
-
-FatCluster
-fat_table_alloc_check_cluster (FatTable* ft, PedFileSystem* fs)
-{
- FatSpecific* fs_info = FAT_SPECIFIC (fs);
- FatCluster result;
-
- while (1) {
- result = fat_table_alloc_cluster (ft);
- if (!result)
- return 0;
- if (fat_read_cluster (fs, fs_info->buffer, result))
- return result;
- fat_table_set_bad (ft, result);
- }
-}
-
-/*
- returns true if is marked as bad
-*/
-int
-fat_table_is_bad (const FatTable* ft, FatCluster cluster)
-{
- return _test_code_bad (ft, fat_table_get (ft, cluster));
-}
-
-/*
- returns true if represents an EOF marker
-*/
-int
-fat_table_is_eof (const FatTable* ft, FatCluster cluster)
-{
- return _test_code_eof (ft, cluster);
-}
-
-/*
- returns true if is available.
-*/
-int
-fat_table_is_available (const FatTable* ft, FatCluster cluster)
-{
- return _test_code_available (ft, fat_table_get (ft, cluster));
-}
-
-/*
- returns true if is empty. Note that this includes bad clusters.
-*/
-int
-fat_table_is_empty (const FatTable* ft, FatCluster cluster)
-{
- return fat_table_is_available (ft, cluster)
- || fat_table_is_bad (ft, cluster);
-}
-
-/*
- returns true if is being used for something constructive.
-*/
-int
-fat_table_is_active (const FatTable* ft, FatCluster cluster)
-{
- return !fat_table_is_bad (ft, cluster)
- && !fat_table_is_available (ft, cluster);
-}
-
-/*
- marks as the last cluster in the chain
-*/
-int
-fat_table_set_eof (FatTable* ft, FatCluster cluster)
-{
-
- switch (ft->fat_type) {
- case FAT_TYPE_FAT12:
- PED_ASSERT (0, (void) 0);
- break;
-
- case FAT_TYPE_FAT16:
- return fat_table_set (ft, cluster, 0xfff8);
-
- case FAT_TYPE_FAT32:
- return fat_table_set (ft, cluster, 0x0fffffff);
- }
-
- return 0;
-}
-
-/*
- Marks a clusters as unusable, due to physical disk damage.
-*/
-int
-fat_table_set_bad (FatTable* ft, FatCluster cluster)
-{
- if (!fat_table_is_bad (ft, cluster))
- ft->bad_cluster_count++;
-
- switch (ft->fat_type) {
- case FAT_TYPE_FAT12:
- return fat_table_set (ft, cluster, 0xff7);
-
- case FAT_TYPE_FAT16:
- return fat_table_set (ft, cluster, 0xfff7);
-
- case FAT_TYPE_FAT32:
- return fat_table_set (ft, cluster, 0x0ffffff7);
- }
-
- return 0;
-}
-
-/*
- marks as unused/free/available
-*/
-int
-fat_table_set_avail (FatTable* ft, FatCluster cluster)
-{
- return fat_table_set (ft, cluster, 0);
-}
-
-#endif /* !DISCOVER_ONLY */
-
-int
-fat_table_entry_size (FatType fat_type)
-{
- switch (fat_type) {
- case FAT_TYPE_FAT12:
- return 2; /* FIXME: how? */
-
- case FAT_TYPE_FAT16:
- return 2;
-
- case FAT_TYPE_FAT32:
- return 4;
- }
-
- return 0;
-}
-