.. | .. |
---|
57 | 57 | static int udf_sync_inode(struct inode *inode); |
---|
58 | 58 | static int udf_alloc_i_data(struct inode *inode, size_t size); |
---|
59 | 59 | static sector_t inode_getblk(struct inode *, sector_t, int *, int *); |
---|
60 | | -static int8_t udf_insert_aext(struct inode *, struct extent_position, |
---|
61 | | - struct kernel_lb_addr, uint32_t); |
---|
| 60 | +static int udf_insert_aext(struct inode *, struct extent_position, |
---|
| 61 | + struct kernel_lb_addr, uint32_t); |
---|
62 | 62 | static void udf_split_extents(struct inode *, int *, int, udf_pblk_t, |
---|
63 | 63 | struct kernel_long_ad *, int *); |
---|
64 | 64 | static void udf_prealloc_extents(struct inode *, int, int, |
---|
65 | 65 | struct kernel_long_ad *, int *); |
---|
66 | 66 | static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *); |
---|
67 | | -static void udf_update_extents(struct inode *, struct kernel_long_ad *, int, |
---|
68 | | - int, struct extent_position *); |
---|
| 67 | +static int udf_update_extents(struct inode *, struct kernel_long_ad *, int, |
---|
| 68 | + int, struct extent_position *); |
---|
69 | 69 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
---|
70 | 70 | |
---|
71 | 71 | static void __udf_clear_extent_cache(struct inode *inode) |
---|
.. | .. |
---|
438 | 438 | iinfo->i_next_alloc_goal++; |
---|
439 | 439 | } |
---|
440 | 440 | |
---|
| 441 | + /* |
---|
| 442 | + * Block beyond EOF and prealloc extents? Just discard preallocation |
---|
| 443 | + * as it is not useful and complicates things. |
---|
| 444 | + */ |
---|
| 445 | + if (((loff_t)block) << inode->i_blkbits >= iinfo->i_lenExtents) |
---|
| 446 | + udf_discard_prealloc(inode); |
---|
441 | 447 | udf_clear_extent_cache(inode); |
---|
442 | 448 | phys = inode_getblk(inode, block, &err, &new); |
---|
443 | 449 | if (!phys) |
---|
.. | .. |
---|
487 | 493 | uint32_t add; |
---|
488 | 494 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
---|
489 | 495 | struct super_block *sb = inode->i_sb; |
---|
490 | | - struct kernel_lb_addr prealloc_loc = {}; |
---|
491 | | - uint32_t prealloc_len = 0; |
---|
492 | 496 | struct udf_inode_info *iinfo; |
---|
493 | 497 | int err; |
---|
494 | 498 | |
---|
.. | .. |
---|
509 | 513 | ~(sb->s_blocksize - 1); |
---|
510 | 514 | } |
---|
511 | 515 | |
---|
512 | | - /* Last extent are just preallocated blocks? */ |
---|
513 | | - if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == |
---|
514 | | - EXT_NOT_RECORDED_ALLOCATED) { |
---|
515 | | - /* Save the extent so that we can reattach it to the end */ |
---|
516 | | - prealloc_loc = last_ext->extLocation; |
---|
517 | | - prealloc_len = last_ext->extLength; |
---|
518 | | - /* Mark the extent as a hole */ |
---|
519 | | - last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
---|
520 | | - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
---|
521 | | - last_ext->extLocation.logicalBlockNum = 0; |
---|
522 | | - last_ext->extLocation.partitionReferenceNum = 0; |
---|
523 | | - } |
---|
524 | | - |
---|
525 | 516 | /* Can we merge with the previous extent? */ |
---|
526 | 517 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == |
---|
527 | 518 | EXT_NOT_RECORDED_NOT_ALLOCATED) { |
---|
.. | .. |
---|
534 | 525 | } |
---|
535 | 526 | |
---|
536 | 527 | if (fake) { |
---|
537 | | - udf_add_aext(inode, last_pos, &last_ext->extLocation, |
---|
538 | | - last_ext->extLength, 1); |
---|
| 528 | + err = udf_add_aext(inode, last_pos, &last_ext->extLocation, |
---|
| 529 | + last_ext->extLength, 1); |
---|
| 530 | + if (err < 0) |
---|
| 531 | + goto out_err; |
---|
539 | 532 | count++; |
---|
540 | 533 | } else { |
---|
541 | 534 | struct kernel_lb_addr tmploc; |
---|
.. | .. |
---|
549 | 542 | * more extents, we may need to enter possible following |
---|
550 | 543 | * empty indirect extent. |
---|
551 | 544 | */ |
---|
552 | | - if (new_block_bytes || prealloc_len) |
---|
| 545 | + if (new_block_bytes) |
---|
553 | 546 | udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); |
---|
554 | 547 | } |
---|
555 | 548 | |
---|
.. | .. |
---|
569 | 562 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, |
---|
570 | 563 | last_ext->extLength, 1); |
---|
571 | 564 | if (err) |
---|
572 | | - return err; |
---|
| 565 | + goto out_err; |
---|
573 | 566 | count++; |
---|
574 | 567 | } |
---|
575 | 568 | if (new_block_bytes) { |
---|
.. | .. |
---|
578 | 571 | err = udf_add_aext(inode, last_pos, &last_ext->extLocation, |
---|
579 | 572 | last_ext->extLength, 1); |
---|
580 | 573 | if (err) |
---|
581 | | - return err; |
---|
| 574 | + goto out_err; |
---|
582 | 575 | count++; |
---|
583 | 576 | } |
---|
584 | 577 | |
---|
585 | 578 | out: |
---|
586 | | - /* Do we have some preallocated blocks saved? */ |
---|
587 | | - if (prealloc_len) { |
---|
588 | | - err = udf_add_aext(inode, last_pos, &prealloc_loc, |
---|
589 | | - prealloc_len, 1); |
---|
590 | | - if (err) |
---|
591 | | - return err; |
---|
592 | | - last_ext->extLocation = prealloc_loc; |
---|
593 | | - last_ext->extLength = prealloc_len; |
---|
594 | | - count++; |
---|
595 | | - } |
---|
596 | | - |
---|
597 | 579 | /* last_pos should point to the last written extent... */ |
---|
598 | 580 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
---|
599 | 581 | last_pos->offset -= sizeof(struct short_ad); |
---|
.. | .. |
---|
603 | 585 | return -EIO; |
---|
604 | 586 | |
---|
605 | 587 | return count; |
---|
| 588 | +out_err: |
---|
| 589 | + /* Remove extents we've created so far */ |
---|
| 590 | + udf_clear_extent_cache(inode); |
---|
| 591 | + udf_truncate_extents(inode); |
---|
| 592 | + return err; |
---|
606 | 593 | } |
---|
607 | 594 | |
---|
608 | 595 | /* Extend the final block of the file to final_block_len bytes */ |
---|
609 | 596 | static void udf_do_extend_final_block(struct inode *inode, |
---|
610 | 597 | struct extent_position *last_pos, |
---|
611 | 598 | struct kernel_long_ad *last_ext, |
---|
612 | | - uint32_t final_block_len) |
---|
| 599 | + uint32_t new_elen) |
---|
613 | 600 | { |
---|
614 | | - struct super_block *sb = inode->i_sb; |
---|
615 | 601 | uint32_t added_bytes; |
---|
616 | 602 | |
---|
617 | | - added_bytes = final_block_len - |
---|
618 | | - (last_ext->extLength & (sb->s_blocksize - 1)); |
---|
| 603 | + /* |
---|
| 604 | + * Extent already large enough? It may be already rounded up to block |
---|
| 605 | + * size... |
---|
| 606 | + */ |
---|
| 607 | + if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) |
---|
| 608 | + return; |
---|
| 609 | + added_bytes = new_elen - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); |
---|
619 | 610 | last_ext->extLength += added_bytes; |
---|
620 | 611 | UDF_I(inode)->i_lenExtents += added_bytes; |
---|
621 | 612 | |
---|
.. | .. |
---|
632 | 623 | int8_t etype; |
---|
633 | 624 | struct super_block *sb = inode->i_sb; |
---|
634 | 625 | sector_t first_block = newsize >> sb->s_blocksize_bits, offset; |
---|
635 | | - unsigned long partial_final_block; |
---|
| 626 | + loff_t new_elen; |
---|
636 | 627 | int adsize; |
---|
637 | 628 | struct udf_inode_info *iinfo = UDF_I(inode); |
---|
638 | 629 | struct kernel_long_ad extent; |
---|
639 | 630 | int err = 0; |
---|
640 | | - int within_final_block; |
---|
| 631 | + bool within_last_ext; |
---|
641 | 632 | |
---|
642 | 633 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
---|
643 | 634 | adsize = sizeof(struct short_ad); |
---|
.. | .. |
---|
646 | 637 | else |
---|
647 | 638 | BUG(); |
---|
648 | 639 | |
---|
| 640 | + /* |
---|
| 641 | + * When creating hole in file, just don't bother with preserving |
---|
| 642 | + * preallocation. It likely won't be very useful anyway. |
---|
| 643 | + */ |
---|
| 644 | + udf_discard_prealloc(inode); |
---|
| 645 | + |
---|
649 | 646 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
---|
650 | | - within_final_block = (etype != -1); |
---|
| 647 | + within_last_ext = (etype != -1); |
---|
| 648 | + /* We don't expect extents past EOF... */ |
---|
| 649 | + WARN_ON_ONCE(within_last_ext && |
---|
| 650 | + elen > ((loff_t)offset + 1) << inode->i_blkbits); |
---|
651 | 651 | |
---|
652 | 652 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || |
---|
653 | 653 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { |
---|
.. | .. |
---|
663 | 663 | extent.extLength |= etype << 30; |
---|
664 | 664 | } |
---|
665 | 665 | |
---|
666 | | - partial_final_block = newsize & (sb->s_blocksize - 1); |
---|
| 666 | + new_elen = ((loff_t)offset << inode->i_blkbits) | |
---|
| 667 | + (newsize & (sb->s_blocksize - 1)); |
---|
667 | 668 | |
---|
668 | 669 | /* File has extent covering the new size (could happen when extending |
---|
669 | 670 | * inside a block)? |
---|
670 | 671 | */ |
---|
671 | | - if (within_final_block) { |
---|
| 672 | + if (within_last_ext) { |
---|
672 | 673 | /* Extending file within the last file block */ |
---|
673 | | - udf_do_extend_final_block(inode, &epos, &extent, |
---|
674 | | - partial_final_block); |
---|
| 674 | + udf_do_extend_final_block(inode, &epos, &extent, new_elen); |
---|
675 | 675 | } else { |
---|
676 | | - loff_t add = ((loff_t)offset << sb->s_blocksize_bits) | |
---|
677 | | - partial_final_block; |
---|
678 | | - err = udf_do_extend_file(inode, &epos, &extent, add); |
---|
| 676 | + err = udf_do_extend_file(inode, &epos, &extent, new_elen); |
---|
679 | 677 | } |
---|
680 | 678 | |
---|
681 | 679 | if (err < 0) |
---|
.. | .. |
---|
697 | 695 | struct kernel_lb_addr eloc, tmpeloc; |
---|
698 | 696 | int c = 1; |
---|
699 | 697 | loff_t lbcount = 0, b_off = 0; |
---|
700 | | - udf_pblk_t newblocknum, newblock; |
---|
| 698 | + udf_pblk_t newblocknum, newblock = 0; |
---|
701 | 699 | sector_t offset = 0; |
---|
702 | 700 | int8_t etype; |
---|
703 | 701 | struct udf_inode_info *iinfo = UDF_I(inode); |
---|
.. | .. |
---|
776 | 774 | goto out_free; |
---|
777 | 775 | } |
---|
778 | 776 | |
---|
779 | | - /* Are we beyond EOF? */ |
---|
| 777 | + /* Are we beyond EOF and preallocated extent? */ |
---|
780 | 778 | if (etype == -1) { |
---|
781 | 779 | int ret; |
---|
782 | 780 | loff_t hole_len; |
---|
| 781 | + |
---|
783 | 782 | isBeyondEOF = true; |
---|
784 | 783 | if (count) { |
---|
785 | 784 | if (c) |
---|
.. | .. |
---|
799 | 798 | ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len); |
---|
800 | 799 | if (ret < 0) { |
---|
801 | 800 | *err = ret; |
---|
802 | | - newblock = 0; |
---|
803 | 801 | goto out_free; |
---|
804 | 802 | } |
---|
805 | 803 | c = 0; |
---|
806 | 804 | offset = 0; |
---|
807 | 805 | count += ret; |
---|
808 | | - /* We are not covered by a preallocated extent? */ |
---|
809 | | - if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != |
---|
810 | | - EXT_NOT_RECORDED_ALLOCATED) { |
---|
811 | | - /* Is there any real extent? - otherwise we overwrite |
---|
812 | | - * the fake one... */ |
---|
813 | | - if (count) |
---|
814 | | - c = !c; |
---|
815 | | - laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
---|
816 | | - inode->i_sb->s_blocksize; |
---|
817 | | - memset(&laarr[c].extLocation, 0x00, |
---|
818 | | - sizeof(struct kernel_lb_addr)); |
---|
819 | | - count++; |
---|
820 | | - } |
---|
| 806 | + /* |
---|
| 807 | + * Is there any real extent? - otherwise we overwrite the fake |
---|
| 808 | + * one... |
---|
| 809 | + */ |
---|
| 810 | + if (count) |
---|
| 811 | + c = !c; |
---|
| 812 | + laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | |
---|
| 813 | + inode->i_sb->s_blocksize; |
---|
| 814 | + memset(&laarr[c].extLocation, 0x00, |
---|
| 815 | + sizeof(struct kernel_lb_addr)); |
---|
| 816 | + count++; |
---|
821 | 817 | endnum = c + 1; |
---|
822 | 818 | lastblock = 1; |
---|
823 | 819 | } else { |
---|
.. | .. |
---|
864 | 860 | goal, err); |
---|
865 | 861 | if (!newblocknum) { |
---|
866 | 862 | *err = -ENOSPC; |
---|
867 | | - newblock = 0; |
---|
868 | 863 | goto out_free; |
---|
869 | 864 | } |
---|
870 | 865 | if (isBeyondEOF) |
---|
.. | .. |
---|
890 | 885 | /* write back the new extents, inserting new extents if the new number |
---|
891 | 886 | * of extents is greater than the old number, and deleting extents if |
---|
892 | 887 | * the new number of extents is less than the old number */ |
---|
893 | | - udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); |
---|
| 888 | + *err = udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); |
---|
| 889 | + if (*err < 0) |
---|
| 890 | + goto out_free; |
---|
894 | 891 | |
---|
895 | 892 | newblock = udf_get_pblock(inode->i_sb, newblocknum, |
---|
896 | 893 | iinfo->i_location.partitionReferenceNum, 0); |
---|
.. | .. |
---|
1094 | 1091 | blocksize - 1) >> blocksize_bits)))) { |
---|
1095 | 1092 | |
---|
1096 | 1093 | if (((li->extLength & UDF_EXTENT_LENGTH_MASK) + |
---|
1097 | | - (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + |
---|
1098 | | - blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) { |
---|
1099 | | - lip1->extLength = (lip1->extLength - |
---|
1100 | | - (li->extLength & |
---|
1101 | | - UDF_EXTENT_LENGTH_MASK) + |
---|
1102 | | - UDF_EXTENT_LENGTH_MASK) & |
---|
1103 | | - ~(blocksize - 1); |
---|
1104 | | - li->extLength = (li->extLength & |
---|
1105 | | - UDF_EXTENT_FLAG_MASK) + |
---|
1106 | | - (UDF_EXTENT_LENGTH_MASK + 1) - |
---|
1107 | | - blocksize; |
---|
1108 | | - lip1->extLocation.logicalBlockNum = |
---|
1109 | | - li->extLocation.logicalBlockNum + |
---|
1110 | | - ((li->extLength & |
---|
1111 | | - UDF_EXTENT_LENGTH_MASK) >> |
---|
1112 | | - blocksize_bits); |
---|
1113 | | - } else { |
---|
| 1094 | + (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + |
---|
| 1095 | + blocksize - 1) <= UDF_EXTENT_LENGTH_MASK) { |
---|
1114 | 1096 | li->extLength = lip1->extLength + |
---|
1115 | 1097 | (((li->extLength & |
---|
1116 | 1098 | UDF_EXTENT_LENGTH_MASK) + |
---|
.. | .. |
---|
1173 | 1155 | } |
---|
1174 | 1156 | } |
---|
1175 | 1157 | |
---|
1176 | | -static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, |
---|
1177 | | - int startnum, int endnum, |
---|
1178 | | - struct extent_position *epos) |
---|
| 1158 | +static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, |
---|
| 1159 | + int startnum, int endnum, |
---|
| 1160 | + struct extent_position *epos) |
---|
1179 | 1161 | { |
---|
1180 | 1162 | int start = 0, i; |
---|
1181 | 1163 | struct kernel_lb_addr tmploc; |
---|
1182 | 1164 | uint32_t tmplen; |
---|
| 1165 | + int err; |
---|
1183 | 1166 | |
---|
1184 | 1167 | if (startnum > endnum) { |
---|
1185 | 1168 | for (i = 0; i < (startnum - endnum); i++) |
---|
1186 | 1169 | udf_delete_aext(inode, *epos); |
---|
1187 | 1170 | } else if (startnum < endnum) { |
---|
1188 | 1171 | for (i = 0; i < (endnum - startnum); i++) { |
---|
1189 | | - udf_insert_aext(inode, *epos, laarr[i].extLocation, |
---|
1190 | | - laarr[i].extLength); |
---|
| 1172 | + err = udf_insert_aext(inode, *epos, |
---|
| 1173 | + laarr[i].extLocation, |
---|
| 1174 | + laarr[i].extLength); |
---|
| 1175 | + /* |
---|
| 1176 | + * If we fail here, we are likely corrupting the extent |
---|
| 1177 | + * list and leaking blocks. At least stop early to |
---|
| 1178 | + * limit the damage. |
---|
| 1179 | + */ |
---|
| 1180 | + if (err < 0) |
---|
| 1181 | + return err; |
---|
1191 | 1182 | udf_next_aext(inode, epos, &laarr[i].extLocation, |
---|
1192 | 1183 | &laarr[i].extLength, 1); |
---|
1193 | 1184 | start++; |
---|
.. | .. |
---|
1199 | 1190 | udf_write_aext(inode, epos, &laarr[i].extLocation, |
---|
1200 | 1191 | laarr[i].extLength, 1); |
---|
1201 | 1192 | } |
---|
| 1193 | + return 0; |
---|
1202 | 1194 | } |
---|
1203 | 1195 | |
---|
1204 | 1196 | struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, |
---|
.. | .. |
---|
1401 | 1393 | ret = -EIO; |
---|
1402 | 1394 | goto out; |
---|
1403 | 1395 | } |
---|
| 1396 | + iinfo->i_hidden = hidden_inode; |
---|
1404 | 1397 | iinfo->i_unique = 0; |
---|
1405 | 1398 | iinfo->i_lenEAttr = 0; |
---|
1406 | 1399 | iinfo->i_lenExtents = 0; |
---|
.. | .. |
---|
1736 | 1729 | |
---|
1737 | 1730 | if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) |
---|
1738 | 1731 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); |
---|
1739 | | - else |
---|
1740 | | - fe->fileLinkCount = cpu_to_le16(inode->i_nlink); |
---|
| 1732 | + else { |
---|
| 1733 | + if (iinfo->i_hidden) |
---|
| 1734 | + fe->fileLinkCount = cpu_to_le16(0); |
---|
| 1735 | + else |
---|
| 1736 | + fe->fileLinkCount = cpu_to_le16(inode->i_nlink); |
---|
| 1737 | + } |
---|
1741 | 1738 | |
---|
1742 | 1739 | fe->informationLength = cpu_to_le64(inode->i_size); |
---|
1743 | 1740 | |
---|
.. | .. |
---|
1908 | 1905 | if (!inode) |
---|
1909 | 1906 | return ERR_PTR(-ENOMEM); |
---|
1910 | 1907 | |
---|
1911 | | - if (!(inode->i_state & I_NEW)) |
---|
| 1908 | + if (!(inode->i_state & I_NEW)) { |
---|
| 1909 | + if (UDF_I(inode)->i_hidden != hidden_inode) { |
---|
| 1910 | + iput(inode); |
---|
| 1911 | + return ERR_PTR(-EFSCORRUPTED); |
---|
| 1912 | + } |
---|
1912 | 1913 | return inode; |
---|
| 1914 | + } |
---|
1913 | 1915 | |
---|
1914 | 1916 | memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); |
---|
1915 | 1917 | err = udf_read_inode(inode, hidden_inode); |
---|
.. | .. |
---|
2223 | 2225 | return etype; |
---|
2224 | 2226 | } |
---|
2225 | 2227 | |
---|
2226 | | -static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, |
---|
2227 | | - struct kernel_lb_addr neloc, uint32_t nelen) |
---|
| 2228 | +static int udf_insert_aext(struct inode *inode, struct extent_position epos, |
---|
| 2229 | + struct kernel_lb_addr neloc, uint32_t nelen) |
---|
2228 | 2230 | { |
---|
2229 | 2231 | struct kernel_lb_addr oeloc; |
---|
2230 | 2232 | uint32_t oelen; |
---|
2231 | 2233 | int8_t etype; |
---|
| 2234 | + int err; |
---|
2232 | 2235 | |
---|
2233 | 2236 | if (epos.bh) |
---|
2234 | 2237 | get_bh(epos.bh); |
---|
.. | .. |
---|
2238 | 2241 | neloc = oeloc; |
---|
2239 | 2242 | nelen = (etype << 30) | oelen; |
---|
2240 | 2243 | } |
---|
2241 | | - udf_add_aext(inode, &epos, &neloc, nelen, 1); |
---|
| 2244 | + err = udf_add_aext(inode, &epos, &neloc, nelen, 1); |
---|
2242 | 2245 | brelse(epos.bh); |
---|
2243 | 2246 | |
---|
2244 | | - return (nelen >> 30); |
---|
| 2247 | + return err; |
---|
2245 | 2248 | } |
---|
2246 | 2249 | |
---|
2247 | 2250 | int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) |
---|