fs/udf/balloc.c

Source file repositories/reference/linux-study-clean/fs/udf/balloc.c

File Facts

System
Linux kernel
Corpus path
fs/udf/balloc.c
Extension
.c
Size
19196 bytes
Lines
737
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (udf_test_bit(i + off, bh->b_data)) {
			bitmap->s_block_bitmap[bitmap_nr] =
							ERR_PTR(-EFSCORRUPTED);
			brelse(bh);
			return -EFSCORRUPTED;
		}
	return 0;
}

static int load_block_bitmap(struct super_block *sb,
			     struct udf_bitmap *bitmap,
			     unsigned int block_group)
{
	int retval = 0;
	int nr_groups = bitmap->s_nr_groups;

	if (block_group >= nr_groups) {
		udf_debug("block_group (%u) >= nr_groups (%d)\n",
			  block_group, nr_groups);
		return -EFSCORRUPTED;
	}

	if (bitmap->s_block_bitmap[block_group]) {
		/*
		 * The bitmap failed verification in the past. No point in
		 * trying again.
		 */
		if (IS_ERR(bitmap->s_block_bitmap[block_group]))
			return PTR_ERR(bitmap->s_block_bitmap[block_group]);
		return block_group;
	}

	retval = read_block_bitmap(sb, bitmap, block_group, block_group);
	if (retval < 0)
		return retval;

	return block_group;
}

static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)
{
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct logicalVolIntegrityDesc *lvid;

	if (!sbi->s_lvid_bh)
		return;

	lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
	le32_add_cpu(&lvid->freeSpaceTable[partition], cnt);
	udf_updated_lvid(sb);
}

static void udf_bitmap_free_blocks(struct super_block *sb,
				   struct udf_bitmap *bitmap,
				   struct kernel_lb_addr *bloc,
				   uint32_t offset,
				   uint32_t count)
{
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct buffer_head *bh = NULL;
	unsigned long block;
	unsigned long block_group;
	unsigned long bit;
	unsigned long i;
	int bitmap_nr;
	unsigned long overflow;

	mutex_lock(&sbi->s_alloc_mutex);
	/* We make sure this cannot overflow when mounting the filesystem */
	block = bloc->logicalBlockNum + offset +
		(sizeof(struct spaceBitmapDesc) << 3);
	do {
		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)) {

Annotation

Implementation Notes