patch-2.4.13 linux/fs/udf/balloc.c

Next file: linux/fs/udf/dir.c
Previous file: linux/fs/super.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.12/linux/fs/udf/balloc.c linux/fs/udf/balloc.c
@@ -44,12 +44,15 @@
 #define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
 #define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
 #define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))
+#define UintBPL Uint(BITS_PER_LONG)
+#define Uint(x) xUint(x)
+#define xUint(x) Uint ## x
 
 extern inline int find_next_one_bit (void * addr, int size, int offset)
 {
-	unsigned long * p = ((unsigned long *) addr) + (offset / BITS_PER_LONG);
-	unsigned long result = offset & ~(BITS_PER_LONG-1);
-	unsigned long tmp;
+	UintBPL * p = ((UintBPL *) addr) + (offset / BITS_PER_LONG);
+	UintBPL result = offset & ~(BITS_PER_LONG-1);
+	UintBPL tmp;
 
 	if (offset >= size)
 		return size;
@@ -126,7 +129,7 @@
 	}
 }
 
-static inline int load_block_bitmap(struct super_block *sb,
+static inline int load_block_bitmap(struct super_block * sb,
 	struct udf_bitmap *bitmap, unsigned int block_group)
 {
 	int slot;
@@ -142,7 +145,8 @@
 	return slot;
 }
 
-static void udf_bitmap_free_blocks(struct inode * inode,
+static void udf_bitmap_free_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
 {
 	struct buffer_head * bh = NULL;
@@ -152,14 +156,6 @@
 	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 ||
@@ -200,7 +196,8 @@
 		}
 		else
 		{
-			DQUOT_FREE_BLOCK(inode, 1);
+			if (inode)
+				DQUOT_FREE_BLOCK(inode, 1);
 			if (UDF_SB_LVIDBH(sb))
 			{
 				UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -223,7 +220,8 @@
 	return;
 }
 
-static int udf_bitmap_prealloc_blocks(struct inode * inode,
+static int udf_bitmap_prealloc_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
 	Uint32 block_count)
 {
@@ -231,14 +229,7 @@
 	int bit, block, block_group, group_start;
 	int nr_groups, bitmap_nr;
 	struct buffer_head *bh;
-	struct super_block *sb;
 
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return 0;
-	}
 	lock_super(sb);
 
 	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
@@ -293,23 +284,17 @@
 	return alloc_count;
 }
 
-static int udf_bitmap_new_block(struct inode * inode,
+static int udf_bitmap_new_block(struct super_block * sb,
+	struct inode * inode,
 	struct udf_bitmap *bitmap, Uint16 partition, Uint32 goal, int *err)
 {
 	int newbit, bit=0, block, block_group, group_start;
 	int end_goal, nr_groups, bitmap_nr, i;
 	struct buffer_head *bh = NULL;
-	struct super_block *sb;
 	char *ptr;
 	int newblock = 0;
 
 	*err = -ENOSPC;
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return newblock;
-	}
 	lock_super(sb);
 
 repeat:
@@ -404,7 +389,7 @@
 	/*
 	 * Check quota for allocation of this block.
 	 */
-	if (DQUOT_ALLOC_BLOCK(inode, 1))
+	if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
 	{
 		unlock_super(sb);
 		*err = -EDQUOT;
@@ -439,30 +424,17 @@
 	return 0;
 }
 
-static void udf_table_free_blocks(struct inode * inode,
+static void udf_table_free_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
 {
-	struct super_block * sb;
 	Uint32 start, end;
 	Uint32 nextoffset, oextoffset, elen;
 	lb_addr nbloc, obloc, eloc;
 	struct buffer_head *obh, *nbh;
-	char etype;
+	Sint8 etype;
 	int i;
 
-	udf_debug("ino=%ld, bloc=%d, offset=%d, count=%d\n",
-		inode->i_ino, bloc.logicalBlockNum, offset, count);
-
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device");
-		return;
-	}
-
-	if (table == NULL)
-		return;
-
 	lock_super(sb);
 	if (bloc.logicalBlockNum < 0 ||
 		(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
@@ -475,7 +447,8 @@
 
 	/* We do this up front - There are some error conditions that could occure,
 	   but.. oh well */
-	DQUOT_FREE_BLOCK(inode, count);
+	if (inode)
+		DQUOT_FREE_BLOCK(inode, count);
 	if (UDF_SB_LVIDBH(sb))
 	{
 		UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -690,33 +663,20 @@
 	return;
 }
 
-static int udf_table_prealloc_blocks(struct inode * inode,
+static int udf_table_prealloc_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct inode *table, Uint16 partition, Uint32 first_block,
 	Uint32 block_count)
 {
-	struct super_block *sb;
 	int alloc_count = 0;
 	Uint32 extoffset, elen, adsize;
 	lb_addr bloc, eloc;
 	struct buffer_head *bh;
-	char etype = -1;
-
-	udf_debug("ino=%ld, partition=%d, first_block=%d, block_count=%d\n",
-		inode->i_ino, partition, first_block, block_count);
-
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return 0;
-	}
+	Sint8 etype = -1;
 
 	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
 		return 0;
 
-	if (table == NULL)
-		return 0;
-
 	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
 	else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
@@ -745,7 +705,9 @@
 		extoffset -= adsize;
 
 		alloc_count = (elen >> sb->s_blocksize_bits);
-		if (alloc_count > block_count)
+		if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
+			alloc_count = 0;
+		else if (alloc_count > block_count)
 		{
 			alloc_count = block_count;
 			eloc.logicalBlockNum += alloc_count;
@@ -765,37 +727,24 @@
 		UDF_SB_LVID(sb)->freeSpaceTable[partition] =
 			cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+		sb->s_dirt = 1;
 	}
-	sb->s_dirt = 1;
 	unlock_super(sb);
-	udf_debug("alloc_count=%d\n", alloc_count);
 	return alloc_count;
 }
 
-static int udf_table_new_block(const struct inode * inode,
+static int udf_table_new_block(struct super_block * sb,
+	struct inode * inode,
 	struct inode *table, Uint16 partition, Uint32 goal, int *err)
 {
-	struct super_block *sb;
 	Uint32 spread = 0xFFFFFFFF, nspread;
 	Uint32 newblock = 0, adsize;
 	Uint32 extoffset, goal_extoffset, elen, goal_elen = 0;
 	lb_addr bloc, goal_bloc, eloc, goal_eloc;
 	struct buffer_head *bh, *goal_bh;
-	char etype;
-
-	udf_debug("ino=%ld, partition=%d, goal=%d\n",
-		inode->i_ino, partition, goal);
+	Sint8 etype;
 
 	*err = -ENOSPC;
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return newblock;
-	}
-
-	if (table == NULL)
-		return newblock;
 
 	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
@@ -868,6 +817,14 @@
 	goal_eloc.logicalBlockNum ++;
 	goal_elen -= sb->s_blocksize;
 
+	if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
+	{
+		udf_release_data(goal_bh);
+		unlock_super(sb);
+		*err = -EDQUOT;
+		return 0;
+	}
+
 	if (goal_elen)
 		udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
 	else
@@ -887,93 +844,98 @@
 	return newblock;
 }
 
-inline void udf_free_blocks(struct inode * inode, lb_addr bloc,
-	Uint32 offset, Uint32 count)
+inline void udf_free_blocks(struct super_block * sb,
+	struct inode * inode,
+	lb_addr bloc, Uint32 offset, Uint32 count)
 {
-	if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	Uint16 partition = bloc.partitionReferenceNum;
+
+	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
-		return udf_bitmap_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_bitmap,
+		return udf_bitmap_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
 			bloc, offset, count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
 	{
-		return udf_table_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_table,
+		return udf_table_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
 			bloc, offset, count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_BITMAP)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
-		return udf_bitmap_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_bitmap,
+		return udf_bitmap_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
 			bloc, offset, count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
 	{
-		return udf_table_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_table,
+		return udf_table_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
 			bloc, offset, count);
 	}
 	else
 		return;
 }
 
-inline int udf_prealloc_blocks(struct inode * inode, Uint16 partition,
-	Uint32 first_block, Uint32 block_count)
+inline int udf_prealloc_blocks(struct super_block * sb,
+	struct inode * inode,
+	Uint16 partition, Uint32 first_block, Uint32 block_count)
 {
-	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
-		return udf_bitmap_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+		return udf_bitmap_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
 			partition, first_block, block_count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
 	{
-		return udf_table_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+		return udf_table_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
 			partition, first_block, block_count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
-		return udf_bitmap_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+		return udf_bitmap_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
 			partition, first_block, block_count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
 	{
-		return udf_table_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+		return udf_table_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
 			partition, first_block, block_count);
 	}
 	else
 		return 0;
 }
 
-inline int udf_new_block(struct inode * inode, Uint16 partition,
-	Uint32 goal, int *err)
+inline int udf_new_block(struct super_block * sb,
+	struct inode * inode,
+	Uint16 partition, Uint32 goal, int *err)
 {
-	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
-		return udf_bitmap_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+		return udf_bitmap_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
 			partition, goal, err);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
 	{
-		return udf_table_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+		return udf_table_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
 			partition, goal, err);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
-		return udf_bitmap_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+		return udf_bitmap_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
 			partition, goal, err);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
 	{
-		return udf_table_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+		return udf_table_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
 			partition, goal, err);
 	}
 	else

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)