mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	udf: Factor out code for creating indirect extent
Factor out code for creating indirect extent from udf_add_aext(). It was mostly duplicated in two places. Also remove some opencoded versions of udf_write_aext(). Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
		
							parent
							
								
									b0918d9f47
								
							
						
					
					
						commit
						fcea62babc
					
				
					 3 changed files with 130 additions and 189 deletions
				
			
		| 
						 | 
					@ -447,9 +447,6 @@ static void udf_table_free_blocks(struct super_block *sb,
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int adsize;
 | 
							int adsize;
 | 
				
			||||||
		struct short_ad *sad = NULL;
 | 
					 | 
				
			||||||
		struct long_ad *lad = NULL;
 | 
					 | 
				
			||||||
		struct allocExtDesc *aed;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		eloc.logicalBlockNum = start;
 | 
							eloc.logicalBlockNum = start;
 | 
				
			||||||
		elen = EXT_RECORDED_ALLOCATED |
 | 
							elen = EXT_RECORDED_ALLOCATED |
 | 
				
			||||||
| 
						 | 
					@ -466,102 +463,17 @@ static void udf_table_free_blocks(struct super_block *sb,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (epos.offset + (2 * adsize) > sb->s_blocksize) {
 | 
							if (epos.offset + (2 * adsize) > sb->s_blocksize) {
 | 
				
			||||||
			unsigned char *sptr, *dptr;
 | 
					 | 
				
			||||||
			int loffset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			brelse(oepos.bh);
 | 
					 | 
				
			||||||
			oepos = epos;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* Steal a block from the extent being free'd */
 | 
								/* Steal a block from the extent being free'd */
 | 
				
			||||||
			epos.block.logicalBlockNum = eloc.logicalBlockNum;
 | 
								udf_setup_indirect_aext(table, eloc.logicalBlockNum,
 | 
				
			||||||
 | 
											&epos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			eloc.logicalBlockNum++;
 | 
								eloc.logicalBlockNum++;
 | 
				
			||||||
			elen -= sb->s_blocksize;
 | 
								elen -= sb->s_blocksize;
 | 
				
			||||||
 | 
					 | 
				
			||||||
			epos.bh = udf_tread(sb,
 | 
					 | 
				
			||||||
					udf_get_lb_pblock(sb, &epos.block, 0));
 | 
					 | 
				
			||||||
			if (!epos.bh) {
 | 
					 | 
				
			||||||
				brelse(oepos.bh);
 | 
					 | 
				
			||||||
				goto error_return;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			aed = (struct allocExtDesc *)(epos.bh->b_data);
 | 
					 | 
				
			||||||
			aed->previousAllocExtLocation =
 | 
					 | 
				
			||||||
				cpu_to_le32(oepos.block.logicalBlockNum);
 | 
					 | 
				
			||||||
			if (epos.offset + adsize > sb->s_blocksize) {
 | 
					 | 
				
			||||||
				loffset = epos.offset;
 | 
					 | 
				
			||||||
				aed->lengthAllocDescs = cpu_to_le32(adsize);
 | 
					 | 
				
			||||||
				sptr = iinfo->i_ext.i_data + epos.offset
 | 
					 | 
				
			||||||
								- adsize;
 | 
					 | 
				
			||||||
				dptr = epos.bh->b_data +
 | 
					 | 
				
			||||||
					sizeof(struct allocExtDesc);
 | 
					 | 
				
			||||||
				memcpy(dptr, sptr, adsize);
 | 
					 | 
				
			||||||
				epos.offset = sizeof(struct allocExtDesc) +
 | 
					 | 
				
			||||||
						adsize;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				loffset = epos.offset + adsize;
 | 
					 | 
				
			||||||
				aed->lengthAllocDescs = cpu_to_le32(0);
 | 
					 | 
				
			||||||
				if (oepos.bh) {
 | 
					 | 
				
			||||||
					sptr = oepos.bh->b_data + epos.offset;
 | 
					 | 
				
			||||||
					aed = (struct allocExtDesc *)
 | 
					 | 
				
			||||||
						oepos.bh->b_data;
 | 
					 | 
				
			||||||
					le32_add_cpu(&aed->lengthAllocDescs,
 | 
					 | 
				
			||||||
							adsize);
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					sptr = iinfo->i_ext.i_data +
 | 
					 | 
				
			||||||
								epos.offset;
 | 
					 | 
				
			||||||
					iinfo->i_lenAlloc += adsize;
 | 
					 | 
				
			||||||
					mark_inode_dirty(table);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				epos.offset = sizeof(struct allocExtDesc);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (sbi->s_udfrev >= 0x0200)
 | 
					 | 
				
			||||||
				udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
 | 
					 | 
				
			||||||
					    3, 1, epos.block.logicalBlockNum,
 | 
					 | 
				
			||||||
					    sizeof(struct tag));
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
 | 
					 | 
				
			||||||
					    2, 1, epos.block.logicalBlockNum,
 | 
					 | 
				
			||||||
					    sizeof(struct tag));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			switch (iinfo->i_alloc_type) {
 | 
					 | 
				
			||||||
			case ICBTAG_FLAG_AD_SHORT:
 | 
					 | 
				
			||||||
				sad = (struct short_ad *)sptr;
 | 
					 | 
				
			||||||
				sad->extLength = cpu_to_le32(
 | 
					 | 
				
			||||||
					EXT_NEXT_EXTENT_ALLOCDECS |
 | 
					 | 
				
			||||||
					sb->s_blocksize);
 | 
					 | 
				
			||||||
				sad->extPosition =
 | 
					 | 
				
			||||||
					cpu_to_le32(epos.block.logicalBlockNum);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case ICBTAG_FLAG_AD_LONG:
 | 
					 | 
				
			||||||
				lad = (struct long_ad *)sptr;
 | 
					 | 
				
			||||||
				lad->extLength = cpu_to_le32(
 | 
					 | 
				
			||||||
					EXT_NEXT_EXTENT_ALLOCDECS |
 | 
					 | 
				
			||||||
					sb->s_blocksize);
 | 
					 | 
				
			||||||
				lad->extLocation =
 | 
					 | 
				
			||||||
					cpu_to_lelb(epos.block);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (oepos.bh) {
 | 
					 | 
				
			||||||
				udf_update_tag(oepos.bh->b_data, loffset);
 | 
					 | 
				
			||||||
				mark_buffer_dirty(oepos.bh);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				mark_inode_dirty(table);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* It's possible that stealing the block emptied the extent */
 | 
							/* It's possible that stealing the block emptied the extent */
 | 
				
			||||||
		if (elen) {
 | 
							if (elen)
 | 
				
			||||||
			udf_write_aext(table, &epos, &eloc, elen, 1);
 | 
								__udf_add_aext(table, &epos, &eloc, elen, 1);
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!epos.bh) {
 | 
					 | 
				
			||||||
				iinfo->i_lenAlloc += adsize;
 | 
					 | 
				
			||||||
				mark_inode_dirty(table);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				aed = (struct allocExtDesc *)epos.bh->b_data;
 | 
					 | 
				
			||||||
				le32_add_cpu(&aed->lengthAllocDescs, adsize);
 | 
					 | 
				
			||||||
				udf_update_tag(epos.bh->b_data, epos.offset);
 | 
					 | 
				
			||||||
				mark_buffer_dirty(epos.bh);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brelse(epos.bh);
 | 
						brelse(epos.bh);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										215
									
								
								fs/udf/inode.c
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								fs/udf/inode.c
									
									
									
									
									
								
							| 
						 | 
					@ -1866,112 +1866,102 @@ struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino,
 | 
				
			||||||
	return inode;
 | 
						return inode;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int udf_add_aext(struct inode *inode, struct extent_position *epos,
 | 
					int udf_setup_indirect_aext(struct inode *inode, int block,
 | 
				
			||||||
 | 
								    struct extent_position *epos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct super_block *sb = inode->i_sb;
 | 
				
			||||||
 | 
						struct buffer_head *bh;
 | 
				
			||||||
 | 
						struct allocExtDesc *aed;
 | 
				
			||||||
 | 
						struct extent_position nepos;
 | 
				
			||||||
 | 
						struct kernel_lb_addr neloc;
 | 
				
			||||||
 | 
						int ver, adsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
 | 
				
			||||||
 | 
							adsize = sizeof(struct short_ad);
 | 
				
			||||||
 | 
						else if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_LONG)
 | 
				
			||||||
 | 
							adsize = sizeof(struct long_ad);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						neloc.logicalBlockNum = block;
 | 
				
			||||||
 | 
						neloc.partitionReferenceNum = epos->block.partitionReferenceNum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bh = udf_tgetblk(sb, udf_get_lb_pblock(sb, &neloc, 0));
 | 
				
			||||||
 | 
						if (!bh)
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
						lock_buffer(bh);
 | 
				
			||||||
 | 
						memset(bh->b_data, 0x00, sb->s_blocksize);
 | 
				
			||||||
 | 
						set_buffer_uptodate(bh);
 | 
				
			||||||
 | 
						unlock_buffer(bh);
 | 
				
			||||||
 | 
						mark_buffer_dirty_inode(bh, inode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aed = (struct allocExtDesc *)(bh->b_data);
 | 
				
			||||||
 | 
						if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) {
 | 
				
			||||||
 | 
							aed->previousAllocExtLocation =
 | 
				
			||||||
 | 
									cpu_to_le32(epos->block.logicalBlockNum);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						aed->lengthAllocDescs = cpu_to_le32(0);
 | 
				
			||||||
 | 
						if (UDF_SB(sb)->s_udfrev >= 0x0200)
 | 
				
			||||||
 | 
							ver = 3;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ver = 2;
 | 
				
			||||||
 | 
						udf_new_tag(bh->b_data, TAG_IDENT_AED, ver, 1, block,
 | 
				
			||||||
 | 
							    sizeof(struct tag));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nepos.block = neloc;
 | 
				
			||||||
 | 
						nepos.offset = sizeof(struct allocExtDesc);
 | 
				
			||||||
 | 
						nepos.bh = bh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Do we have to copy current last extent to make space for indirect
 | 
				
			||||||
 | 
						 * one?
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (epos->offset + adsize > sb->s_blocksize) {
 | 
				
			||||||
 | 
							struct kernel_lb_addr cp_loc;
 | 
				
			||||||
 | 
							uint32_t cp_len;
 | 
				
			||||||
 | 
							int cp_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							epos->offset -= adsize;
 | 
				
			||||||
 | 
							cp_type = udf_current_aext(inode, epos, &cp_loc, &cp_len, 0);
 | 
				
			||||||
 | 
							cp_len |= ((uint32_t)cp_type) << 30;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							__udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1);
 | 
				
			||||||
 | 
							udf_write_aext(inode, epos, &nepos.block,
 | 
				
			||||||
 | 
								       sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							__udf_add_aext(inode, epos, &nepos.block,
 | 
				
			||||||
 | 
								       sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						brelse(epos->bh);
 | 
				
			||||||
 | 
						*epos = nepos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Append extent at the given position - should be the first free one in inode
 | 
				
			||||||
 | 
					 * / indirect extent. This function assumes there is enough space in the inode
 | 
				
			||||||
 | 
					 * or indirect extent. Use udf_add_aext() if you didn't check for this before.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int __udf_add_aext(struct inode *inode, struct extent_position *epos,
 | 
				
			||||||
		   struct kernel_lb_addr *eloc, uint32_t elen, int inc)
 | 
							   struct kernel_lb_addr *eloc, uint32_t elen, int inc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int adsize;
 | 
					 | 
				
			||||||
	struct short_ad *sad = NULL;
 | 
					 | 
				
			||||||
	struct long_ad *lad = NULL;
 | 
					 | 
				
			||||||
	struct allocExtDesc *aed;
 | 
					 | 
				
			||||||
	uint8_t *ptr;
 | 
					 | 
				
			||||||
	struct udf_inode_info *iinfo = UDF_I(inode);
 | 
						struct udf_inode_info *iinfo = UDF_I(inode);
 | 
				
			||||||
 | 
						struct allocExtDesc *aed;
 | 
				
			||||||
	if (!epos->bh)
 | 
						int adsize;
 | 
				
			||||||
		ptr = iinfo->i_ext.i_data + epos->offset -
 | 
					 | 
				
			||||||
			udf_file_entry_alloc_offset(inode) +
 | 
					 | 
				
			||||||
			iinfo->i_lenEAttr;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		ptr = epos->bh->b_data + epos->offset;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
 | 
						if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
 | 
				
			||||||
		adsize = sizeof(struct short_ad);
 | 
							adsize = sizeof(struct short_ad);
 | 
				
			||||||
	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
 | 
						else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
 | 
				
			||||||
		adsize = sizeof(struct long_ad);
 | 
							adsize = sizeof(struct long_ad);
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) {
 | 
						if (!epos->bh) {
 | 
				
			||||||
		unsigned char *sptr, *dptr;
 | 
							WARN_ON(iinfo->i_lenAlloc !=
 | 
				
			||||||
		struct buffer_head *nbh;
 | 
								epos->offset - udf_file_entry_alloc_offset(inode));
 | 
				
			||||||
		int err, loffset;
 | 
					 | 
				
			||||||
		struct kernel_lb_addr obloc = epos->block;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
 | 
					 | 
				
			||||||
						obloc.partitionReferenceNum,
 | 
					 | 
				
			||||||
						obloc.logicalBlockNum, &err);
 | 
					 | 
				
			||||||
		if (!epos->block.logicalBlockNum)
 | 
					 | 
				
			||||||
			return -ENOSPC;
 | 
					 | 
				
			||||||
		nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
 | 
					 | 
				
			||||||
								 &epos->block,
 | 
					 | 
				
			||||||
								 0));
 | 
					 | 
				
			||||||
		if (!nbh)
 | 
					 | 
				
			||||||
			return -EIO;
 | 
					 | 
				
			||||||
		lock_buffer(nbh);
 | 
					 | 
				
			||||||
		memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
 | 
					 | 
				
			||||||
		set_buffer_uptodate(nbh);
 | 
					 | 
				
			||||||
		unlock_buffer(nbh);
 | 
					 | 
				
			||||||
		mark_buffer_dirty_inode(nbh, inode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		aed = (struct allocExtDesc *)(nbh->b_data);
 | 
					 | 
				
			||||||
		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
 | 
					 | 
				
			||||||
			aed->previousAllocExtLocation =
 | 
					 | 
				
			||||||
					cpu_to_le32(obloc.logicalBlockNum);
 | 
					 | 
				
			||||||
		if (epos->offset + adsize > inode->i_sb->s_blocksize) {
 | 
					 | 
				
			||||||
			loffset = epos->offset;
 | 
					 | 
				
			||||||
			aed->lengthAllocDescs = cpu_to_le32(adsize);
 | 
					 | 
				
			||||||
			sptr = ptr - adsize;
 | 
					 | 
				
			||||||
			dptr = nbh->b_data + sizeof(struct allocExtDesc);
 | 
					 | 
				
			||||||
			memcpy(dptr, sptr, adsize);
 | 
					 | 
				
			||||||
			epos->offset = sizeof(struct allocExtDesc) + adsize;
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
			loffset = epos->offset + adsize;
 | 
					 | 
				
			||||||
			aed->lengthAllocDescs = cpu_to_le32(0);
 | 
					 | 
				
			||||||
			sptr = ptr;
 | 
					 | 
				
			||||||
			epos->offset = sizeof(struct allocExtDesc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (epos->bh) {
 | 
					 | 
				
			||||||
		aed = (struct allocExtDesc *)epos->bh->b_data;
 | 
							aed = (struct allocExtDesc *)epos->bh->b_data;
 | 
				
			||||||
				le32_add_cpu(&aed->lengthAllocDescs, adsize);
 | 
							WARN_ON(le32_to_cpu(aed->lengthAllocDescs) !=
 | 
				
			||||||
			} else {
 | 
								epos->offset - sizeof(struct allocExtDesc));
 | 
				
			||||||
				iinfo->i_lenAlloc += adsize;
 | 
							WARN_ON(epos->offset + adsize > inode->i_sb->s_blocksize);
 | 
				
			||||||
				mark_inode_dirty(inode);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200)
 | 
					 | 
				
			||||||
			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
 | 
					 | 
				
			||||||
				    epos->block.logicalBlockNum, sizeof(struct tag));
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
 | 
					 | 
				
			||||||
				    epos->block.logicalBlockNum, sizeof(struct tag));
 | 
					 | 
				
			||||||
		switch (iinfo->i_alloc_type) {
 | 
					 | 
				
			||||||
		case ICBTAG_FLAG_AD_SHORT:
 | 
					 | 
				
			||||||
			sad = (struct short_ad *)sptr;
 | 
					 | 
				
			||||||
			sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
 | 
					 | 
				
			||||||
						     inode->i_sb->s_blocksize);
 | 
					 | 
				
			||||||
			sad->extPosition =
 | 
					 | 
				
			||||||
				cpu_to_le32(epos->block.logicalBlockNum);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case ICBTAG_FLAG_AD_LONG:
 | 
					 | 
				
			||||||
			lad = (struct long_ad *)sptr;
 | 
					 | 
				
			||||||
			lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
 | 
					 | 
				
			||||||
						     inode->i_sb->s_blocksize);
 | 
					 | 
				
			||||||
			lad->extLocation = cpu_to_lelb(epos->block);
 | 
					 | 
				
			||||||
			memset(lad->impUse, 0x00, sizeof(lad->impUse));
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (epos->bh) {
 | 
					 | 
				
			||||||
			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
 | 
					 | 
				
			||||||
			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
 | 
					 | 
				
			||||||
				udf_update_tag(epos->bh->b_data, loffset);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				udf_update_tag(epos->bh->b_data,
 | 
					 | 
				
			||||||
						sizeof(struct allocExtDesc));
 | 
					 | 
				
			||||||
			mark_buffer_dirty_inode(epos->bh, inode);
 | 
					 | 
				
			||||||
			brelse(epos->bh);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			mark_inode_dirty(inode);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		epos->bh = nbh;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	udf_write_aext(inode, epos, eloc, elen, inc);
 | 
						udf_write_aext(inode, epos, eloc, elen, inc);
 | 
				
			||||||
| 
						 | 
					@ -1995,6 +1985,41 @@ int udf_add_aext(struct inode *inode, struct extent_position *epos,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Append extent at given position - should be the first free one in inode
 | 
				
			||||||
 | 
					 * / indirect extent. Takes care of allocating and linking indirect blocks.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int udf_add_aext(struct inode *inode, struct extent_position *epos,
 | 
				
			||||||
 | 
							 struct kernel_lb_addr *eloc, uint32_t elen, int inc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int adsize;
 | 
				
			||||||
 | 
						struct super_block *sb = inode->i_sb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
 | 
				
			||||||
 | 
							adsize = sizeof(struct short_ad);
 | 
				
			||||||
 | 
						else if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_LONG)
 | 
				
			||||||
 | 
							adsize = sizeof(struct long_ad);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (epos->offset + (2 * adsize) > sb->s_blocksize) {
 | 
				
			||||||
 | 
							int err;
 | 
				
			||||||
 | 
							int new_block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							new_block = udf_new_block(sb, NULL,
 | 
				
			||||||
 | 
										  epos->block.partitionReferenceNum,
 | 
				
			||||||
 | 
										  epos->block.logicalBlockNum, &err);
 | 
				
			||||||
 | 
							if (!new_block)
 | 
				
			||||||
 | 
								return -ENOSPC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = udf_setup_indirect_aext(inode, new_block, epos);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
 | 
								return err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return __udf_add_aext(inode, epos, eloc, elen, inc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void udf_write_aext(struct inode *inode, struct extent_position *epos,
 | 
					void udf_write_aext(struct inode *inode, struct extent_position *epos,
 | 
				
			||||||
		    struct kernel_lb_addr *eloc, uint32_t elen, int inc)
 | 
							    struct kernel_lb_addr *eloc, uint32_t elen, int inc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,6 +159,10 @@ extern int udf_write_inode(struct inode *, struct writeback_control *wbc);
 | 
				
			||||||
extern long udf_block_map(struct inode *, sector_t);
 | 
					extern long udf_block_map(struct inode *, sector_t);
 | 
				
			||||||
extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
 | 
					extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
 | 
				
			||||||
			 struct kernel_lb_addr *, uint32_t *, sector_t *);
 | 
								 struct kernel_lb_addr *, uint32_t *, sector_t *);
 | 
				
			||||||
 | 
					extern int udf_setup_indirect_aext(struct inode *inode, int block,
 | 
				
			||||||
 | 
									   struct extent_position *epos);
 | 
				
			||||||
 | 
					extern int __udf_add_aext(struct inode *inode, struct extent_position *epos,
 | 
				
			||||||
 | 
								  struct kernel_lb_addr *eloc, uint32_t elen, int inc);
 | 
				
			||||||
extern int udf_add_aext(struct inode *, struct extent_position *,
 | 
					extern int udf_add_aext(struct inode *, struct extent_position *,
 | 
				
			||||||
			struct kernel_lb_addr *, uint32_t, int);
 | 
								struct kernel_lb_addr *, uint32_t, int);
 | 
				
			||||||
extern void udf_write_aext(struct inode *, struct extent_position *,
 | 
					extern void udf_write_aext(struct inode *, struct extent_position *,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue