Ejemplo n.º 1
0
static void udf_bitmap_free_blocks(const struct inode * inode,
	struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
{
	struct buffer_head * bh = NULL;
	unsigned long block;
	unsigned long block_group;
	unsigned long bit;
	unsigned long i;
	int bitmap_nr;
	unsigned long overflow;
	struct super_block * sb;

	sb = inode->i_sb;
	if (!sb)
	{
		udf_debug("nonexistent device");
		return;
	}

	lock_super(sb);
	if (bloc.logicalBlockNum < 0 ||
		(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
	{
		udf_debug("%d < %d || %d + %d > %d\n",
			bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
			UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
		goto error_return;
	}

	block = bloc.logicalBlockNum + offset + (sizeof(struct SpaceBitmapDesc) << 3);

do_more:
	overflow = 0;
	block_group = block >> (sb->s_blocksize_bits + 3);
	bit = block % (sb->s_blocksize << 3);

	/*
	 * Check to see if we are freeing blocks across a group boundary.
	 */
	if (bit + count > (sb->s_blocksize << 3))
	{
		overflow = bit + count - (sb->s_blocksize << 3);
		count -= overflow;
	}
	bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
	if (bitmap_nr < 0)
		goto error_return;

	bh = bitmap->s_block_bitmap[bitmap_nr];
	for (i=0; i < count; i++)
	{
		if (udf_set_bit(bit + i, bh->b_data))
		{
			udf_debug("bit %ld already set\n", bit + i);
			udf_debug("byte=%2x\n", ((char *)bh->b_data)[(bit + i) >> 3]);
		}
		else
		{
Ejemplo n.º 2
0
int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
{
	struct udf_sparing_data *sdata;
	struct sparingTable *st = NULL;
	struct sparingEntry mapEntry;
	uint32_t packet;
	int i, j, k, l;

	for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
		if (old_block > UDF_SB_PARTROOT(sb,i) &&
		    old_block < UDF_SB_PARTROOT(sb,i) + UDF_SB_PARTLEN(sb,i)) {
			sdata = &UDF_SB_TYPESPAR(sb,i);
			packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1);

			for (j = 0; j < 4; j++) {
				if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) {
					st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
					break;
				}
			}

			if (!st)
				return 1;

			for (k = 0; k < le16_to_cpu(st->reallocationTableLen); k++) {
				if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF) {
					for (; j < 4; j++) {
						if (sdata->s_spar_map[j]) {
							st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
							st->mapEntry[k].origLocation = cpu_to_le32(packet);
							udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
							mark_buffer_dirty(sdata->s_spar_map[j]);
						}
					}
					*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
						((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
					return 0;
				} else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet) {
					*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
						((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
					return 0;
				} else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet) {
					break;
				}
			}

			for (l = k; l < le16_to_cpu(st->reallocationTableLen); l++) {
				if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF) {
					for (; j < 4; j++) {
						if (sdata->s_spar_map[j]) {
							st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
							mapEntry = st->mapEntry[l];
							mapEntry.origLocation = cpu_to_le32(packet);
							memmove(&st->mapEntry[k + 1], &st->mapEntry[k], (l - k) * sizeof(struct sparingEntry));
							st->mapEntry[k] = mapEntry;
							udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
							mark_buffer_dirty(sdata->s_spar_map[j]);
						}
					}
					*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
						((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
					return 0;
				}
			}

			return 1;
		} /* if old_block */
	}

	if (i == UDF_SB_NUMPARTS(sb)) {
		/* outside of partitions */
		/* for now, fail =) */
		return 1;
	}

	return 0;
}
Ejemplo n.º 3
0
static int 
udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
{
	struct buffer_head *bh = NULL;
	long lastblock;
	Uint16 ident;

	if (fileset->logicalBlockNum != 0xFFFFFFFF ||
		fileset->partitionReferenceNum != 0xFFFF)
	{
		bh = udf_read_ptagged(sb, *fileset, 0, &ident);

		if (!bh)
			return 1;
		else if (ident != TID_FILE_SET_DESC)
		{
			udf_release_data(bh);
			return 1;
		}
			
	}

	if (!bh) /* Search backwards through the partitions */
	{
		lb_addr newfileset;

		return 1;
		
		for (newfileset.partitionReferenceNum=UDF_SB_NUMPARTS(sb)-1;
			(newfileset.partitionReferenceNum != 0xFFFF &&
				fileset->logicalBlockNum == 0xFFFFFFFF &&
				fileset->partitionReferenceNum == 0xFFFF);
			newfileset.partitionReferenceNum--)
		{
			lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum);
			newfileset.logicalBlockNum = 0;

			do
			{
				bh = udf_read_ptagged(sb, newfileset, 0, &ident);
				if (!bh)
				{
					newfileset.logicalBlockNum ++;
					continue;
				}

				switch (ident)
				{
					case TID_SPACE_BITMAP_DESC:
					{
						struct SpaceBitmapDesc *sp;
						sp = (struct SpaceBitmapDesc *)bh->b_data;
						newfileset.logicalBlockNum += 1 +
							((le32_to_cpu(sp->numOfBytes) + sizeof(struct SpaceBitmapDesc) - 1)
								>> sb->s_blocksize_bits);
						udf_release_data(bh);
						break;
					}
					case TID_FILE_SET_DESC:
					{
						*fileset = newfileset;
						break;
					}
					default:
					{
						newfileset.logicalBlockNum ++;
						udf_release_data(bh);
						bh = NULL;
						break;
					}
				}
			}
			while (newfileset.logicalBlockNum < lastblock &&
				fileset->logicalBlockNum == 0xFFFFFFFF &&
				fileset->partitionReferenceNum == 0xFFFF);
		}
	}