diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-12 16:22:50 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-12 16:22:50 -0800 | 
| commit | 83c0fb6500b13c9b7564fe453b76356dc58415d4 (patch) | |
| tree | fe4c449dabb67da76ea1f6045f490c044327a46b /fs | |
| parent | 11bfe2ea732c6499c46c4f3a63d567c05b9dbafd (diff) | |
| parent | 3a065fcf9efed42ba736da7be528f2d3dec4965a (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6:
  udf: use ext2_find_next_bit
  udf: Do not read inode before writing it
  udf: Fix unalloc space handling in udf_update_inode
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/udf/balloc.c | 49 | ||||
| -rw-r--r-- | fs/udf/inode.c | 34 | 
2 files changed, 18 insertions, 65 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index ccc3ad7242d4..19626e2491c4 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -31,55 +31,8 @@  #define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr)  #define udf_set_bit(nr, addr) ext2_set_bit(nr, addr)  #define udf_test_bit(nr, addr) ext2_test_bit(nr, addr) -#define udf_find_first_one_bit(addr, size) find_first_one_bit(addr, size)  #define udf_find_next_one_bit(addr, size, offset) \ -		find_next_one_bit(addr, size, offset) - -#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_t uint(BITS_PER_LONG) -#define uint(x) xuint(x) -#define xuint(x) __le ## x - -static inline int find_next_one_bit(void *addr, int size, int offset) -{ -	uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG); -	int result = offset & ~(BITS_PER_LONG - 1); -	unsigned long tmp; - -	if (offset >= size) -		return size; -	size -= result; -	offset &= (BITS_PER_LONG - 1); -	if (offset) { -		tmp = leBPL_to_cpup(p++); -		tmp &= ~0UL << offset; -		if (size < BITS_PER_LONG) -			goto found_first; -		if (tmp) -			goto found_middle; -		size -= BITS_PER_LONG; -		result += BITS_PER_LONG; -	} -	while (size & ~(BITS_PER_LONG - 1)) { -		tmp = leBPL_to_cpup(p++); -		if (tmp) -			goto found_middle; -		result += BITS_PER_LONG; -		size -= BITS_PER_LONG; -	} -	if (!size) -		return result; -	tmp = leBPL_to_cpup(p); -found_first: -	tmp &= ~0UL >> (BITS_PER_LONG - size); -found_middle: -	return result + ffz(~tmp); -} - -#define find_first_one_bit(addr, size)\ -	find_next_one_bit((addr), (size), 0) +		ext2_find_next_bit(addr, size, offset)  static int read_block_bitmap(struct super_block *sb,  			     struct udf_bitmap *bitmap, unsigned int block, diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 86f0ccb80765..bb863fe579ac 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1408,20 +1408,19 @@ static int udf_update_inode(struct inode *inode, int do_sync)  	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;  	struct udf_inode_info *iinfo = UDF_I(inode); -	bh = udf_tread(inode->i_sb, -			udf_get_lb_pblock(inode->i_sb, -					  &iinfo->i_location, 0)); +	bh = udf_tgetblk(inode->i_sb, +			udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0));  	if (!bh) { -		udf_debug("bread failure\n"); -		return -EIO; +		udf_debug("getblk failure\n"); +		return -ENOMEM;  	} -	memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); - +	lock_buffer(bh); +	memset(bh->b_data, 0, inode->i_sb->s_blocksize);  	fe = (struct fileEntry *)bh->b_data;  	efe = (struct extendedFileEntry *)bh->b_data; -	if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { +	if (iinfo->i_use) {  		struct unallocSpaceEntry *use =  			(struct unallocSpaceEntry *)bh->b_data; @@ -1429,20 +1428,18 @@ static int udf_update_inode(struct inode *inode, int do_sync)  		memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),  		       iinfo->i_ext.i_data, inode->i_sb->s_blocksize -  					sizeof(struct unallocSpaceEntry)); +		use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE); +		use->descTag.tagLocation = +				cpu_to_le32(iinfo->i_location.logicalBlockNum);  		crclen = sizeof(struct unallocSpaceEntry) +  				iinfo->i_lenAlloc - sizeof(struct tag); -		use->descTag.tagLocation = cpu_to_le32( -						iinfo->i_location. -							logicalBlockNum);  		use->descTag.descCRCLength = cpu_to_le16(crclen);  		use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +  							   sizeof(struct tag),  							   crclen));  		use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); -		mark_buffer_dirty(bh); -		brelse(bh); -		return err; +		goto out;  	}  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) @@ -1597,18 +1594,21 @@ static int udf_update_inode(struct inode *inode, int do_sync)  	fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number);  	fe->descTag.tagLocation = cpu_to_le32(  					iinfo->i_location.logicalBlockNum); -	crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - -								sizeof(struct tag); +	crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag);  	fe->descTag.descCRCLength = cpu_to_le16(crclen);  	fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag),  						  crclen));  	fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); +out: +	set_buffer_uptodate(bh); +	unlock_buffer(bh); +  	/* write the data blocks */  	mark_buffer_dirty(bh);  	if (do_sync) {  		sync_dirty_buffer(bh); -		if (buffer_req(bh) && !buffer_uptodate(bh)) { +		if (buffer_write_io_error(bh)) {  			printk(KERN_WARNING "IO error syncing udf inode "  				"[%s:%08lx]\n", inode->i_sb->s_id,  				inode->i_ino);  | 
