diff options
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r-- | fs/udf/inode.c | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 6d24c2c63f93..8a3fbd177cab 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/pagemap.h> | 36 | #include <linux/pagemap.h> |
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
39 | #include <linux/quotaops.h> | ||
39 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
40 | #include <linux/crc-itu-t.h> | 41 | #include <linux/crc-itu-t.h> |
41 | 42 | ||
@@ -70,6 +71,9 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | |||
70 | 71 | ||
71 | void udf_delete_inode(struct inode *inode) | 72 | void udf_delete_inode(struct inode *inode) |
72 | { | 73 | { |
74 | if (!is_bad_inode(inode)) | ||
75 | dquot_initialize(inode); | ||
76 | |||
73 | truncate_inode_pages(&inode->i_data, 0); | 77 | truncate_inode_pages(&inode->i_data, 0); |
74 | 78 | ||
75 | if (is_bad_inode(inode)) | 79 | if (is_bad_inode(inode)) |
@@ -97,15 +101,19 @@ no_delete: | |||
97 | */ | 101 | */ |
98 | void udf_clear_inode(struct inode *inode) | 102 | void udf_clear_inode(struct inode *inode) |
99 | { | 103 | { |
100 | struct udf_inode_info *iinfo; | 104 | struct udf_inode_info *iinfo = UDF_I(inode); |
101 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { | 105 | |
102 | lock_kernel(); | 106 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && |
103 | udf_truncate_tail_extent(inode); | 107 | inode->i_size != iinfo->i_lenExtents) { |
104 | unlock_kernel(); | 108 | printk(KERN_WARNING "UDF-fs (%s): Inode %lu (mode %o) has " |
105 | write_inode_now(inode, 0); | 109 | "inode size %llu different from extent length %llu. " |
106 | invalidate_inode_buffers(inode); | 110 | "Filesystem need not be standards compliant.\n", |
111 | inode->i_sb->s_id, inode->i_ino, inode->i_mode, | ||
112 | (unsigned long long)inode->i_size, | ||
113 | (unsigned long long)iinfo->i_lenExtents); | ||
107 | } | 114 | } |
108 | iinfo = UDF_I(inode); | 115 | |
116 | dquot_drop(inode); | ||
109 | kfree(iinfo->i_ext.i_data); | 117 | kfree(iinfo->i_ext.i_data); |
110 | iinfo->i_ext.i_data = NULL; | 118 | iinfo->i_ext.i_data = NULL; |
111 | } | 119 | } |
@@ -198,7 +206,6 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, | |||
198 | int newblock; | 206 | int newblock; |
199 | struct buffer_head *dbh = NULL; | 207 | struct buffer_head *dbh = NULL; |
200 | struct kernel_lb_addr eloc; | 208 | struct kernel_lb_addr eloc; |
201 | uint32_t elen; | ||
202 | uint8_t alloctype; | 209 | uint8_t alloctype; |
203 | struct extent_position epos; | 210 | struct extent_position epos; |
204 | 211 | ||
@@ -273,12 +280,11 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, | |||
273 | eloc.logicalBlockNum = *block; | 280 | eloc.logicalBlockNum = *block; |
274 | eloc.partitionReferenceNum = | 281 | eloc.partitionReferenceNum = |
275 | iinfo->i_location.partitionReferenceNum; | 282 | iinfo->i_location.partitionReferenceNum; |
276 | elen = inode->i_sb->s_blocksize; | 283 | iinfo->i_lenExtents = inode->i_size; |
277 | iinfo->i_lenExtents = elen; | ||
278 | epos.bh = NULL; | 284 | epos.bh = NULL; |
279 | epos.block = iinfo->i_location; | 285 | epos.block = iinfo->i_location; |
280 | epos.offset = udf_file_entry_alloc_offset(inode); | 286 | epos.offset = udf_file_entry_alloc_offset(inode); |
281 | udf_add_aext(inode, &epos, &eloc, elen, 0); | 287 | udf_add_aext(inode, &epos, &eloc, inode->i_size, 0); |
282 | /* UniqueID stuff */ | 288 | /* UniqueID stuff */ |
283 | 289 | ||
284 | brelse(epos.bh); | 290 | brelse(epos.bh); |
@@ -1308,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1308 | break; | 1314 | break; |
1309 | case ICBTAG_FILE_TYPE_SYMLINK: | 1315 | case ICBTAG_FILE_TYPE_SYMLINK: |
1310 | inode->i_data.a_ops = &udf_symlink_aops; | 1316 | inode->i_data.a_ops = &udf_symlink_aops; |
1311 | inode->i_op = &page_symlink_inode_operations; | 1317 | inode->i_op = &udf_symlink_inode_operations; |
1312 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 1318 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
1313 | break; | 1319 | break; |
1314 | case ICBTAG_FILE_TYPE_MAIN: | 1320 | case ICBTAG_FILE_TYPE_MAIN: |
@@ -1373,12 +1379,12 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) | |||
1373 | return mode; | 1379 | return mode; |
1374 | } | 1380 | } |
1375 | 1381 | ||
1376 | int udf_write_inode(struct inode *inode, int sync) | 1382 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1377 | { | 1383 | { |
1378 | int ret; | 1384 | int ret; |
1379 | 1385 | ||
1380 | lock_kernel(); | 1386 | lock_kernel(); |
1381 | ret = udf_update_inode(inode, sync); | 1387 | ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1382 | unlock_kernel(); | 1388 | unlock_kernel(); |
1383 | 1389 | ||
1384 | return ret; | 1390 | return ret; |
@@ -1402,20 +1408,19 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1402 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 1408 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
1403 | struct udf_inode_info *iinfo = UDF_I(inode); | 1409 | struct udf_inode_info *iinfo = UDF_I(inode); |
1404 | 1410 | ||
1405 | bh = udf_tread(inode->i_sb, | 1411 | bh = udf_tgetblk(inode->i_sb, |
1406 | udf_get_lb_pblock(inode->i_sb, | 1412 | udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); |
1407 | &iinfo->i_location, 0)); | ||
1408 | if (!bh) { | 1413 | if (!bh) { |
1409 | udf_debug("bread failure\n"); | 1414 | udf_debug("getblk failure\n"); |
1410 | return -EIO; | 1415 | return -ENOMEM; |
1411 | } | 1416 | } |
1412 | 1417 | ||
1413 | memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); | 1418 | lock_buffer(bh); |
1414 | 1419 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | |
1415 | fe = (struct fileEntry *)bh->b_data; | 1420 | fe = (struct fileEntry *)bh->b_data; |
1416 | efe = (struct extendedFileEntry *)bh->b_data; | 1421 | efe = (struct extendedFileEntry *)bh->b_data; |
1417 | 1422 | ||
1418 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { | 1423 | if (iinfo->i_use) { |
1419 | struct unallocSpaceEntry *use = | 1424 | struct unallocSpaceEntry *use = |
1420 | (struct unallocSpaceEntry *)bh->b_data; | 1425 | (struct unallocSpaceEntry *)bh->b_data; |
1421 | 1426 | ||
@@ -1423,20 +1428,18 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1423 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), | 1428 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), |
1424 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - | 1429 | iinfo->i_ext.i_data, inode->i_sb->s_blocksize - |
1425 | 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); | ||
1426 | crclen = sizeof(struct unallocSpaceEntry) + | 1434 | crclen = sizeof(struct unallocSpaceEntry) + |
1427 | iinfo->i_lenAlloc - sizeof(struct tag); | 1435 | iinfo->i_lenAlloc - sizeof(struct tag); |
1428 | use->descTag.tagLocation = cpu_to_le32( | ||
1429 | iinfo->i_location. | ||
1430 | logicalBlockNum); | ||
1431 | use->descTag.descCRCLength = cpu_to_le16(crclen); | 1436 | use->descTag.descCRCLength = cpu_to_le16(crclen); |
1432 | 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 + |
1433 | sizeof(struct tag), | 1438 | sizeof(struct tag), |
1434 | crclen)); | 1439 | crclen)); |
1435 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); | 1440 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); |
1436 | 1441 | ||
1437 | mark_buffer_dirty(bh); | 1442 | goto out; |
1438 | brelse(bh); | ||
1439 | return err; | ||
1440 | } | 1443 | } |
1441 | 1444 | ||
1442 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) | 1445 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) |
@@ -1591,18 +1594,21 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1591 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); | 1594 | fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number); |
1592 | fe->descTag.tagLocation = cpu_to_le32( | 1595 | fe->descTag.tagLocation = cpu_to_le32( |
1593 | iinfo->i_location.logicalBlockNum); | 1596 | iinfo->i_location.logicalBlockNum); |
1594 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - | 1597 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag); |
1595 | sizeof(struct tag); | ||
1596 | fe->descTag.descCRCLength = cpu_to_le16(crclen); | 1598 | fe->descTag.descCRCLength = cpu_to_le16(crclen); |
1597 | 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), |
1598 | crclen)); | 1600 | crclen)); |
1599 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); | 1601 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); |
1600 | 1602 | ||
1603 | out: | ||
1604 | set_buffer_uptodate(bh); | ||
1605 | unlock_buffer(bh); | ||
1606 | |||
1601 | /* write the data blocks */ | 1607 | /* write the data blocks */ |
1602 | mark_buffer_dirty(bh); | 1608 | mark_buffer_dirty(bh); |
1603 | if (do_sync) { | 1609 | if (do_sync) { |
1604 | sync_dirty_buffer(bh); | 1610 | sync_dirty_buffer(bh); |
1605 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | 1611 | if (buffer_write_io_error(bh)) { |
1606 | printk(KERN_WARNING "IO error syncing udf inode " | 1612 | printk(KERN_WARNING "IO error syncing udf inode " |
1607 | "[%s:%08lx]\n", inode->i_sb->s_id, | 1613 | "[%s:%08lx]\n", inode->i_sb->s_id, |
1608 | inode->i_ino); | 1614 | inode->i_ino); |
@@ -1672,7 +1678,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1672 | return -1; | 1678 | return -1; |
1673 | 1679 | ||
1674 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { | 1680 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { |
1675 | char *sptr, *dptr; | 1681 | unsigned char *sptr, *dptr; |
1676 | struct buffer_head *nbh; | 1682 | struct buffer_head *nbh; |
1677 | int err, loffset; | 1683 | int err, loffset; |
1678 | struct kernel_lb_addr obloc = epos->block; | 1684 | struct kernel_lb_addr obloc = epos->block; |