diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-12 19:22:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-12 19:22:50 -0500 |
commit | 83c0fb6500b13c9b7564fe453b76356dc58415d4 (patch) | |
tree | fe4c449dabb67da76ea1f6045f490c044327a46b | |
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
-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 @@ | |||
31 | #define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr) | 31 | #define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr) |
32 | #define udf_set_bit(nr, addr) ext2_set_bit(nr, addr) | 32 | #define udf_set_bit(nr, addr) ext2_set_bit(nr, addr) |
33 | #define udf_test_bit(nr, addr) ext2_test_bit(nr, addr) | 33 | #define udf_test_bit(nr, addr) ext2_test_bit(nr, addr) |
34 | #define udf_find_first_one_bit(addr, size) find_first_one_bit(addr, size) | ||
35 | #define udf_find_next_one_bit(addr, size, offset) \ | 34 | #define udf_find_next_one_bit(addr, size, offset) \ |
36 | find_next_one_bit(addr, size, offset) | 35 | ext2_find_next_bit(addr, size, offset) |
37 | |||
38 | #define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x) | ||
39 | #define leNUM_to_cpup(x, y) xleNUM_to_cpup(x, y) | ||
40 | #define xleNUM_to_cpup(x, y) (le ## x ## _to_cpup(y)) | ||
41 | #define uintBPL_t uint(BITS_PER_LONG) | ||
42 | #define uint(x) xuint(x) | ||
43 | #define xuint(x) __le ## x | ||
44 | |||
45 | static inline int find_next_one_bit(void *addr, int size, int offset) | ||
46 | { | ||
47 | uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG); | ||
48 | int result = offset & ~(BITS_PER_LONG - 1); | ||
49 | unsigned long tmp; | ||
50 | |||
51 | if (offset >= size) | ||
52 | return size; | ||
53 | size -= result; | ||
54 | offset &= (BITS_PER_LONG - 1); | ||
55 | if (offset) { | ||
56 | tmp = leBPL_to_cpup(p++); | ||
57 | tmp &= ~0UL << offset; | ||
58 | if (size < BITS_PER_LONG) | ||
59 | goto found_first; | ||
60 | if (tmp) | ||
61 | goto found_middle; | ||
62 | size -= BITS_PER_LONG; | ||
63 | result += BITS_PER_LONG; | ||
64 | } | ||
65 | while (size & ~(BITS_PER_LONG - 1)) { | ||
66 | tmp = leBPL_to_cpup(p++); | ||
67 | if (tmp) | ||
68 | goto found_middle; | ||
69 | result += BITS_PER_LONG; | ||
70 | size -= BITS_PER_LONG; | ||
71 | } | ||
72 | if (!size) | ||
73 | return result; | ||
74 | tmp = leBPL_to_cpup(p); | ||
75 | found_first: | ||
76 | tmp &= ~0UL >> (BITS_PER_LONG - size); | ||
77 | found_middle: | ||
78 | return result + ffz(~tmp); | ||
79 | } | ||
80 | |||
81 | #define find_first_one_bit(addr, size)\ | ||
82 | find_next_one_bit((addr), (size), 0) | ||
83 | 36 | ||
84 | static int read_block_bitmap(struct super_block *sb, | 37 | static int read_block_bitmap(struct super_block *sb, |
85 | struct udf_bitmap *bitmap, unsigned int block, | 38 | 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) | |||
1408 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 1408 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
1409 | struct udf_inode_info *iinfo = UDF_I(inode); | 1409 | struct udf_inode_info *iinfo = UDF_I(inode); |
1410 | 1410 | ||
1411 | bh = udf_tread(inode->i_sb, | 1411 | bh = udf_tgetblk(inode->i_sb, |
1412 | udf_get_lb_pblock(inode->i_sb, | 1412 | udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); |
1413 | &iinfo->i_location, 0)); | ||
1414 | if (!bh) { | 1413 | if (!bh) { |
1415 | udf_debug("bread failure\n"); | 1414 | udf_debug("getblk failure\n"); |
1416 | return -EIO; | 1415 | return -ENOMEM; |
1417 | } | 1416 | } |
1418 | 1417 | ||
1419 | memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); | 1418 | lock_buffer(bh); |
1420 | 1419 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | |
1421 | fe = (struct fileEntry *)bh->b_data; | 1420 | fe = (struct fileEntry *)bh->b_data; |
1422 | efe = (struct extendedFileEntry *)bh->b_data; | 1421 | efe = (struct extendedFileEntry *)bh->b_data; |
1423 | 1422 | ||
1424 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { | 1423 | if (iinfo->i_use) { |
1425 | struct unallocSpaceEntry *use = | 1424 | struct unallocSpaceEntry *use = |
1426 | (struct unallocSpaceEntry *)bh->b_data; | 1425 | (struct unallocSpaceEntry *)bh->b_data; |
1427 | 1426 | ||
@@ -1429,20 +1428,18 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1429 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), | 1428 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), |
1430 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - | 1429 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - |
1431 | sizeof(struct unallocSpaceEntry)); | 1430 | sizeof(struct unallocSpaceEntry)); |
1431 | use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE); | ||
1432 | use->descTag.tagLocation = | ||
1433 | cpu_to_le32(iinfo->i_location.logicalBlockNum); | ||
1432 | crclen = sizeof(struct unallocSpaceEntry) + | 1434 | crclen = sizeof(struct unallocSpaceEntry) + |
1433 | iinfo->i_lenAlloc - sizeof(struct tag); | 1435 | iinfo->i_lenAlloc - sizeof(struct tag); |
1434 | use->descTag.tagLocation = cpu_to_le32( | ||
1435 | iinfo->i_location. | ||
1436 | logicalBlockNum); | ||
1437 | use->descTag.descCRCLength = cpu_to_le16(crclen); | 1436 | use->descTag.descCRCLength = cpu_to_le16(crclen); |
1438 | use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + | 1437 | use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + |
1439 | sizeof(struct tag), | 1438 | sizeof(struct tag), |
1440 | crclen)); | 1439 | crclen)); |
1441 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); | 1440 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); |
1442 | 1441 | ||
1443 | mark_buffer_dirty(bh); | 1442 | goto out; |
1444 | brelse(bh); | ||
1445 | return err; | ||
1446 | } | 1443 | } |
1447 | 1444 | ||
1448 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) | 1445 | 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) | |||
1597 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); | 1594 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); |
1598 | fe->descTag.tagLocation = cpu_to_le32( | 1595 | fe->descTag.tagLocation = cpu_to_le32( |
1599 | iinfo->i_location.logicalBlockNum); | 1596 | iinfo->i_location.logicalBlockNum); |
1600 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - | 1597 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag); |
1601 | sizeof(struct tag); | ||
1602 | fe->descTag.descCRCLength = cpu_to_le16(crclen); | 1598 | fe->descTag.descCRCLength = cpu_to_le16(crclen); |
1603 | fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag), | 1599 | fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag), |
1604 | crclen)); | 1600 | crclen)); |
1605 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); | 1601 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); |
1606 | 1602 | ||
1603 | out: | ||
1604 | set_buffer_uptodate(bh); | ||
1605 | unlock_buffer(bh); | ||
1606 | |||
1607 | /* write the data blocks */ | 1607 | /* write the data blocks */ |
1608 | mark_buffer_dirty(bh); | 1608 | mark_buffer_dirty(bh); |
1609 | if (do_sync) { | 1609 | if (do_sync) { |
1610 | sync_dirty_buffer(bh); | 1610 | sync_dirty_buffer(bh); |
1611 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | 1611 | if (buffer_write_io_error(bh)) { |
1612 | printk(KERN_WARNING "IO error syncing udf inode " | 1612 | printk(KERN_WARNING "IO error syncing udf inode " |
1613 | "[%s:%08lx]\n", inode->i_sb->s_id, | 1613 | "[%s:%08lx]\n", inode->i_sb->s_id, |
1614 | inode->i_ino); | 1614 | inode->i_ino); |