Beispiel #1
0
static int
read_next_dir_buffer (FatTraverseInfo* trav_info)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (trav_info->fs);

	PED_ASSERT (!trav_info->is_legacy_root_dir);

	trav_info->this_buffer = trav_info->next_buffer;

	if (trav_info->this_buffer < 2
	    || trav_info->this_buffer >= fs_info->cluster_count + 2) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			"Cluster %ld in directory %s is outside file system!",
			(long) trav_info->this_buffer,
			trav_info->dir_name);
		return 0;
	}

	trav_info->next_buffer
		= fat_table_get (fs_info->fat, trav_info->this_buffer);

	return fat_read_cluster (trav_info->fs, (void *) trav_info->dir_entries,
				 trav_info->this_buffer);
}
Beispiel #2
0
/* when converting FAT32 -> FAT16
 * fat_duplicate clusters() duplicated the root directory unnecessarily.
 * Let's free it.
 *
 * This must be called AFTER fat_construct_new_fat().  (otherwise, our
 * changes just get overwritten)
 */
static int
free_root_dir (FatOpContext* ctx)
{
	FatSpecific*		old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatSpecific*		new_fs_info = FAT_SPECIFIC (ctx->new_fs);
	FatCluster		old_cluster;
	FatFragment		i;

	PED_ASSERT (old_fs_info->fat_type == FAT_TYPE_FAT32);
	PED_ASSERT (new_fs_info->fat_type == FAT_TYPE_FAT16);

	for (old_cluster = old_fs_info->root_cluster;
	     !fat_table_is_eof (old_fs_info->fat, old_cluster);
	     old_cluster = fat_table_get (old_fs_info->fat, old_cluster)) {
		FatFragment old_frag;
		old_frag = fat_cluster_to_frag (ctx->old_fs, old_cluster);
		for (i = 0; i < new_fs_info->cluster_frags; i++) {
			FatFragment new_frag;
			FatCluster new_clst;
			new_frag = fat_op_context_map_fragment (ctx,
								old_frag + i);
			new_clst = fat_frag_to_cluster (ctx->old_fs, new_frag);
			if (!fat_table_set_avail (new_fs_info->fat, new_clst))
				return 0;
		}
	}

	return 1;
}
Beispiel #3
0
static FatFragment
_get_next_old_frag (FatOpContext* ctx, FatFragment frag)
{
	FatSpecific*	old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatCluster	cluster;
	FatCluster	next_cluster;

	if ((frag + 1) % old_fs_info->cluster_frags != 0) {
		if (fat_is_fragment_active (ctx->old_fs, frag + 1))
			return frag + 1;
		else
			return -1;
	} else {
		cluster = fat_frag_to_cluster (ctx->old_fs, frag);
		next_cluster = fat_table_get (old_fs_info->fat, cluster);

		if (fat_table_is_eof (old_fs_info->fat, next_cluster))
			return -1;
		else
			return fat_cluster_to_frag (ctx->old_fs, next_cluster);
	}
}
Beispiel #4
0
/*
    Constructs the new fat for the resized file system.
*/
static int
fat_construct_new_fat (FatOpContext* ctx)
{
	FatSpecific*	old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatSpecific*	new_fs_info = FAT_SPECIFIC (ctx->new_fs);
	FatFragment	old_frag;
	FatCluster	new_cluster;
	FatFragment	new_frag;
	FatFragment	old_next_frag;
	FatFragment	new_next_frag;
	FatCluster	new_next_cluster;
	FatClusterFlag	flag;
	int		i;

	fat_table_clear (new_fs_info->fat);
	if (!fat_table_set_cluster_count (new_fs_info->fat,
					  new_fs_info->cluster_count))
		return 0;

	for (old_frag = 0; old_frag < old_fs_info->frag_count; old_frag++) {
		flag = fat_get_fragment_flag (ctx->old_fs, old_frag);
		if (flag == FAT_FLAG_FREE)
			continue;
		if (flag == FAT_FLAG_BAD) {
			new_frag = fat_op_context_map_static_fragment (
						ctx, old_frag);
			if (new_frag == -1)
				continue;
			new_cluster = fat_frag_to_cluster (ctx->new_fs,
							   new_frag);
			fat_table_set_bad (new_fs_info->fat, new_cluster);
			continue;
		}

		new_frag = fat_op_context_map_fragment (ctx, old_frag);
		new_cluster = fat_frag_to_cluster (ctx->new_fs, new_frag);

		old_next_frag = _get_next_old_frag (ctx, old_frag);
		if (old_next_frag == -1) {
			fat_table_set_eof (new_fs_info->fat, new_cluster);
			continue;
		}

		new_next_frag = fat_op_context_map_fragment (ctx,
							     old_next_frag);
		PED_ASSERT (new_next_frag != -1);

		new_next_cluster = fat_frag_to_cluster (ctx->new_fs,
							new_next_frag);
		PED_ASSERT (new_next_cluster != new_cluster);

		fat_table_set (new_fs_info->fat, new_cluster, new_next_cluster);
	}

#if 0
#ifdef PED_VERBOSE
	for (old_cluster=2; old_cluster < old_fs_info->cluster_count+2;
	     old_cluster++) {
		if (fat_table_is_available (old_fs_info->fat, old_cluster))
			continue;

		printf ("%d->%d\t(next: %d->%d)\n",
			old_cluster,
			ctx->remap [old_cluster],
			fat_table_get (old_fs_info->fat, old_cluster),
			fat_table_get (new_fs_info->fat,
				       ctx->remap [old_cluster]));
	}
#endif /* PED_VERBOSE */
#endif

	if (old_fs_info->fat_type == FAT_TYPE_FAT32
	    && new_fs_info->fat_type == FAT_TYPE_FAT32) {
		new_fs_info->root_cluster
			= fat_op_context_map_cluster (ctx,
					old_fs_info->root_cluster);
	}

	if (old_fs_info->fat_type == FAT_TYPE_FAT16
	    && new_fs_info->fat_type == FAT_TYPE_FAT32) {
		for (i=0; ctx->new_root_dir[i+1]; i++) {
			fat_table_set (new_fs_info->fat,
				       ctx->new_root_dir[i],
				       ctx->new_root_dir[i+1]);
		}
		fat_table_set_eof (new_fs_info->fat, ctx->new_root_dir[i]);
	}

	return 1;
}