diff options
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/balloc.c | 177 | ||||
-rw-r--r-- | fs/udf/dir.c | 39 | ||||
-rw-r--r-- | fs/udf/directory.c | 30 | ||||
-rw-r--r-- | fs/udf/file.c | 1 | ||||
-rw-r--r-- | fs/udf/fsync.c | 1 | ||||
-rw-r--r-- | fs/udf/inode.c | 598 | ||||
-rw-r--r-- | fs/udf/misc.c | 6 | ||||
-rw-r--r-- | fs/udf/namei.c | 227 | ||||
-rw-r--r-- | fs/udf/partition.c | 2 | ||||
-rw-r--r-- | fs/udf/super.c | 83 | ||||
-rw-r--r-- | fs/udf/symlink.c | 2 | ||||
-rw-r--r-- | fs/udf/truncate.c | 275 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 2 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 26 |
14 files changed, 810 insertions, 659 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index ea521f846d..4cec910156 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -427,9 +427,9 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
427 | { | 427 | { |
428 | struct udf_sb_info *sbi = UDF_SB(sb); | 428 | struct udf_sb_info *sbi = UDF_SB(sb); |
429 | uint32_t start, end; | 429 | uint32_t start, end; |
430 | uint32_t nextoffset, oextoffset, elen; | 430 | uint32_t elen; |
431 | kernel_lb_addr nbloc, obloc, eloc; | 431 | kernel_lb_addr eloc; |
432 | struct buffer_head *obh, *nbh; | 432 | struct extent_position oepos, epos; |
433 | int8_t etype; | 433 | int8_t etype; |
434 | int i; | 434 | int i; |
435 | 435 | ||
@@ -457,14 +457,13 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
457 | start = bloc.logicalBlockNum + offset; | 457 | start = bloc.logicalBlockNum + offset; |
458 | end = bloc.logicalBlockNum + offset + count - 1; | 458 | end = bloc.logicalBlockNum + offset + count - 1; |
459 | 459 | ||
460 | oextoffset = nextoffset = sizeof(struct unallocSpaceEntry); | 460 | epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry); |
461 | elen = 0; | 461 | elen = 0; |
462 | obloc = nbloc = UDF_I_LOCATION(table); | 462 | epos.block = oepos.block = UDF_I_LOCATION(table); |
463 | 463 | epos.bh = oepos.bh = NULL; | |
464 | obh = nbh = NULL; | ||
465 | 464 | ||
466 | while (count && (etype = | 465 | while (count && (etype = |
467 | udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) | 466 | udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
468 | { | 467 | { |
469 | if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == | 468 | if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == |
470 | start)) | 469 | start)) |
@@ -482,7 +481,7 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
482 | start += count; | 481 | start += count; |
483 | count = 0; | 482 | count = 0; |
484 | } | 483 | } |
485 | udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1); | 484 | udf_write_aext(table, &oepos, eloc, elen, 1); |
486 | } | 485 | } |
487 | else if (eloc.logicalBlockNum == (end + 1)) | 486 | else if (eloc.logicalBlockNum == (end + 1)) |
488 | { | 487 | { |
@@ -502,20 +501,20 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
502 | end -= count; | 501 | end -= count; |
503 | count = 0; | 502 | count = 0; |
504 | } | 503 | } |
505 | udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1); | 504 | udf_write_aext(table, &oepos, eloc, elen, 1); |
506 | } | 505 | } |
507 | 506 | ||
508 | if (nbh != obh) | 507 | if (epos.bh != oepos.bh) |
509 | { | 508 | { |
510 | i = -1; | 509 | i = -1; |
511 | obloc = nbloc; | 510 | oepos.block = epos.block; |
512 | udf_release_data(obh); | 511 | brelse(oepos.bh); |
513 | atomic_inc(&nbh->b_count); | 512 | get_bh(epos.bh); |
514 | obh = nbh; | 513 | oepos.bh = epos.bh; |
515 | oextoffset = 0; | 514 | oepos.offset = 0; |
516 | } | 515 | } |
517 | else | 516 | else |
518 | oextoffset = nextoffset; | 517 | oepos.offset = epos.offset; |
519 | } | 518 | } |
520 | 519 | ||
521 | if (count) | 520 | if (count) |
@@ -547,55 +546,53 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
547 | adsize = sizeof(long_ad); | 546 | adsize = sizeof(long_ad); |
548 | else | 547 | else |
549 | { | 548 | { |
550 | udf_release_data(obh); | 549 | brelse(oepos.bh); |
551 | udf_release_data(nbh); | 550 | brelse(epos.bh); |
552 | goto error_return; | 551 | goto error_return; |
553 | } | 552 | } |
554 | 553 | ||
555 | if (nextoffset + (2 * adsize) > sb->s_blocksize) | 554 | if (epos.offset + (2 * adsize) > sb->s_blocksize) |
556 | { | 555 | { |
557 | char *sptr, *dptr; | 556 | char *sptr, *dptr; |
558 | int loffset; | 557 | int loffset; |
559 | 558 | ||
560 | udf_release_data(obh); | 559 | brelse(oepos.bh); |
561 | obh = nbh; | 560 | oepos = epos; |
562 | obloc = nbloc; | ||
563 | oextoffset = nextoffset; | ||
564 | 561 | ||
565 | /* Steal a block from the extent being free'd */ | 562 | /* Steal a block from the extent being free'd */ |
566 | nbloc.logicalBlockNum = eloc.logicalBlockNum; | 563 | epos.block.logicalBlockNum = eloc.logicalBlockNum; |
567 | eloc.logicalBlockNum ++; | 564 | eloc.logicalBlockNum ++; |
568 | elen -= sb->s_blocksize; | 565 | elen -= sb->s_blocksize; |
569 | 566 | ||
570 | if (!(nbh = udf_tread(sb, | 567 | if (!(epos.bh = udf_tread(sb, |
571 | udf_get_lb_pblock(sb, nbloc, 0)))) | 568 | udf_get_lb_pblock(sb, epos.block, 0)))) |
572 | { | 569 | { |
573 | udf_release_data(obh); | 570 | brelse(oepos.bh); |
574 | goto error_return; | 571 | goto error_return; |
575 | } | 572 | } |
576 | aed = (struct allocExtDesc *)(nbh->b_data); | 573 | aed = (struct allocExtDesc *)(epos.bh->b_data); |
577 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); | 574 | aed->previousAllocExtLocation = cpu_to_le32(oepos.block.logicalBlockNum); |
578 | if (nextoffset + adsize > sb->s_blocksize) | 575 | if (epos.offset + adsize > sb->s_blocksize) |
579 | { | 576 | { |
580 | loffset = nextoffset; | 577 | loffset = epos.offset; |
581 | aed->lengthAllocDescs = cpu_to_le32(adsize); | 578 | aed->lengthAllocDescs = cpu_to_le32(adsize); |
582 | sptr = UDF_I_DATA(inode) + nextoffset - | 579 | sptr = UDF_I_DATA(inode) + epos.offset - |
583 | udf_file_entry_alloc_offset(inode) + | 580 | udf_file_entry_alloc_offset(inode) + |
584 | UDF_I_LENEATTR(inode) - adsize; | 581 | UDF_I_LENEATTR(inode) - adsize; |
585 | dptr = nbh->b_data + sizeof(struct allocExtDesc); | 582 | dptr = epos.bh->b_data + sizeof(struct allocExtDesc); |
586 | memcpy(dptr, sptr, adsize); | 583 | memcpy(dptr, sptr, adsize); |
587 | nextoffset = sizeof(struct allocExtDesc) + adsize; | 584 | epos.offset = sizeof(struct allocExtDesc) + adsize; |
588 | } | 585 | } |
589 | else | 586 | else |
590 | { | 587 | { |
591 | loffset = nextoffset + adsize; | 588 | loffset = epos.offset + adsize; |
592 | aed->lengthAllocDescs = cpu_to_le32(0); | 589 | aed->lengthAllocDescs = cpu_to_le32(0); |
593 | sptr = (obh)->b_data + nextoffset; | 590 | sptr = oepos.bh->b_data + epos.offset; |
594 | nextoffset = sizeof(struct allocExtDesc); | 591 | epos.offset = sizeof(struct allocExtDesc); |
595 | 592 | ||
596 | if (obh) | 593 | if (oepos.bh) |
597 | { | 594 | { |
598 | aed = (struct allocExtDesc *)(obh)->b_data; | 595 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
599 | aed->lengthAllocDescs = | 596 | aed->lengthAllocDescs = |
600 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 597 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
601 | } | 598 | } |
@@ -606,11 +603,11 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
606 | } | 603 | } |
607 | } | 604 | } |
608 | if (UDF_SB_UDFREV(sb) >= 0x0200) | 605 | if (UDF_SB_UDFREV(sb) >= 0x0200) |
609 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, | 606 | udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1, |
610 | nbloc.logicalBlockNum, sizeof(tag)); | 607 | epos.block.logicalBlockNum, sizeof(tag)); |
611 | else | 608 | else |
612 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, | 609 | udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1, |
613 | nbloc.logicalBlockNum, sizeof(tag)); | 610 | epos.block.logicalBlockNum, sizeof(tag)); |
614 | switch (UDF_I_ALLOCTYPE(table)) | 611 | switch (UDF_I_ALLOCTYPE(table)) |
615 | { | 612 | { |
616 | case ICBTAG_FLAG_AD_SHORT: | 613 | case ICBTAG_FLAG_AD_SHORT: |
@@ -619,7 +616,7 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
619 | sad->extLength = cpu_to_le32( | 616 | sad->extLength = cpu_to_le32( |
620 | EXT_NEXT_EXTENT_ALLOCDECS | | 617 | EXT_NEXT_EXTENT_ALLOCDECS | |
621 | sb->s_blocksize); | 618 | sb->s_blocksize); |
622 | sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum); | 619 | sad->extPosition = cpu_to_le32(epos.block.logicalBlockNum); |
623 | break; | 620 | break; |
624 | } | 621 | } |
625 | case ICBTAG_FLAG_AD_LONG: | 622 | case ICBTAG_FLAG_AD_LONG: |
@@ -628,14 +625,14 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
628 | lad->extLength = cpu_to_le32( | 625 | lad->extLength = cpu_to_le32( |
629 | EXT_NEXT_EXTENT_ALLOCDECS | | 626 | EXT_NEXT_EXTENT_ALLOCDECS | |
630 | sb->s_blocksize); | 627 | sb->s_blocksize); |
631 | lad->extLocation = cpu_to_lelb(nbloc); | 628 | lad->extLocation = cpu_to_lelb(epos.block); |
632 | break; | 629 | break; |
633 | } | 630 | } |
634 | } | 631 | } |
635 | if (obh) | 632 | if (oepos.bh) |
636 | { | 633 | { |
637 | udf_update_tag(obh->b_data, loffset); | 634 | udf_update_tag(oepos.bh->b_data, loffset); |
638 | mark_buffer_dirty(obh); | 635 | mark_buffer_dirty(oepos.bh); |
639 | } | 636 | } |
640 | else | 637 | else |
641 | mark_inode_dirty(table); | 638 | mark_inode_dirty(table); |
@@ -643,26 +640,26 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
643 | 640 | ||
644 | if (elen) /* It's possible that stealing the block emptied the extent */ | 641 | if (elen) /* It's possible that stealing the block emptied the extent */ |
645 | { | 642 | { |
646 | udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1); | 643 | udf_write_aext(table, &epos, eloc, elen, 1); |
647 | 644 | ||
648 | if (!nbh) | 645 | if (!epos.bh) |
649 | { | 646 | { |
650 | UDF_I_LENALLOC(table) += adsize; | 647 | UDF_I_LENALLOC(table) += adsize; |
651 | mark_inode_dirty(table); | 648 | mark_inode_dirty(table); |
652 | } | 649 | } |
653 | else | 650 | else |
654 | { | 651 | { |
655 | aed = (struct allocExtDesc *)nbh->b_data; | 652 | aed = (struct allocExtDesc *)epos.bh->b_data; |
656 | aed->lengthAllocDescs = | 653 | aed->lengthAllocDescs = |
657 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 654 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
658 | udf_update_tag(nbh->b_data, nextoffset); | 655 | udf_update_tag(epos.bh->b_data, epos.offset); |
659 | mark_buffer_dirty(nbh); | 656 | mark_buffer_dirty(epos.bh); |
660 | } | 657 | } |
661 | } | 658 | } |
662 | } | 659 | } |
663 | 660 | ||
664 | udf_release_data(nbh); | 661 | brelse(epos.bh); |
665 | udf_release_data(obh); | 662 | brelse(oepos.bh); |
666 | 663 | ||
667 | error_return: | 664 | error_return: |
668 | sb->s_dirt = 1; | 665 | sb->s_dirt = 1; |
@@ -677,9 +674,9 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
677 | { | 674 | { |
678 | struct udf_sb_info *sbi = UDF_SB(sb); | 675 | struct udf_sb_info *sbi = UDF_SB(sb); |
679 | int alloc_count = 0; | 676 | int alloc_count = 0; |
680 | uint32_t extoffset, elen, adsize; | 677 | uint32_t elen, adsize; |
681 | kernel_lb_addr bloc, eloc; | 678 | kernel_lb_addr eloc; |
682 | struct buffer_head *bh; | 679 | struct extent_position epos; |
683 | int8_t etype = -1; | 680 | int8_t etype = -1; |
684 | 681 | ||
685 | if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) | 682 | if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) |
@@ -693,14 +690,13 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
693 | return 0; | 690 | return 0; |
694 | 691 | ||
695 | mutex_lock(&sbi->s_alloc_mutex); | 692 | mutex_lock(&sbi->s_alloc_mutex); |
696 | extoffset = sizeof(struct unallocSpaceEntry); | 693 | epos.offset = sizeof(struct unallocSpaceEntry); |
697 | bloc = UDF_I_LOCATION(table); | 694 | epos.block = UDF_I_LOCATION(table); |
698 | 695 | epos.bh = NULL; | |
699 | bh = NULL; | ||
700 | eloc.logicalBlockNum = 0xFFFFFFFF; | 696 | eloc.logicalBlockNum = 0xFFFFFFFF; |
701 | 697 | ||
702 | while (first_block != eloc.logicalBlockNum && (etype = | 698 | while (first_block != eloc.logicalBlockNum && (etype = |
703 | udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 699 | udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
704 | { | 700 | { |
705 | udf_debug("eloc=%d, elen=%d, first_block=%d\n", | 701 | udf_debug("eloc=%d, elen=%d, first_block=%d\n", |
706 | eloc.logicalBlockNum, elen, first_block); | 702 | eloc.logicalBlockNum, elen, first_block); |
@@ -709,7 +705,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
709 | 705 | ||
710 | if (first_block == eloc.logicalBlockNum) | 706 | if (first_block == eloc.logicalBlockNum) |
711 | { | 707 | { |
712 | extoffset -= adsize; | 708 | epos.offset -= adsize; |
713 | 709 | ||
714 | alloc_count = (elen >> sb->s_blocksize_bits); | 710 | alloc_count = (elen >> sb->s_blocksize_bits); |
715 | if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) | 711 | if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) |
@@ -719,15 +715,15 @@ static int udf_table_prealloc_blocks(struct super_block * sb, | |||
719 | alloc_count = block_count; | 715 | alloc_count = block_count; |
720 | eloc.logicalBlockNum += alloc_count; | 716 | eloc.logicalBlockNum += alloc_count; |
721 | elen -= (alloc_count << sb->s_blocksize_bits); | 717 | elen -= (alloc_count << sb->s_blocksize_bits); |
722 | udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1); | 718 | udf_write_aext(table, &epos, eloc, (etype << 30) | elen, 1); |
723 | } | 719 | } |
724 | else | 720 | else |
725 | udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh); | 721 | udf_delete_aext(table, epos, eloc, (etype << 30) | elen); |
726 | } | 722 | } |
727 | else | 723 | else |
728 | alloc_count = 0; | 724 | alloc_count = 0; |
729 | 725 | ||
730 | udf_release_data(bh); | 726 | brelse(epos.bh); |
731 | 727 | ||
732 | if (alloc_count && UDF_SB_LVIDBH(sb)) | 728 | if (alloc_count && UDF_SB_LVIDBH(sb)) |
733 | { | 729 | { |
@@ -747,9 +743,9 @@ static int udf_table_new_block(struct super_block * sb, | |||
747 | struct udf_sb_info *sbi = UDF_SB(sb); | 743 | struct udf_sb_info *sbi = UDF_SB(sb); |
748 | uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; | 744 | uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; |
749 | uint32_t newblock = 0, adsize; | 745 | uint32_t newblock = 0, adsize; |
750 | uint32_t extoffset, goal_extoffset, elen, goal_elen = 0; | 746 | uint32_t elen, goal_elen = 0; |
751 | kernel_lb_addr bloc, goal_bloc, eloc, goal_eloc; | 747 | kernel_lb_addr eloc, goal_eloc; |
752 | struct buffer_head *bh, *goal_bh; | 748 | struct extent_position epos, goal_epos; |
753 | int8_t etype; | 749 | int8_t etype; |
754 | 750 | ||
755 | *err = -ENOSPC; | 751 | *err = -ENOSPC; |
@@ -770,14 +766,12 @@ static int udf_table_new_block(struct super_block * sb, | |||
770 | We store the buffer_head, bloc, and extoffset of the current closest | 766 | We store the buffer_head, bloc, and extoffset of the current closest |
771 | match and use that when we are done. | 767 | match and use that when we are done. |
772 | */ | 768 | */ |
773 | 769 | epos.offset = sizeof(struct unallocSpaceEntry); | |
774 | extoffset = sizeof(struct unallocSpaceEntry); | 770 | epos.block = UDF_I_LOCATION(table); |
775 | bloc = UDF_I_LOCATION(table); | 771 | epos.bh = goal_epos.bh = NULL; |
776 | |||
777 | goal_bh = bh = NULL; | ||
778 | 772 | ||
779 | while (spread && (etype = | 773 | while (spread && (etype = |
780 | udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 774 | udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
781 | { | 775 | { |
782 | if (goal >= eloc.logicalBlockNum) | 776 | if (goal >= eloc.logicalBlockNum) |
783 | { | 777 | { |
@@ -793,24 +787,24 @@ static int udf_table_new_block(struct super_block * sb, | |||
793 | if (nspread < spread) | 787 | if (nspread < spread) |
794 | { | 788 | { |
795 | spread = nspread; | 789 | spread = nspread; |
796 | if (goal_bh != bh) | 790 | if (goal_epos.bh != epos.bh) |
797 | { | 791 | { |
798 | udf_release_data(goal_bh); | 792 | brelse(goal_epos.bh); |
799 | goal_bh = bh; | 793 | goal_epos.bh = epos.bh; |
800 | atomic_inc(&goal_bh->b_count); | 794 | get_bh(goal_epos.bh); |
801 | } | 795 | } |
802 | goal_bloc = bloc; | 796 | goal_epos.block = epos.block; |
803 | goal_extoffset = extoffset - adsize; | 797 | goal_epos.offset = epos.offset - adsize; |
804 | goal_eloc = eloc; | 798 | goal_eloc = eloc; |
805 | goal_elen = (etype << 30) | elen; | 799 | goal_elen = (etype << 30) | elen; |
806 | } | 800 | } |
807 | } | 801 | } |
808 | 802 | ||
809 | udf_release_data(bh); | 803 | brelse(epos.bh); |
810 | 804 | ||
811 | if (spread == 0xFFFFFFFF) | 805 | if (spread == 0xFFFFFFFF) |
812 | { | 806 | { |
813 | udf_release_data(goal_bh); | 807 | brelse(goal_epos.bh); |
814 | mutex_unlock(&sbi->s_alloc_mutex); | 808 | mutex_unlock(&sbi->s_alloc_mutex); |
815 | return 0; | 809 | return 0; |
816 | } | 810 | } |
@@ -826,17 +820,17 @@ static int udf_table_new_block(struct super_block * sb, | |||
826 | 820 | ||
827 | if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) | 821 | if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) |
828 | { | 822 | { |
829 | udf_release_data(goal_bh); | 823 | brelse(goal_epos.bh); |
830 | mutex_unlock(&sbi->s_alloc_mutex); | 824 | mutex_unlock(&sbi->s_alloc_mutex); |
831 | *err = -EDQUOT; | 825 | *err = -EDQUOT; |
832 | return 0; | 826 | return 0; |
833 | } | 827 | } |
834 | 828 | ||
835 | if (goal_elen) | 829 | if (goal_elen) |
836 | udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1); | 830 | udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1); |
837 | else | 831 | else |
838 | udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh); | 832 | udf_delete_aext(table, goal_epos, goal_eloc, goal_elen); |
839 | udf_release_data(goal_bh); | 833 | brelse(goal_epos.bh); |
840 | 834 | ||
841 | if (UDF_SB_LVIDBH(sb)) | 835 | if (UDF_SB_LVIDBH(sb)) |
842 | { | 836 | { |
@@ -921,11 +915,14 @@ inline int udf_new_block(struct super_block * sb, | |||
921 | struct inode * inode, | 915 | struct inode * inode, |
922 | uint16_t partition, uint32_t goal, int *err) | 916 | uint16_t partition, uint32_t goal, int *err) |
923 | { | 917 | { |
918 | int ret; | ||
919 | |||
924 | if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) | 920 | if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) |
925 | { | 921 | { |
926 | return udf_bitmap_new_block(sb, inode, | 922 | ret = udf_bitmap_new_block(sb, inode, |
927 | UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap, | 923 | UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap, |
928 | partition, goal, err); | 924 | partition, goal, err); |
925 | return ret; | ||
929 | } | 926 | } |
930 | else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) | 927 | else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) |
931 | { | 928 | { |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 2391c9150c..e45f86b5e7 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -111,11 +111,13 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
111 | uint16_t liu; | 111 | uint16_t liu; |
112 | uint8_t lfi; | 112 | uint8_t lfi; |
113 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 113 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; |
114 | struct buffer_head * bh = NULL, * tmp, * bha[16]; | 114 | struct buffer_head *tmp, *bha[16]; |
115 | kernel_lb_addr bloc, eloc; | 115 | kernel_lb_addr eloc; |
116 | uint32_t extoffset, elen, offset; | 116 | uint32_t elen; |
117 | sector_t offset; | ||
117 | int i, num; | 118 | int i, num; |
118 | unsigned int dt_type; | 119 | unsigned int dt_type; |
120 | struct extent_position epos = { NULL, 0, {0, 0}}; | ||
119 | 121 | ||
120 | if (nf_pos >= size) | 122 | if (nf_pos >= size) |
121 | return 0; | 123 | return 0; |
@@ -127,23 +129,22 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
127 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 129 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
128 | fibh.sbh = fibh.ebh = NULL; | 130 | fibh.sbh = fibh.ebh = NULL; |
129 | else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), | 131 | else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), |
130 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 132 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
131 | { | 133 | { |
132 | offset >>= dir->i_sb->s_blocksize_bits; | ||
133 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 134 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
134 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 135 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
135 | { | 136 | { |
136 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 137 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
137 | extoffset -= sizeof(short_ad); | 138 | epos.offset -= sizeof(short_ad); |
138 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 139 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
139 | extoffset -= sizeof(long_ad); | 140 | epos.offset -= sizeof(long_ad); |
140 | } | 141 | } |
141 | else | 142 | else |
142 | offset = 0; | 143 | offset = 0; |
143 | 144 | ||
144 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) | 145 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) |
145 | { | 146 | { |
146 | udf_release_data(bh); | 147 | brelse(epos.bh); |
147 | return -EIO; | 148 | return -EIO; |
148 | } | 149 | } |
149 | 150 | ||
@@ -171,7 +172,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
171 | } | 172 | } |
172 | else | 173 | else |
173 | { | 174 | { |
174 | udf_release_data(bh); | 175 | brelse(epos.bh); |
175 | return -ENOENT; | 176 | return -ENOENT; |
176 | } | 177 | } |
177 | 178 | ||
@@ -179,14 +180,14 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
179 | { | 180 | { |
180 | filp->f_pos = nf_pos + 1; | 181 | filp->f_pos = nf_pos + 1; |
181 | 182 | ||
182 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 183 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); |
183 | 184 | ||
184 | if (!fi) | 185 | if (!fi) |
185 | { | 186 | { |
186 | if (fibh.sbh != fibh.ebh) | 187 | if (fibh.sbh != fibh.ebh) |
187 | udf_release_data(fibh.ebh); | 188 | brelse(fibh.ebh); |
188 | udf_release_data(fibh.sbh); | 189 | brelse(fibh.sbh); |
189 | udf_release_data(bh); | 190 | brelse(epos.bh); |
190 | return 0; | 191 | return 0; |
191 | } | 192 | } |
192 | 193 | ||
@@ -244,9 +245,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
244 | if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) | 245 | if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) |
245 | { | 246 | { |
246 | if (fibh.sbh != fibh.ebh) | 247 | if (fibh.sbh != fibh.ebh) |
247 | udf_release_data(fibh.ebh); | 248 | brelse(fibh.ebh); |
248 | udf_release_data(fibh.sbh); | 249 | brelse(fibh.sbh); |
249 | udf_release_data(bh); | 250 | brelse(epos.bh); |
250 | return 0; | 251 | return 0; |
251 | } | 252 | } |
252 | } | 253 | } |
@@ -255,9 +256,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
255 | filp->f_pos = nf_pos + 1; | 256 | filp->f_pos = nf_pos + 1; |
256 | 257 | ||
257 | if (fibh.sbh != fibh.ebh) | 258 | if (fibh.sbh != fibh.ebh) |
258 | udf_release_data(fibh.ebh); | 259 | brelse(fibh.ebh); |
259 | udf_release_data(fibh.sbh); | 260 | brelse(fibh.sbh); |
260 | udf_release_data(bh); | 261 | brelse(epos.bh); |
261 | 262 | ||
262 | return 0; | 263 | return 0; |
263 | } | 264 | } |
diff --git a/fs/udf/directory.c b/fs/udf/directory.c index fe751a2a0e..198caa3302 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c | |||
@@ -36,14 +36,14 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, | |||
36 | 36 | ||
37 | if (!ad) | 37 | if (!ad) |
38 | { | 38 | { |
39 | udf_release_data(*bh); | 39 | brelse(*bh); |
40 | *error = 1; | 40 | *error = 1; |
41 | return NULL; | 41 | return NULL; |
42 | } | 42 | } |
43 | 43 | ||
44 | if (*offset == dir->i_sb->s_blocksize) | 44 | if (*offset == dir->i_sb->s_blocksize) |
45 | { | 45 | { |
46 | udf_release_data(*bh); | 46 | brelse(*bh); |
47 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); | 47 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); |
48 | if (!block) | 48 | if (!block) |
49 | return NULL; | 49 | return NULL; |
@@ -57,7 +57,7 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, | |||
57 | remainder = dir->i_sb->s_blocksize - loffset; | 57 | remainder = dir->i_sb->s_blocksize - loffset; |
58 | memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder); | 58 | memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder); |
59 | 59 | ||
60 | udf_release_data(*bh); | 60 | brelse(*bh); |
61 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); | 61 | block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); |
62 | if (!block) | 62 | if (!block) |
63 | return NULL; | 63 | return NULL; |
@@ -75,9 +75,9 @@ struct fileIdentDesc * | |||
75 | udf_fileident_read(struct inode *dir, loff_t *nf_pos, | 75 | udf_fileident_read(struct inode *dir, loff_t *nf_pos, |
76 | struct udf_fileident_bh *fibh, | 76 | struct udf_fileident_bh *fibh, |
77 | struct fileIdentDesc *cfi, | 77 | struct fileIdentDesc *cfi, |
78 | kernel_lb_addr *bloc, uint32_t *extoffset, | 78 | struct extent_position *epos, |
79 | kernel_lb_addr *eloc, uint32_t *elen, | 79 | kernel_lb_addr *eloc, uint32_t *elen, |
80 | uint32_t *offset, struct buffer_head **bh) | 80 | sector_t *offset) |
81 | { | 81 | { |
82 | struct fileIdentDesc *fi; | 82 | struct fileIdentDesc *fi; |
83 | int i, num, block; | 83 | int i, num, block; |
@@ -105,13 +105,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
105 | 105 | ||
106 | if (fibh->eoffset == dir->i_sb->s_blocksize) | 106 | if (fibh->eoffset == dir->i_sb->s_blocksize) |
107 | { | 107 | { |
108 | int lextoffset = *extoffset; | 108 | int lextoffset = epos->offset; |
109 | 109 | ||
110 | if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) != | 110 | if (udf_next_aext(dir, epos, eloc, elen, 1) != |
111 | (EXT_RECORDED_ALLOCATED >> 30)) | 111 | (EXT_RECORDED_ALLOCATED >> 30)) |
112 | { | ||
113 | return NULL; | 112 | return NULL; |
114 | } | ||
115 | 113 | ||
116 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); | 114 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); |
117 | 115 | ||
@@ -120,9 +118,9 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
120 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) | 118 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) |
121 | *offset = 0; | 119 | *offset = 0; |
122 | else | 120 | else |
123 | *extoffset = lextoffset; | 121 | epos->offset = lextoffset; |
124 | 122 | ||
125 | udf_release_data(fibh->sbh); | 123 | brelse(fibh->sbh); |
126 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) | 124 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) |
127 | return NULL; | 125 | return NULL; |
128 | fibh->soffset = fibh->eoffset = 0; | 126 | fibh->soffset = fibh->eoffset = 0; |
@@ -151,7 +149,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
151 | } | 149 | } |
152 | else if (fibh->sbh != fibh->ebh) | 150 | else if (fibh->sbh != fibh->ebh) |
153 | { | 151 | { |
154 | udf_release_data(fibh->sbh); | 152 | brelse(fibh->sbh); |
155 | fibh->sbh = fibh->ebh; | 153 | fibh->sbh = fibh->ebh; |
156 | } | 154 | } |
157 | 155 | ||
@@ -169,13 +167,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
169 | } | 167 | } |
170 | else if (fibh->eoffset > dir->i_sb->s_blocksize) | 168 | else if (fibh->eoffset > dir->i_sb->s_blocksize) |
171 | { | 169 | { |
172 | int lextoffset = *extoffset; | 170 | int lextoffset = epos->offset; |
173 | 171 | ||
174 | if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) != | 172 | if (udf_next_aext(dir, epos, eloc, elen, 1) != |
175 | (EXT_RECORDED_ALLOCATED >> 30)) | 173 | (EXT_RECORDED_ALLOCATED >> 30)) |
176 | { | ||
177 | return NULL; | 174 | return NULL; |
178 | } | ||
179 | 175 | ||
180 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); | 176 | block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); |
181 | 177 | ||
@@ -184,7 +180,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, | |||
184 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) | 180 | if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) |
185 | *offset = 0; | 181 | *offset = 0; |
186 | else | 182 | else |
187 | *extoffset = lextoffset; | 183 | epos->offset = lextoffset; |
188 | 184 | ||
189 | fibh->soffset -= dir->i_sb->s_blocksize; | 185 | fibh->soffset -= dir->i_sb->s_blocksize; |
190 | fibh->eoffset -= dir->i_sb->s_blocksize; | 186 | fibh->eoffset -= dir->i_sb->s_blocksize; |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 40d5047def..51b5764685 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/smp_lock.h> | 36 | #include <linux/smp_lock.h> |
37 | #include <linux/pagemap.h> | 37 | #include <linux/pagemap.h> |
38 | #include <linux/buffer_head.h> | 38 | #include <linux/buffer_head.h> |
39 | #include <linux/aio.h> | ||
39 | 40 | ||
40 | #include "udf_i.h" | 41 | #include "udf_i.h" |
41 | #include "udf_sb.h" | 42 | #include "udf_sb.h" |
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c index 5887d78cde..6ded93e7c4 100644 --- a/fs/udf/fsync.c +++ b/fs/udf/fsync.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "udfdecl.h" | 21 | #include "udfdecl.h" |
22 | 22 | ||
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/smp_lock.h> | ||
25 | 24 | ||
26 | static int udf_fsync_inode(struct inode *, int); | 25 | static int udf_fsync_inode(struct inode *, int); |
27 | 26 | ||
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index ae21a0e59e..bf7de0bdba 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -49,10 +49,10 @@ MODULE_LICENSE("GPL"); | |||
49 | static mode_t udf_convert_permissions(struct fileEntry *); | 49 | static mode_t udf_convert_permissions(struct fileEntry *); |
50 | static int udf_update_inode(struct inode *, int); | 50 | static int udf_update_inode(struct inode *, int); |
51 | static void udf_fill_inode(struct inode *, struct buffer_head *); | 51 | static void udf_fill_inode(struct inode *, struct buffer_head *); |
52 | static struct buffer_head *inode_getblk(struct inode *, long, int *, | 52 | static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, |
53 | long *, int *); | 53 | long *, int *); |
54 | static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int, | 54 | static int8_t udf_insert_aext(struct inode *, struct extent_position, |
55 | kernel_lb_addr, uint32_t, struct buffer_head *); | 55 | kernel_lb_addr, uint32_t); |
56 | static void udf_split_extents(struct inode *, int *, int, int, | 56 | static void udf_split_extents(struct inode *, int *, int, int, |
57 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); | 57 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
58 | static void udf_prealloc_extents(struct inode *, int, int, | 58 | static void udf_prealloc_extents(struct inode *, int, int, |
@@ -61,7 +61,7 @@ static void udf_merge_extents(struct inode *, | |||
61 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); | 61 | kernel_long_ad [EXTENT_MERGE_SIZE], int *); |
62 | static void udf_update_extents(struct inode *, | 62 | static void udf_update_extents(struct inode *, |
63 | kernel_long_ad [EXTENT_MERGE_SIZE], int, int, | 63 | kernel_long_ad [EXTENT_MERGE_SIZE], int, int, |
64 | kernel_lb_addr, uint32_t, struct buffer_head **); | 64 | struct extent_position *); |
65 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | 65 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
66 | 66 | ||
67 | /* | 67 | /* |
@@ -100,14 +100,23 @@ no_delete: | |||
100 | clear_inode(inode); | 100 | clear_inode(inode); |
101 | } | 101 | } |
102 | 102 | ||
103 | /* | ||
104 | * If we are going to release inode from memory, we discard preallocation and | ||
105 | * truncate last inode extent to proper length. We could use drop_inode() but | ||
106 | * it's called under inode_lock and thus we cannot mark inode dirty there. We | ||
107 | * use clear_inode() but we have to make sure to write inode as it's not written | ||
108 | * automatically. | ||
109 | */ | ||
103 | void udf_clear_inode(struct inode *inode) | 110 | void udf_clear_inode(struct inode *inode) |
104 | { | 111 | { |
105 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { | 112 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { |
106 | lock_kernel(); | 113 | lock_kernel(); |
114 | /* Discard preallocation for directories, symlinks, etc. */ | ||
107 | udf_discard_prealloc(inode); | 115 | udf_discard_prealloc(inode); |
116 | udf_truncate_tail_extent(inode); | ||
108 | unlock_kernel(); | 117 | unlock_kernel(); |
118 | write_inode_now(inode, 1); | ||
109 | } | 119 | } |
110 | |||
111 | kfree(UDF_I_DATA(inode)); | 120 | kfree(UDF_I_DATA(inode)); |
112 | UDF_I_DATA(inode) = NULL; | 121 | UDF_I_DATA(inode) = NULL; |
113 | } | 122 | } |
@@ -194,10 +203,11 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) | |||
194 | struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) | 203 | struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) |
195 | { | 204 | { |
196 | int newblock; | 205 | int newblock; |
197 | struct buffer_head *sbh = NULL, *dbh = NULL; | 206 | struct buffer_head *dbh = NULL; |
198 | kernel_lb_addr bloc, eloc; | 207 | kernel_lb_addr eloc; |
199 | uint32_t elen, extoffset; | 208 | uint32_t elen; |
200 | uint8_t alloctype; | 209 | uint8_t alloctype; |
210 | struct extent_position epos; | ||
201 | 211 | ||
202 | struct udf_fileident_bh sfibh, dfibh; | 212 | struct udf_fileident_bh sfibh, dfibh; |
203 | loff_t f_pos = udf_ext0_offset(inode) >> 2; | 213 | loff_t f_pos = udf_ext0_offset(inode) >> 2; |
@@ -237,16 +247,16 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int | |||
237 | mark_buffer_dirty_inode(dbh, inode); | 247 | mark_buffer_dirty_inode(dbh, inode); |
238 | 248 | ||
239 | sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; | 249 | sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; |
240 | sbh = sfibh.sbh = sfibh.ebh = NULL; | 250 | sfibh.sbh = sfibh.ebh = NULL; |
241 | dfibh.soffset = dfibh.eoffset = 0; | 251 | dfibh.soffset = dfibh.eoffset = 0; |
242 | dfibh.sbh = dfibh.ebh = dbh; | 252 | dfibh.sbh = dfibh.ebh = dbh; |
243 | while ( (f_pos < size) ) | 253 | while ( (f_pos < size) ) |
244 | { | 254 | { |
245 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; | 255 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
246 | sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL); | 256 | sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); |
247 | if (!sfi) | 257 | if (!sfi) |
248 | { | 258 | { |
249 | udf_release_data(dbh); | 259 | brelse(dbh); |
250 | return NULL; | 260 | return NULL; |
251 | } | 261 | } |
252 | UDF_I_ALLOCTYPE(inode) = alloctype; | 262 | UDF_I_ALLOCTYPE(inode) = alloctype; |
@@ -258,7 +268,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int | |||
258 | sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) | 268 | sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) |
259 | { | 269 | { |
260 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; | 270 | UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; |
261 | udf_release_data(dbh); | 271 | brelse(dbh); |
262 | return NULL; | 272 | return NULL; |
263 | } | 273 | } |
264 | } | 274 | } |
@@ -266,16 +276,17 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int | |||
266 | 276 | ||
267 | memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); | 277 | memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); |
268 | UDF_I_LENALLOC(inode) = 0; | 278 | UDF_I_LENALLOC(inode) = 0; |
269 | bloc = UDF_I_LOCATION(inode); | ||
270 | eloc.logicalBlockNum = *block; | 279 | eloc.logicalBlockNum = *block; |
271 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; | 280 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; |
272 | elen = inode->i_size; | 281 | elen = inode->i_size; |
273 | UDF_I_LENEXTENTS(inode) = elen; | 282 | UDF_I_LENEXTENTS(inode) = elen; |
274 | extoffset = udf_file_entry_alloc_offset(inode); | 283 | epos.bh = NULL; |
275 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0); | 284 | epos.block = UDF_I_LOCATION(inode); |
285 | epos.offset = udf_file_entry_alloc_offset(inode); | ||
286 | udf_add_aext(inode, &epos, eloc, elen, 0); | ||
276 | /* UniqueID stuff */ | 287 | /* UniqueID stuff */ |
277 | 288 | ||
278 | udf_release_data(sbh); | 289 | brelse(epos.bh); |
279 | mark_inode_dirty(inode); | 290 | mark_inode_dirty(inode); |
280 | return dbh; | 291 | return dbh; |
281 | } | 292 | } |
@@ -354,53 +365,153 @@ udf_getblk(struct inode *inode, long block, int create, int *err) | |||
354 | return NULL; | 365 | return NULL; |
355 | } | 366 | } |
356 | 367 | ||
357 | static struct buffer_head * inode_getblk(struct inode * inode, long block, | 368 | /* Extend the file by 'blocks' blocks, return the number of extents added */ |
369 | int udf_extend_file(struct inode *inode, struct extent_position *last_pos, | ||
370 | kernel_long_ad *last_ext, sector_t blocks) | ||
371 | { | ||
372 | sector_t add; | ||
373 | int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); | ||
374 | struct super_block *sb = inode->i_sb; | ||
375 | kernel_lb_addr prealloc_loc = {0, 0}; | ||
376 | int prealloc_len = 0; | ||
377 | |||
378 | /* The previous extent is fake and we should not extend by anything | ||
379 | * - there's nothing to do... */ | ||
380 | if (!blocks && fake) | ||
381 | return 0; | ||
382 | /* Round the last extent up to a multiple of block size */ | ||
383 | if (last_ext->extLength & (sb->s_blocksize - 1)) { | ||
384 | last_ext->extLength = | ||
385 | (last_ext->extLength & UDF_EXTENT_FLAG_MASK) | | ||
386 | (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) + | ||
387 | sb->s_blocksize - 1) & ~(sb->s_blocksize - 1)); | ||
388 | UDF_I_LENEXTENTS(inode) = | ||
389 | (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) & | ||
390 | ~(sb->s_blocksize - 1); | ||
391 | } | ||
392 | /* Last extent are just preallocated blocks? */ | ||
393 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) { | ||
394 | /* Save the extent so that we can reattach it to the end */ | ||
395 | prealloc_loc = last_ext->extLocation; | ||
396 | prealloc_len = last_ext->extLength; | ||
397 | /* Mark the extent as a hole */ | ||
398 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
399 | (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); | ||
400 | last_ext->extLocation.logicalBlockNum = 0; | ||
401 | last_ext->extLocation.partitionReferenceNum = 0; | ||
402 | } | ||
403 | /* Can we merge with the previous extent? */ | ||
404 | if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) { | ||
405 | add = ((1<<30) - sb->s_blocksize - (last_ext->extLength & | ||
406 | UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits; | ||
407 | if (add > blocks) | ||
408 | add = blocks; | ||
409 | blocks -= add; | ||
410 | last_ext->extLength += add << sb->s_blocksize_bits; | ||
411 | } | ||
412 | |||
413 | if (fake) { | ||
414 | udf_add_aext(inode, last_pos, last_ext->extLocation, | ||
415 | last_ext->extLength, 1); | ||
416 | count++; | ||
417 | } | ||
418 | else | ||
419 | udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1); | ||
420 | /* Managed to do everything necessary? */ | ||
421 | if (!blocks) | ||
422 | goto out; | ||
423 | |||
424 | /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ | ||
425 | last_ext->extLocation.logicalBlockNum = 0; | ||
426 | last_ext->extLocation.partitionReferenceNum = 0; | ||
427 | add = (1 << (30-sb->s_blocksize_bits)) - 1; | ||
428 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits); | ||
429 | /* Create enough extents to cover the whole hole */ | ||
430 | while (blocks > add) { | ||
431 | blocks -= add; | ||
432 | if (udf_add_aext(inode, last_pos, last_ext->extLocation, | ||
433 | last_ext->extLength, 1) == -1) | ||
434 | return -1; | ||
435 | count++; | ||
436 | } | ||
437 | if (blocks) { | ||
438 | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
439 | (blocks << sb->s_blocksize_bits); | ||
440 | if (udf_add_aext(inode, last_pos, last_ext->extLocation, | ||
441 | last_ext->extLength, 1) == -1) | ||
442 | return -1; | ||
443 | count++; | ||
444 | } | ||
445 | out: | ||
446 | /* Do we have some preallocated blocks saved? */ | ||
447 | if (prealloc_len) { | ||
448 | if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1) | ||
449 | return -1; | ||
450 | last_ext->extLocation = prealloc_loc; | ||
451 | last_ext->extLength = prealloc_len; | ||
452 | count++; | ||
453 | } | ||
454 | /* last_pos should point to the last written extent... */ | ||
455 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | ||
456 | last_pos->offset -= sizeof(short_ad); | ||
457 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | ||
458 | last_pos->offset -= sizeof(long_ad); | ||
459 | else | ||
460 | return -1; | ||
461 | return count; | ||
462 | } | ||
463 | |||
464 | static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | ||
358 | int *err, long *phys, int *new) | 465 | int *err, long *phys, int *new) |
359 | { | 466 | { |
360 | struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL; | 467 | static sector_t last_block; |
468 | struct buffer_head *result = NULL; | ||
361 | kernel_long_ad laarr[EXTENT_MERGE_SIZE]; | 469 | kernel_long_ad laarr[EXTENT_MERGE_SIZE]; |
362 | uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0; | 470 | struct extent_position prev_epos, cur_epos, next_epos; |
363 | int count = 0, startnum = 0, endnum = 0; | 471 | int count = 0, startnum = 0, endnum = 0; |
364 | uint32_t elen = 0; | 472 | uint32_t elen = 0, tmpelen; |
365 | kernel_lb_addr eloc, pbloc, cbloc, nbloc; | 473 | kernel_lb_addr eloc, tmpeloc; |
366 | int c = 1; | 474 | int c = 1; |
367 | uint64_t lbcount = 0, b_off = 0; | 475 | loff_t lbcount = 0, b_off = 0; |
368 | uint32_t newblocknum, newblock, offset = 0; | 476 | uint32_t newblocknum, newblock; |
477 | sector_t offset = 0; | ||
369 | int8_t etype; | 478 | int8_t etype; |
370 | int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; | 479 | int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; |
371 | char lastblock = 0; | 480 | int lastblock = 0; |
372 | 481 | ||
373 | pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode); | 482 | prev_epos.offset = udf_file_entry_alloc_offset(inode); |
374 | b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits; | 483 | prev_epos.block = UDF_I_LOCATION(inode); |
375 | pbloc = cbloc = nbloc = UDF_I_LOCATION(inode); | 484 | prev_epos.bh = NULL; |
485 | cur_epos = next_epos = prev_epos; | ||
486 | b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; | ||
376 | 487 | ||
377 | /* find the extent which contains the block we are looking for. | 488 | /* find the extent which contains the block we are looking for. |
378 | alternate between laarr[0] and laarr[1] for locations of the | 489 | alternate between laarr[0] and laarr[1] for locations of the |
379 | current extent, and the previous extent */ | 490 | current extent, and the previous extent */ |
380 | do | 491 | do |
381 | { | 492 | { |
382 | if (pbh != cbh) | 493 | if (prev_epos.bh != cur_epos.bh) |
383 | { | 494 | { |
384 | udf_release_data(pbh); | 495 | brelse(prev_epos.bh); |
385 | atomic_inc(&cbh->b_count); | 496 | get_bh(cur_epos.bh); |
386 | pbh = cbh; | 497 | prev_epos.bh = cur_epos.bh; |
387 | } | 498 | } |
388 | if (cbh != nbh) | 499 | if (cur_epos.bh != next_epos.bh) |
389 | { | 500 | { |
390 | udf_release_data(cbh); | 501 | brelse(cur_epos.bh); |
391 | atomic_inc(&nbh->b_count); | 502 | get_bh(next_epos.bh); |
392 | cbh = nbh; | 503 | cur_epos.bh = next_epos.bh; |
393 | } | 504 | } |
394 | 505 | ||
395 | lbcount += elen; | 506 | lbcount += elen; |
396 | 507 | ||
397 | pbloc = cbloc; | 508 | prev_epos.block = cur_epos.block; |
398 | cbloc = nbloc; | 509 | cur_epos.block = next_epos.block; |
399 | 510 | ||
400 | pextoffset = cextoffset; | 511 | prev_epos.offset = cur_epos.offset; |
401 | cextoffset = nextoffset; | 512 | cur_epos.offset = next_epos.offset; |
402 | 513 | ||
403 | if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1) | 514 | if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1) |
404 | break; | 515 | break; |
405 | 516 | ||
406 | c = !c; | 517 | c = !c; |
@@ -418,6 +529,12 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
418 | 529 | ||
419 | b_off -= lbcount; | 530 | b_off -= lbcount; |
420 | offset = b_off >> inode->i_sb->s_blocksize_bits; | 531 | offset = b_off >> inode->i_sb->s_blocksize_bits; |
532 | /* | ||
533 | * Move prev_epos and cur_epos into indirect extent if we are at | ||
534 | * the pointer to it | ||
535 | */ | ||
536 | udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0); | ||
537 | udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); | ||
421 | 538 | ||
422 | /* if the extent is allocated and recorded, return the block | 539 | /* if the extent is allocated and recorded, return the block |
423 | if the extent is not a multiple of the blocksize, round up */ | 540 | if the extent is not a multiple of the blocksize, round up */ |
@@ -429,54 +546,77 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
429 | elen = EXT_RECORDED_ALLOCATED | | 546 | elen = EXT_RECORDED_ALLOCATED | |
430 | ((elen + inode->i_sb->s_blocksize - 1) & | 547 | ((elen + inode->i_sb->s_blocksize - 1) & |
431 | ~(inode->i_sb->s_blocksize - 1)); | 548 | ~(inode->i_sb->s_blocksize - 1)); |
432 | etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1); | 549 | etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1); |
433 | } | 550 | } |
434 | udf_release_data(pbh); | 551 | brelse(prev_epos.bh); |
435 | udf_release_data(cbh); | 552 | brelse(cur_epos.bh); |
436 | udf_release_data(nbh); | 553 | brelse(next_epos.bh); |
437 | newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); | 554 | newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
438 | *phys = newblock; | 555 | *phys = newblock; |
439 | return NULL; | 556 | return NULL; |
440 | } | 557 | } |
441 | 558 | ||
559 | last_block = block; | ||
560 | /* Are we beyond EOF? */ | ||
442 | if (etype == -1) | 561 | if (etype == -1) |
443 | { | 562 | { |
444 | endnum = startnum = ((count > 1) ? 1 : count); | 563 | int ret; |
445 | if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1)) | 564 | |
446 | { | 565 | if (count) { |
447 | laarr[c].extLength = | 566 | if (c) |
448 | (laarr[c].extLength & UDF_EXTENT_FLAG_MASK) | | 567 | laarr[0] = laarr[1]; |
449 | (((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) + | 568 | startnum = 1; |
450 | inode->i_sb->s_blocksize - 1) & | 569 | } |
451 | ~(inode->i_sb->s_blocksize - 1)); | 570 | else { |
452 | UDF_I_LENEXTENTS(inode) = | 571 | /* Create a fake extent when there's not one */ |
453 | (UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) & | 572 | memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr)); |
454 | ~(inode->i_sb->s_blocksize - 1); | 573 | laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; |
574 | /* Will udf_extend_file() create real extent from a fake one? */ | ||
575 | startnum = (offset > 0); | ||
576 | } | ||
577 | /* Create extents for the hole between EOF and offset */ | ||
578 | ret = udf_extend_file(inode, &prev_epos, laarr, offset); | ||
579 | if (ret == -1) { | ||
580 | brelse(prev_epos.bh); | ||
581 | brelse(cur_epos.bh); | ||
582 | brelse(next_epos.bh); | ||
583 | /* We don't really know the error here so we just make | ||
584 | * something up */ | ||
585 | *err = -ENOSPC; | ||
586 | return NULL; | ||
455 | } | 587 | } |
456 | c = !c; | 588 | c = 0; |
457 | laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | 589 | offset = 0; |
458 | ((offset + 1) << inode->i_sb->s_blocksize_bits); | 590 | count += ret; |
459 | memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); | 591 | /* We are not covered by a preallocated extent? */ |
460 | count ++; | 592 | if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) { |
461 | endnum ++; | 593 | /* Is there any real extent? - otherwise we overwrite |
594 | * the fake one... */ | ||
595 | if (count) | ||
596 | c = !c; | ||
597 | laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
598 | inode->i_sb->s_blocksize; | ||
599 | memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); | ||
600 | count ++; | ||
601 | endnum ++; | ||
602 | } | ||
603 | endnum = c+1; | ||
462 | lastblock = 1; | 604 | lastblock = 1; |
463 | } | 605 | } |
464 | else | 606 | else { |
465 | endnum = startnum = ((count > 2) ? 2 : count); | 607 | endnum = startnum = ((count > 2) ? 2 : count); |
466 | 608 | ||
467 | /* if the current extent is in position 0, swap it with the previous */ | 609 | /* if the current extent is in position 0, swap it with the previous */ |
468 | if (!c && count != 1) | 610 | if (!c && count != 1) |
469 | { | 611 | { |
470 | laarr[2] = laarr[0]; | 612 | laarr[2] = laarr[0]; |
471 | laarr[0] = laarr[1]; | 613 | laarr[0] = laarr[1]; |
472 | laarr[1] = laarr[2]; | 614 | laarr[1] = laarr[2]; |
473 | c = 1; | 615 | c = 1; |
474 | } | 616 | } |
475 | 617 | ||
476 | /* if the current block is located in a extent, read the next extent */ | 618 | /* if the current block is located in an extent, read the next extent */ |
477 | if (etype != -1) | 619 | if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) |
478 | { | ||
479 | if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1) | ||
480 | { | 620 | { |
481 | laarr[c+1].extLength = (etype << 30) | elen; | 621 | laarr[c+1].extLength = (etype << 30) | elen; |
482 | laarr[c+1].extLocation = eloc; | 622 | laarr[c+1].extLocation = eloc; |
@@ -484,11 +624,10 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
484 | startnum ++; | 624 | startnum ++; |
485 | endnum ++; | 625 | endnum ++; |
486 | } | 626 | } |
487 | else | 627 | else { |
488 | lastblock = 1; | 628 | lastblock = 1; |
629 | } | ||
489 | } | 630 | } |
490 | udf_release_data(cbh); | ||
491 | udf_release_data(nbh); | ||
492 | 631 | ||
493 | /* if the current extent is not recorded but allocated, get the | 632 | /* if the current extent is not recorded but allocated, get the |
494 | block in the extent corresponding to the requested block */ | 633 | block in the extent corresponding to the requested block */ |
@@ -508,7 +647,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
508 | if (!(newblocknum = udf_new_block(inode->i_sb, inode, | 647 | if (!(newblocknum = udf_new_block(inode->i_sb, inode, |
509 | UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) | 648 | UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) |
510 | { | 649 | { |
511 | udf_release_data(pbh); | 650 | brelse(prev_epos.bh); |
512 | *err = -ENOSPC; | 651 | *err = -ENOSPC; |
513 | return NULL; | 652 | return NULL; |
514 | } | 653 | } |
@@ -529,11 +668,11 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block, | |||
529 | udf_merge_extents(inode, laarr, &endnum); | 668 | udf_merge_extents(inode, laarr, &endnum); |
530 | 669 | ||
531 | /* write back the new extents, inserting new extents if the new number | 670 | /* write back the new extents, inserting new extents if the new number |
532 | of extents is greater than the old number, and deleting extents if | 671 | of extents is greater than the old number, and deleting extents if |
533 | the new number of extents is less than the old number */ | 672 | the new number of extents is less than the old number */ |
534 | udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh); | 673 | udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); |
535 | 674 | ||
536 | udf_release_data(pbh); | 675 | brelse(prev_epos.bh); |
537 | 676 | ||
538 | if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, | 677 | if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, |
539 | UDF_I_LOCATION(inode).partitionReferenceNum, 0))) | 678 | UDF_I_LOCATION(inode).partitionReferenceNum, 0))) |
@@ -795,7 +934,7 @@ static void udf_merge_extents(struct inode *inode, | |||
795 | 934 | ||
796 | static void udf_update_extents(struct inode *inode, | 935 | static void udf_update_extents(struct inode *inode, |
797 | kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, | 936 | kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, |
798 | kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh) | 937 | struct extent_position *epos) |
799 | { | 938 | { |
800 | int start = 0, i; | 939 | int start = 0, i; |
801 | kernel_lb_addr tmploc; | 940 | kernel_lb_addr tmploc; |
@@ -804,28 +943,26 @@ static void udf_update_extents(struct inode *inode, | |||
804 | if (startnum > endnum) | 943 | if (startnum > endnum) |
805 | { | 944 | { |
806 | for (i=0; i<(startnum-endnum); i++) | 945 | for (i=0; i<(startnum-endnum); i++) |
807 | { | 946 | udf_delete_aext(inode, *epos, laarr[i].extLocation, |
808 | udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation, | 947 | laarr[i].extLength); |
809 | laarr[i].extLength, *pbh); | ||
810 | } | ||
811 | } | 948 | } |
812 | else if (startnum < endnum) | 949 | else if (startnum < endnum) |
813 | { | 950 | { |
814 | for (i=0; i<(endnum-startnum); i++) | 951 | for (i=0; i<(endnum-startnum); i++) |
815 | { | 952 | { |
816 | udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation, | 953 | udf_insert_aext(inode, *epos, laarr[i].extLocation, |
817 | laarr[i].extLength, *pbh); | 954 | laarr[i].extLength); |
818 | udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation, | 955 | udf_next_aext(inode, epos, &laarr[i].extLocation, |
819 | &laarr[i].extLength, pbh, 1); | 956 | &laarr[i].extLength, 1); |
820 | start ++; | 957 | start ++; |
821 | } | 958 | } |
822 | } | 959 | } |
823 | 960 | ||
824 | for (i=start; i<endnum; i++) | 961 | for (i=start; i<endnum; i++) |
825 | { | 962 | { |
826 | udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0); | 963 | udf_next_aext(inode, epos, &tmploc, &tmplen, 0); |
827 | udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation, | 964 | udf_write_aext(inode, epos, laarr[i].extLocation, |
828 | laarr[i].extLength, *pbh, 1); | 965 | laarr[i].extLength, 1); |
829 | } | 966 | } |
830 | } | 967 | } |
831 | 968 | ||
@@ -931,7 +1068,7 @@ __udf_read_inode(struct inode *inode) | |||
931 | { | 1068 | { |
932 | printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", | 1069 | printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", |
933 | inode->i_ino, ident); | 1070 | inode->i_ino, ident); |
934 | udf_release_data(bh); | 1071 | brelse(bh); |
935 | make_bad_inode(inode); | 1072 | make_bad_inode(inode); |
936 | return; | 1073 | return; |
937 | } | 1074 | } |
@@ -960,35 +1097,36 @@ __udf_read_inode(struct inode *inode) | |||
960 | ident == TAG_IDENT_EFE) | 1097 | ident == TAG_IDENT_EFE) |
961 | { | 1098 | { |
962 | memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); | 1099 | memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); |
963 | udf_release_data(bh); | 1100 | brelse(bh); |
964 | udf_release_data(ibh); | 1101 | brelse(ibh); |
965 | udf_release_data(nbh); | 1102 | brelse(nbh); |
966 | __udf_read_inode(inode); | 1103 | __udf_read_inode(inode); |
967 | return; | 1104 | return; |
968 | } | 1105 | } |
969 | else | 1106 | else |
970 | { | 1107 | { |
971 | udf_release_data(nbh); | 1108 | brelse(nbh); |
972 | udf_release_data(ibh); | 1109 | brelse(ibh); |
973 | } | 1110 | } |
974 | } | 1111 | } |
975 | else | 1112 | else |
976 | udf_release_data(ibh); | 1113 | brelse(ibh); |
977 | } | 1114 | } |
978 | } | 1115 | } |
979 | else | 1116 | else |
980 | udf_release_data(ibh); | 1117 | brelse(ibh); |
981 | } | 1118 | } |
982 | else if (le16_to_cpu(fe->icbTag.strategyType) != 4) | 1119 | else if (le16_to_cpu(fe->icbTag.strategyType) != 4) |
983 | { | 1120 | { |
984 | printk(KERN_ERR "udf: unsupported strategy type: %d\n", | 1121 | printk(KERN_ERR "udf: unsupported strategy type: %d\n", |
985 | le16_to_cpu(fe->icbTag.strategyType)); | 1122 | le16_to_cpu(fe->icbTag.strategyType)); |
986 | udf_release_data(bh); | 1123 | brelse(bh); |
987 | make_bad_inode(inode); | 1124 | make_bad_inode(inode); |
988 | return; | 1125 | return; |
989 | } | 1126 | } |
990 | udf_fill_inode(inode, bh); | 1127 | udf_fill_inode(inode, bh); |
991 | udf_release_data(bh); | 1128 | |
1129 | brelse(bh); | ||
992 | } | 1130 | } |
993 | 1131 | ||
994 | static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | 1132 | static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) |
@@ -1331,7 +1469,7 @@ udf_update_inode(struct inode *inode, int do_sync) | |||
1331 | use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; | 1469 | use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; |
1332 | 1470 | ||
1333 | mark_buffer_dirty(bh); | 1471 | mark_buffer_dirty(bh); |
1334 | udf_release_data(bh); | 1472 | brelse(bh); |
1335 | return err; | 1473 | return err; |
1336 | } | 1474 | } |
1337 | 1475 | ||
@@ -1520,7 +1658,7 @@ udf_update_inode(struct inode *inode, int do_sync) | |||
1520 | err = -EIO; | 1658 | err = -EIO; |
1521 | } | 1659 | } |
1522 | } | 1660 | } |
1523 | udf_release_data(bh); | 1661 | brelse(bh); |
1524 | return err; | 1662 | return err; |
1525 | } | 1663 | } |
1526 | 1664 | ||
@@ -1556,8 +1694,8 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino) | |||
1556 | return NULL; | 1694 | return NULL; |
1557 | } | 1695 | } |
1558 | 1696 | ||
1559 | int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1697 | int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, |
1560 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) | 1698 | kernel_lb_addr eloc, uint32_t elen, int inc) |
1561 | { | 1699 | { |
1562 | int adsize; | 1700 | int adsize; |
1563 | short_ad *sad = NULL; | 1701 | short_ad *sad = NULL; |
@@ -1566,10 +1704,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1566 | int8_t etype; | 1704 | int8_t etype; |
1567 | uint8_t *ptr; | 1705 | uint8_t *ptr; |
1568 | 1706 | ||
1569 | if (!*bh) | 1707 | if (!epos->bh) |
1570 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1708 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1571 | else | 1709 | else |
1572 | ptr = (*bh)->b_data + *extoffset; | 1710 | ptr = epos->bh->b_data + epos->offset; |
1573 | 1711 | ||
1574 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 1712 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
1575 | adsize = sizeof(short_ad); | 1713 | adsize = sizeof(short_ad); |
@@ -1578,20 +1716,20 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1578 | else | 1716 | else |
1579 | return -1; | 1717 | return -1; |
1580 | 1718 | ||
1581 | if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize) | 1719 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) |
1582 | { | 1720 | { |
1583 | char *sptr, *dptr; | 1721 | char *sptr, *dptr; |
1584 | struct buffer_head *nbh; | 1722 | struct buffer_head *nbh; |
1585 | int err, loffset; | 1723 | int err, loffset; |
1586 | kernel_lb_addr obloc = *bloc; | 1724 | kernel_lb_addr obloc = epos->block; |
1587 | 1725 | ||
1588 | if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL, | 1726 | if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, |
1589 | obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) | 1727 | obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) |
1590 | { | 1728 | { |
1591 | return -1; | 1729 | return -1; |
1592 | } | 1730 | } |
1593 | if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, | 1731 | if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, |
1594 | *bloc, 0)))) | 1732 | epos->block, 0)))) |
1595 | { | 1733 | { |
1596 | return -1; | 1734 | return -1; |
1597 | } | 1735 | } |
@@ -1604,25 +1742,25 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1604 | aed = (struct allocExtDesc *)(nbh->b_data); | 1742 | aed = (struct allocExtDesc *)(nbh->b_data); |
1605 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) | 1743 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) |
1606 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); | 1744 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); |
1607 | if (*extoffset + adsize > inode->i_sb->s_blocksize) | 1745 | if (epos->offset + adsize > inode->i_sb->s_blocksize) |
1608 | { | 1746 | { |
1609 | loffset = *extoffset; | 1747 | loffset = epos->offset; |
1610 | aed->lengthAllocDescs = cpu_to_le32(adsize); | 1748 | aed->lengthAllocDescs = cpu_to_le32(adsize); |
1611 | sptr = ptr - adsize; | 1749 | sptr = ptr - adsize; |
1612 | dptr = nbh->b_data + sizeof(struct allocExtDesc); | 1750 | dptr = nbh->b_data + sizeof(struct allocExtDesc); |
1613 | memcpy(dptr, sptr, adsize); | 1751 | memcpy(dptr, sptr, adsize); |
1614 | *extoffset = sizeof(struct allocExtDesc) + adsize; | 1752 | epos->offset = sizeof(struct allocExtDesc) + adsize; |
1615 | } | 1753 | } |
1616 | else | 1754 | else |
1617 | { | 1755 | { |
1618 | loffset = *extoffset + adsize; | 1756 | loffset = epos->offset + adsize; |
1619 | aed->lengthAllocDescs = cpu_to_le32(0); | 1757 | aed->lengthAllocDescs = cpu_to_le32(0); |
1620 | sptr = ptr; | 1758 | sptr = ptr; |
1621 | *extoffset = sizeof(struct allocExtDesc); | 1759 | epos->offset = sizeof(struct allocExtDesc); |
1622 | 1760 | ||
1623 | if (*bh) | 1761 | if (epos->bh) |
1624 | { | 1762 | { |
1625 | aed = (struct allocExtDesc *)(*bh)->b_data; | 1763 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1626 | aed->lengthAllocDescs = | 1764 | aed->lengthAllocDescs = |
1627 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 1765 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1628 | } | 1766 | } |
@@ -1634,10 +1772,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1634 | } | 1772 | } |
1635 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) | 1773 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) |
1636 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, | 1774 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, |
1637 | bloc->logicalBlockNum, sizeof(tag)); | 1775 | epos->block.logicalBlockNum, sizeof(tag)); |
1638 | else | 1776 | else |
1639 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, | 1777 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, |
1640 | bloc->logicalBlockNum, sizeof(tag)); | 1778 | epos->block.logicalBlockNum, sizeof(tag)); |
1641 | switch (UDF_I_ALLOCTYPE(inode)) | 1779 | switch (UDF_I_ALLOCTYPE(inode)) |
1642 | { | 1780 | { |
1643 | case ICBTAG_FLAG_AD_SHORT: | 1781 | case ICBTAG_FLAG_AD_SHORT: |
@@ -1646,7 +1784,7 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1646 | sad->extLength = cpu_to_le32( | 1784 | sad->extLength = cpu_to_le32( |
1647 | EXT_NEXT_EXTENT_ALLOCDECS | | 1785 | EXT_NEXT_EXTENT_ALLOCDECS | |
1648 | inode->i_sb->s_blocksize); | 1786 | inode->i_sb->s_blocksize); |
1649 | sad->extPosition = cpu_to_le32(bloc->logicalBlockNum); | 1787 | sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum); |
1650 | break; | 1788 | break; |
1651 | } | 1789 | } |
1652 | case ICBTAG_FLAG_AD_LONG: | 1790 | case ICBTAG_FLAG_AD_LONG: |
@@ -1655,60 +1793,57 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1655 | lad->extLength = cpu_to_le32( | 1793 | lad->extLength = cpu_to_le32( |
1656 | EXT_NEXT_EXTENT_ALLOCDECS | | 1794 | EXT_NEXT_EXTENT_ALLOCDECS | |
1657 | inode->i_sb->s_blocksize); | 1795 | inode->i_sb->s_blocksize); |
1658 | lad->extLocation = cpu_to_lelb(*bloc); | 1796 | lad->extLocation = cpu_to_lelb(epos->block); |
1659 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); | 1797 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); |
1660 | break; | 1798 | break; |
1661 | } | 1799 | } |
1662 | } | 1800 | } |
1663 | if (*bh) | 1801 | if (epos->bh) |
1664 | { | 1802 | { |
1665 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1803 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1666 | udf_update_tag((*bh)->b_data, loffset); | 1804 | udf_update_tag(epos->bh->b_data, loffset); |
1667 | else | 1805 | else |
1668 | udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); | 1806 | udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
1669 | mark_buffer_dirty_inode(*bh, inode); | 1807 | mark_buffer_dirty_inode(epos->bh, inode); |
1670 | udf_release_data(*bh); | 1808 | brelse(epos->bh); |
1671 | } | 1809 | } |
1672 | else | 1810 | else |
1673 | mark_inode_dirty(inode); | 1811 | mark_inode_dirty(inode); |
1674 | *bh = nbh; | 1812 | epos->bh = nbh; |
1675 | } | 1813 | } |
1676 | 1814 | ||
1677 | etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc); | 1815 | etype = udf_write_aext(inode, epos, eloc, elen, inc); |
1678 | 1816 | ||
1679 | if (!*bh) | 1817 | if (!epos->bh) |
1680 | { | 1818 | { |
1681 | UDF_I_LENALLOC(inode) += adsize; | 1819 | UDF_I_LENALLOC(inode) += adsize; |
1682 | mark_inode_dirty(inode); | 1820 | mark_inode_dirty(inode); |
1683 | } | 1821 | } |
1684 | else | 1822 | else |
1685 | { | 1823 | { |
1686 | aed = (struct allocExtDesc *)(*bh)->b_data; | 1824 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1687 | aed->lengthAllocDescs = | 1825 | aed->lengthAllocDescs = |
1688 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 1826 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1689 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1827 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1690 | udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize)); | 1828 | udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize)); |
1691 | else | 1829 | else |
1692 | udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); | 1830 | udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
1693 | mark_buffer_dirty_inode(*bh, inode); | 1831 | mark_buffer_dirty_inode(epos->bh, inode); |
1694 | } | 1832 | } |
1695 | 1833 | ||
1696 | return etype; | 1834 | return etype; |
1697 | } | 1835 | } |
1698 | 1836 | ||
1699 | int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, | 1837 | int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, |
1700 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) | 1838 | kernel_lb_addr eloc, uint32_t elen, int inc) |
1701 | { | 1839 | { |
1702 | int adsize; | 1840 | int adsize; |
1703 | uint8_t *ptr; | 1841 | uint8_t *ptr; |
1704 | 1842 | ||
1705 | if (!bh) | 1843 | if (!epos->bh) |
1706 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1844 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1707 | else | 1845 | else |
1708 | { | 1846 | ptr = epos->bh->b_data + epos->offset; |
1709 | ptr = bh->b_data + *extoffset; | ||
1710 | atomic_inc(&bh->b_count); | ||
1711 | } | ||
1712 | 1847 | ||
1713 | switch (UDF_I_ALLOCTYPE(inode)) | 1848 | switch (UDF_I_ALLOCTYPE(inode)) |
1714 | { | 1849 | { |
@@ -1733,40 +1868,39 @@ int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, | |||
1733 | return -1; | 1868 | return -1; |
1734 | } | 1869 | } |
1735 | 1870 | ||
1736 | if (bh) | 1871 | if (epos->bh) |
1737 | { | 1872 | { |
1738 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1873 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1739 | { | 1874 | { |
1740 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data; | 1875 | struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data; |
1741 | udf_update_tag((bh)->b_data, | 1876 | udf_update_tag(epos->bh->b_data, |
1742 | le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); | 1877 | le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); |
1743 | } | 1878 | } |
1744 | mark_buffer_dirty_inode(bh, inode); | 1879 | mark_buffer_dirty_inode(epos->bh, inode); |
1745 | udf_release_data(bh); | ||
1746 | } | 1880 | } |
1747 | else | 1881 | else |
1748 | mark_inode_dirty(inode); | 1882 | mark_inode_dirty(inode); |
1749 | 1883 | ||
1750 | if (inc) | 1884 | if (inc) |
1751 | *extoffset += adsize; | 1885 | epos->offset += adsize; |
1752 | return (elen >> 30); | 1886 | return (elen >> 30); |
1753 | } | 1887 | } |
1754 | 1888 | ||
1755 | int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1889 | int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, |
1756 | kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) | 1890 | kernel_lb_addr *eloc, uint32_t *elen, int inc) |
1757 | { | 1891 | { |
1758 | int8_t etype; | 1892 | int8_t etype; |
1759 | 1893 | ||
1760 | while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) == | 1894 | while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == |
1761 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) | 1895 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
1762 | { | 1896 | { |
1763 | *bloc = *eloc; | 1897 | epos->block = *eloc; |
1764 | *extoffset = sizeof(struct allocExtDesc); | 1898 | epos->offset = sizeof(struct allocExtDesc); |
1765 | udf_release_data(*bh); | 1899 | brelse(epos->bh); |
1766 | if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) | 1900 | if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0)))) |
1767 | { | 1901 | { |
1768 | udf_debug("reading block %d failed!\n", | 1902 | udf_debug("reading block %d failed!\n", |
1769 | udf_get_lb_pblock(inode->i_sb, *bloc, 0)); | 1903 | udf_get_lb_pblock(inode->i_sb, epos->block, 0)); |
1770 | return -1; | 1904 | return -1; |
1771 | } | 1905 | } |
1772 | } | 1906 | } |
@@ -1774,26 +1908,26 @@ int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1774 | return etype; | 1908 | return etype; |
1775 | } | 1909 | } |
1776 | 1910 | ||
1777 | int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1911 | int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, |
1778 | kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) | 1912 | kernel_lb_addr *eloc, uint32_t *elen, int inc) |
1779 | { | 1913 | { |
1780 | int alen; | 1914 | int alen; |
1781 | int8_t etype; | 1915 | int8_t etype; |
1782 | uint8_t *ptr; | 1916 | uint8_t *ptr; |
1783 | 1917 | ||
1784 | if (!*bh) | 1918 | if (!epos->bh) |
1785 | { | 1919 | { |
1786 | if (!(*extoffset)) | 1920 | if (!epos->offset) |
1787 | *extoffset = udf_file_entry_alloc_offset(inode); | 1921 | epos->offset = udf_file_entry_alloc_offset(inode); |
1788 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1922 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1789 | alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); | 1923 | alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); |
1790 | } | 1924 | } |
1791 | else | 1925 | else |
1792 | { | 1926 | { |
1793 | if (!(*extoffset)) | 1927 | if (!epos->offset) |
1794 | *extoffset = sizeof(struct allocExtDesc); | 1928 | epos->offset = sizeof(struct allocExtDesc); |
1795 | ptr = (*bh)->b_data + *extoffset; | 1929 | ptr = epos->bh->b_data + epos->offset; |
1796 | alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); | 1930 | alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs); |
1797 | } | 1931 | } |
1798 | 1932 | ||
1799 | switch (UDF_I_ALLOCTYPE(inode)) | 1933 | switch (UDF_I_ALLOCTYPE(inode)) |
@@ -1802,7 +1936,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1802 | { | 1936 | { |
1803 | short_ad *sad; | 1937 | short_ad *sad; |
1804 | 1938 | ||
1805 | if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc))) | 1939 | if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc))) |
1806 | return -1; | 1940 | return -1; |
1807 | 1941 | ||
1808 | etype = le32_to_cpu(sad->extLength) >> 30; | 1942 | etype = le32_to_cpu(sad->extLength) >> 30; |
@@ -1815,7 +1949,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1815 | { | 1949 | { |
1816 | long_ad *lad; | 1950 | long_ad *lad; |
1817 | 1951 | ||
1818 | if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc))) | 1952 | if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc))) |
1819 | return -1; | 1953 | return -1; |
1820 | 1954 | ||
1821 | etype = le32_to_cpu(lad->extLength) >> 30; | 1955 | etype = le32_to_cpu(lad->extLength) >> 30; |
@@ -1834,41 +1968,40 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1834 | } | 1968 | } |
1835 | 1969 | ||
1836 | static int8_t | 1970 | static int8_t |
1837 | udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset, | 1971 | udf_insert_aext(struct inode *inode, struct extent_position epos, |
1838 | kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh) | 1972 | kernel_lb_addr neloc, uint32_t nelen) |
1839 | { | 1973 | { |
1840 | kernel_lb_addr oeloc; | 1974 | kernel_lb_addr oeloc; |
1841 | uint32_t oelen; | 1975 | uint32_t oelen; |
1842 | int8_t etype; | 1976 | int8_t etype; |
1843 | 1977 | ||
1844 | if (bh) | 1978 | if (epos.bh) |
1845 | atomic_inc(&bh->b_count); | 1979 | get_bh(epos.bh); |
1846 | 1980 | ||
1847 | while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1) | 1981 | while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) |
1848 | { | 1982 | { |
1849 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); | 1983 | udf_write_aext(inode, &epos, neloc, nelen, 1); |
1850 | 1984 | ||
1851 | neloc = oeloc; | 1985 | neloc = oeloc; |
1852 | nelen = (etype << 30) | oelen; | 1986 | nelen = (etype << 30) | oelen; |
1853 | } | 1987 | } |
1854 | udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1); | 1988 | udf_add_aext(inode, &epos, neloc, nelen, 1); |
1855 | udf_release_data(bh); | 1989 | brelse(epos.bh); |
1856 | return (nelen >> 30); | 1990 | return (nelen >> 30); |
1857 | } | 1991 | } |
1858 | 1992 | ||
1859 | int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset, | 1993 | int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, |
1860 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh) | 1994 | kernel_lb_addr eloc, uint32_t elen) |
1861 | { | 1995 | { |
1862 | struct buffer_head *obh; | 1996 | struct extent_position oepos; |
1863 | kernel_lb_addr obloc; | 1997 | int adsize; |
1864 | int oextoffset, adsize; | ||
1865 | int8_t etype; | 1998 | int8_t etype; |
1866 | struct allocExtDesc *aed; | 1999 | struct allocExtDesc *aed; |
1867 | 2000 | ||
1868 | if (nbh) | 2001 | if (epos.bh) |
1869 | { | 2002 | { |
1870 | atomic_inc(&nbh->b_count); | 2003 | get_bh(epos.bh); |
1871 | atomic_inc(&nbh->b_count); | 2004 | get_bh(epos.bh); |
1872 | } | 2005 | } |
1873 | 2006 | ||
1874 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 2007 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
@@ -1878,80 +2011,77 @@ int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset | |||
1878 | else | 2011 | else |
1879 | adsize = 0; | 2012 | adsize = 0; |
1880 | 2013 | ||
1881 | obh = nbh; | 2014 | oepos = epos; |
1882 | obloc = nbloc; | 2015 | if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) |
1883 | oextoffset = nextoffset; | ||
1884 | |||
1885 | if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1) | ||
1886 | return -1; | 2016 | return -1; |
1887 | 2017 | ||
1888 | while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) | 2018 | while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) |
1889 | { | 2019 | { |
1890 | udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1); | 2020 | udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1); |
1891 | if (obh != nbh) | 2021 | if (oepos.bh != epos.bh) |
1892 | { | 2022 | { |
1893 | obloc = nbloc; | 2023 | oepos.block = epos.block; |
1894 | udf_release_data(obh); | 2024 | brelse(oepos.bh); |
1895 | atomic_inc(&nbh->b_count); | 2025 | get_bh(epos.bh); |
1896 | obh = nbh; | 2026 | oepos.bh = epos.bh; |
1897 | oextoffset = nextoffset - adsize; | 2027 | oepos.offset = epos.offset - adsize; |
1898 | } | 2028 | } |
1899 | } | 2029 | } |
1900 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | 2030 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); |
1901 | elen = 0; | 2031 | elen = 0; |
1902 | 2032 | ||
1903 | if (nbh != obh) | 2033 | if (epos.bh != oepos.bh) |
1904 | { | 2034 | { |
1905 | udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1); | 2035 | udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1); |
1906 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 2036 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1907 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 2037 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1908 | if (!obh) | 2038 | if (!oepos.bh) |
1909 | { | 2039 | { |
1910 | UDF_I_LENALLOC(inode) -= (adsize * 2); | 2040 | UDF_I_LENALLOC(inode) -= (adsize * 2); |
1911 | mark_inode_dirty(inode); | 2041 | mark_inode_dirty(inode); |
1912 | } | 2042 | } |
1913 | else | 2043 | else |
1914 | { | 2044 | { |
1915 | aed = (struct allocExtDesc *)(obh)->b_data; | 2045 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
1916 | aed->lengthAllocDescs = | 2046 | aed->lengthAllocDescs = |
1917 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); | 2047 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); |
1918 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 2048 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1919 | udf_update_tag((obh)->b_data, oextoffset - (2*adsize)); | 2049 | udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize)); |
1920 | else | 2050 | else |
1921 | udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); | 2051 | udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
1922 | mark_buffer_dirty_inode(obh, inode); | 2052 | mark_buffer_dirty_inode(oepos.bh, inode); |
1923 | } | 2053 | } |
1924 | } | 2054 | } |
1925 | else | 2055 | else |
1926 | { | 2056 | { |
1927 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 2057 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1928 | if (!obh) | 2058 | if (!oepos.bh) |
1929 | { | 2059 | { |
1930 | UDF_I_LENALLOC(inode) -= adsize; | 2060 | UDF_I_LENALLOC(inode) -= adsize; |
1931 | mark_inode_dirty(inode); | 2061 | mark_inode_dirty(inode); |
1932 | } | 2062 | } |
1933 | else | 2063 | else |
1934 | { | 2064 | { |
1935 | aed = (struct allocExtDesc *)(obh)->b_data; | 2065 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
1936 | aed->lengthAllocDescs = | 2066 | aed->lengthAllocDescs = |
1937 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); | 2067 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); |
1938 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 2068 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1939 | udf_update_tag((obh)->b_data, oextoffset - adsize); | 2069 | udf_update_tag(oepos.bh->b_data, epos.offset - adsize); |
1940 | else | 2070 | else |
1941 | udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); | 2071 | udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
1942 | mark_buffer_dirty_inode(obh, inode); | 2072 | mark_buffer_dirty_inode(oepos.bh, inode); |
1943 | } | 2073 | } |
1944 | } | 2074 | } |
1945 | 2075 | ||
1946 | udf_release_data(nbh); | 2076 | brelse(epos.bh); |
1947 | udf_release_data(obh); | 2077 | brelse(oepos.bh); |
1948 | return (elen >> 30); | 2078 | return (elen >> 30); |
1949 | } | 2079 | } |
1950 | 2080 | ||
1951 | int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset, | 2081 | int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos, |
1952 | kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh) | 2082 | kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) |
1953 | { | 2083 | { |
1954 | uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits; | 2084 | loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits; |
1955 | int8_t etype; | 2085 | int8_t etype; |
1956 | 2086 | ||
1957 | if (block < 0) | 2087 | if (block < 0) |
@@ -1960,42 +2090,44 @@ int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t | |||
1960 | return -1; | 2090 | return -1; |
1961 | } | 2091 | } |
1962 | 2092 | ||
1963 | *extoffset = 0; | 2093 | pos->offset = 0; |
2094 | pos->block = UDF_I_LOCATION(inode); | ||
2095 | pos->bh = NULL; | ||
1964 | *elen = 0; | 2096 | *elen = 0; |
1965 | *bloc = UDF_I_LOCATION(inode); | ||
1966 | 2097 | ||
1967 | do | 2098 | do |
1968 | { | 2099 | { |
1969 | if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1) | 2100 | if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) |
1970 | { | 2101 | { |
1971 | *offset = bcount - lbcount; | 2102 | *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits; |
1972 | UDF_I_LENEXTENTS(inode) = lbcount; | 2103 | UDF_I_LENEXTENTS(inode) = lbcount; |
1973 | return -1; | 2104 | return -1; |
1974 | } | 2105 | } |
1975 | lbcount += *elen; | 2106 | lbcount += *elen; |
1976 | } while (lbcount <= bcount); | 2107 | } while (lbcount <= bcount); |
1977 | 2108 | ||
1978 | *offset = bcount + *elen - lbcount; | 2109 | *offset = (bcount + *elen - lbcount) >> inode->i_sb->s_blocksize_bits; |
1979 | 2110 | ||
1980 | return etype; | 2111 | return etype; |
1981 | } | 2112 | } |
1982 | 2113 | ||
1983 | long udf_block_map(struct inode *inode, long block) | 2114 | long udf_block_map(struct inode *inode, sector_t block) |
1984 | { | 2115 | { |
1985 | kernel_lb_addr eloc, bloc; | 2116 | kernel_lb_addr eloc; |
1986 | uint32_t offset, extoffset, elen; | 2117 | uint32_t elen; |
1987 | struct buffer_head *bh = NULL; | 2118 | sector_t offset; |
2119 | struct extent_position epos = { NULL, 0, { 0, 0}}; | ||
1988 | int ret; | 2120 | int ret; |
1989 | 2121 | ||
1990 | lock_kernel(); | 2122 | lock_kernel(); |
1991 | 2123 | ||
1992 | if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 2124 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
1993 | ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits); | 2125 | ret = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
1994 | else | 2126 | else |
1995 | ret = 0; | 2127 | ret = 0; |
1996 | 2128 | ||
1997 | unlock_kernel(); | 2129 | unlock_kernel(); |
1998 | udf_release_data(bh); | 2130 | brelse(epos.bh); |
1999 | 2131 | ||
2000 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 2132 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
2001 | return udf_fixed_to_variable(ret); | 2133 | return udf_fixed_to_variable(ret); |
diff --git a/fs/udf/misc.c b/fs/udf/misc.c index cc8ca3254d..a2b2a98ce7 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c | |||
@@ -274,12 +274,6 @@ udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, uint32_t offset, ui | |||
274 | loc.logicalBlockNum + offset, ident); | 274 | loc.logicalBlockNum + offset, ident); |
275 | } | 275 | } |
276 | 276 | ||
277 | void udf_release_data(struct buffer_head *bh) | ||
278 | { | ||
279 | if (bh) | ||
280 | brelse(bh); | ||
281 | } | ||
282 | |||
283 | void udf_update_tag(char *data, int length) | 277 | void udf_update_tag(char *data, int length) |
284 | { | 278 | { |
285 | tag *tptr = (tag *)data; | 279 | tag *tptr = (tag *)data; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index fe361cd19a..51fe307dc0 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/quotaops.h> | 30 | #include <linux/quotaops.h> |
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/buffer_head.h> | 32 | #include <linux/buffer_head.h> |
33 | #include <linux/sched.h> | ||
33 | 34 | ||
34 | static inline int udf_match(int len1, const char *name1, int len2, const char *name2) | 35 | static inline int udf_match(int len1, const char *name1, int len2, const char *name2) |
35 | { | 36 | { |
@@ -155,9 +156,10 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
155 | uint8_t lfi; | 156 | uint8_t lfi; |
156 | uint16_t liu; | 157 | uint16_t liu; |
157 | loff_t size; | 158 | loff_t size; |
158 | kernel_lb_addr bloc, eloc; | 159 | kernel_lb_addr eloc; |
159 | uint32_t extoffset, elen, offset; | 160 | uint32_t elen; |
160 | struct buffer_head *bh = NULL; | 161 | sector_t offset; |
162 | struct extent_position epos = { NULL, 0, { 0, 0}}; | ||
161 | 163 | ||
162 | size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 164 | size = (udf_ext0_offset(dir) + dir->i_size) >> 2; |
163 | f_pos = (udf_ext0_offset(dir) >> 2); | 165 | f_pos = (udf_ext0_offset(dir) >> 2); |
@@ -166,42 +168,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
166 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 168 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
167 | fibh->sbh = fibh->ebh = NULL; | 169 | fibh->sbh = fibh->ebh = NULL; |
168 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), | 170 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), |
169 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 171 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
170 | { | 172 | { |
171 | offset >>= dir->i_sb->s_blocksize_bits; | ||
172 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 173 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
173 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 174 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
174 | { | 175 | { |
175 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 176 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
176 | extoffset -= sizeof(short_ad); | 177 | epos.offset -= sizeof(short_ad); |
177 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 178 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
178 | extoffset -= sizeof(long_ad); | 179 | epos.offset -= sizeof(long_ad); |
179 | } | 180 | } |
180 | else | 181 | else |
181 | offset = 0; | 182 | offset = 0; |
182 | 183 | ||
183 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) | 184 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) |
184 | { | 185 | { |
185 | udf_release_data(bh); | 186 | brelse(epos.bh); |
186 | return NULL; | 187 | return NULL; |
187 | } | 188 | } |
188 | } | 189 | } |
189 | else | 190 | else |
190 | { | 191 | { |
191 | udf_release_data(bh); | 192 | brelse(epos.bh); |
192 | return NULL; | 193 | return NULL; |
193 | } | 194 | } |
194 | 195 | ||
195 | while ( (f_pos < size) ) | 196 | while ( (f_pos < size) ) |
196 | { | 197 | { |
197 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 198 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset); |
198 | 199 | ||
199 | if (!fi) | 200 | if (!fi) |
200 | { | 201 | { |
201 | if (fibh->sbh != fibh->ebh) | 202 | if (fibh->sbh != fibh->ebh) |
202 | udf_release_data(fibh->ebh); | 203 | brelse(fibh->ebh); |
203 | udf_release_data(fibh->sbh); | 204 | brelse(fibh->sbh); |
204 | udf_release_data(bh); | 205 | brelse(epos.bh); |
205 | return NULL; | 206 | return NULL; |
206 | } | 207 | } |
207 | 208 | ||
@@ -247,15 +248,15 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
247 | { | 248 | { |
248 | if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) | 249 | if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) |
249 | { | 250 | { |
250 | udf_release_data(bh); | 251 | brelse(epos.bh); |
251 | return fi; | 252 | return fi; |
252 | } | 253 | } |
253 | } | 254 | } |
254 | } | 255 | } |
255 | if (fibh->sbh != fibh->ebh) | 256 | if (fibh->sbh != fibh->ebh) |
256 | udf_release_data(fibh->ebh); | 257 | brelse(fibh->ebh); |
257 | udf_release_data(fibh->sbh); | 258 | brelse(fibh->sbh); |
258 | udf_release_data(bh); | 259 | brelse(epos.bh); |
259 | return NULL; | 260 | return NULL; |
260 | } | 261 | } |
261 | 262 | ||
@@ -321,8 +322,8 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
321 | if (udf_find_entry(dir, dentry, &fibh, &cfi)) | 322 | if (udf_find_entry(dir, dentry, &fibh, &cfi)) |
322 | { | 323 | { |
323 | if (fibh.sbh != fibh.ebh) | 324 | if (fibh.sbh != fibh.ebh) |
324 | udf_release_data(fibh.ebh); | 325 | brelse(fibh.ebh); |
325 | udf_release_data(fibh.sbh); | 326 | brelse(fibh.sbh); |
326 | 327 | ||
327 | inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); | 328 | inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); |
328 | if ( !inode ) | 329 | if ( !inode ) |
@@ -353,9 +354,10 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
353 | uint8_t lfi; | 354 | uint8_t lfi; |
354 | uint16_t liu; | 355 | uint16_t liu; |
355 | int block; | 356 | int block; |
356 | kernel_lb_addr bloc, eloc; | 357 | kernel_lb_addr eloc; |
357 | uint32_t extoffset, elen, offset; | 358 | uint32_t elen; |
358 | struct buffer_head *bh = NULL; | 359 | sector_t offset; |
360 | struct extent_position epos = { NULL, 0, { 0, 0 }}; | ||
359 | 361 | ||
360 | sb = dir->i_sb; | 362 | sb = dir->i_sb; |
361 | 363 | ||
@@ -384,23 +386,22 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
384 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 386 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
385 | fibh->sbh = fibh->ebh = NULL; | 387 | fibh->sbh = fibh->ebh = NULL; |
386 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), | 388 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), |
387 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 389 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
388 | { | 390 | { |
389 | offset >>= dir->i_sb->s_blocksize_bits; | ||
390 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 391 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
391 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 392 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
392 | { | 393 | { |
393 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 394 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
394 | extoffset -= sizeof(short_ad); | 395 | epos.offset -= sizeof(short_ad); |
395 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 396 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
396 | extoffset -= sizeof(long_ad); | 397 | epos.offset -= sizeof(long_ad); |
397 | } | 398 | } |
398 | else | 399 | else |
399 | offset = 0; | 400 | offset = 0; |
400 | 401 | ||
401 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) | 402 | if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) |
402 | { | 403 | { |
403 | udf_release_data(bh); | 404 | brelse(epos.bh); |
404 | *err = -EIO; | 405 | *err = -EIO; |
405 | return NULL; | 406 | return NULL; |
406 | } | 407 | } |
@@ -418,14 +419,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
418 | 419 | ||
419 | while ( (f_pos < size) ) | 420 | while ( (f_pos < size) ) |
420 | { | 421 | { |
421 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 422 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset); |
422 | 423 | ||
423 | if (!fi) | 424 | if (!fi) |
424 | { | 425 | { |
425 | if (fibh->sbh != fibh->ebh) | 426 | if (fibh->sbh != fibh->ebh) |
426 | udf_release_data(fibh->ebh); | 427 | brelse(fibh->ebh); |
427 | udf_release_data(fibh->sbh); | 428 | brelse(fibh->sbh); |
428 | udf_release_data(bh); | 429 | brelse(epos.bh); |
429 | *err = -EIO; | 430 | *err = -EIO; |
430 | return NULL; | 431 | return NULL; |
431 | } | 432 | } |
@@ -455,7 +456,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
455 | { | 456 | { |
456 | if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) | 457 | if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) |
457 | { | 458 | { |
458 | udf_release_data(bh); | 459 | brelse(epos.bh); |
459 | cfi->descTag.tagSerialNum = cpu_to_le16(1); | 460 | cfi->descTag.tagSerialNum = cpu_to_le16(1); |
460 | cfi->fileVersionNum = cpu_to_le16(1); | 461 | cfi->fileVersionNum = cpu_to_le16(1); |
461 | cfi->fileCharacteristics = 0; | 462 | cfi->fileCharacteristics = 0; |
@@ -478,9 +479,9 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
478 | udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) | 479 | udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) |
479 | { | 480 | { |
480 | if (fibh->sbh != fibh->ebh) | 481 | if (fibh->sbh != fibh->ebh) |
481 | udf_release_data(fibh->ebh); | 482 | brelse(fibh->ebh); |
482 | udf_release_data(fibh->sbh); | 483 | brelse(fibh->sbh); |
483 | udf_release_data(bh); | 484 | brelse(epos.bh); |
484 | *err = -EEXIST; | 485 | *err = -EEXIST; |
485 | return NULL; | 486 | return NULL; |
486 | } | 487 | } |
@@ -492,25 +493,25 @@ add: | |||
492 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB && | 493 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB && |
493 | sb->s_blocksize - fibh->eoffset < nfidlen) | 494 | sb->s_blocksize - fibh->eoffset < nfidlen) |
494 | { | 495 | { |
495 | udf_release_data(bh); | 496 | brelse(epos.bh); |
496 | bh = NULL; | 497 | epos.bh = NULL; |
497 | fibh->soffset -= udf_ext0_offset(dir); | 498 | fibh->soffset -= udf_ext0_offset(dir); |
498 | fibh->eoffset -= udf_ext0_offset(dir); | 499 | fibh->eoffset -= udf_ext0_offset(dir); |
499 | f_pos -= (udf_ext0_offset(dir) >> 2); | 500 | f_pos -= (udf_ext0_offset(dir) >> 2); |
500 | if (fibh->sbh != fibh->ebh) | 501 | if (fibh->sbh != fibh->ebh) |
501 | udf_release_data(fibh->ebh); | 502 | brelse(fibh->ebh); |
502 | udf_release_data(fibh->sbh); | 503 | brelse(fibh->sbh); |
503 | if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) | 504 | if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) |
504 | return NULL; | 505 | return NULL; |
505 | bloc = UDF_I_LOCATION(dir); | 506 | epos.block = UDF_I_LOCATION(dir); |
506 | eloc.logicalBlockNum = block; | 507 | eloc.logicalBlockNum = block; |
507 | eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; | 508 | eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; |
508 | elen = dir->i_sb->s_blocksize; | 509 | elen = dir->i_sb->s_blocksize; |
509 | extoffset = udf_file_entry_alloc_offset(dir); | 510 | epos.offset = udf_file_entry_alloc_offset(dir); |
510 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 511 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
511 | extoffset += sizeof(short_ad); | 512 | epos.offset += sizeof(short_ad); |
512 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 513 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
513 | extoffset += sizeof(long_ad); | 514 | epos.offset += sizeof(long_ad); |
514 | } | 515 | } |
515 | 516 | ||
516 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) | 517 | if (sb->s_blocksize - fibh->eoffset >= nfidlen) |
@@ -519,7 +520,7 @@ add: | |||
519 | fibh->eoffset += nfidlen; | 520 | fibh->eoffset += nfidlen; |
520 | if (fibh->sbh != fibh->ebh) | 521 | if (fibh->sbh != fibh->ebh) |
521 | { | 522 | { |
522 | udf_release_data(fibh->sbh); | 523 | brelse(fibh->sbh); |
523 | fibh->sbh = fibh->ebh; | 524 | fibh->sbh = fibh->ebh; |
524 | } | 525 | } |
525 | 526 | ||
@@ -541,7 +542,7 @@ add: | |||
541 | fibh->eoffset += nfidlen - sb->s_blocksize; | 542 | fibh->eoffset += nfidlen - sb->s_blocksize; |
542 | if (fibh->sbh != fibh->ebh) | 543 | if (fibh->sbh != fibh->ebh) |
543 | { | 544 | { |
544 | udf_release_data(fibh->sbh); | 545 | brelse(fibh->sbh); |
545 | fibh->sbh = fibh->ebh; | 546 | fibh->sbh = fibh->ebh; |
546 | } | 547 | } |
547 | 548 | ||
@@ -550,14 +551,14 @@ add: | |||
550 | 551 | ||
551 | if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err))) | 552 | if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err))) |
552 | { | 553 | { |
553 | udf_release_data(bh); | 554 | brelse(epos.bh); |
554 | udf_release_data(fibh->sbh); | 555 | brelse(fibh->sbh); |
555 | return NULL; | 556 | return NULL; |
556 | } | 557 | } |
557 | 558 | ||
558 | if (!(fibh->soffset)) | 559 | if (!(fibh->soffset)) |
559 | { | 560 | { |
560 | if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) == | 561 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
561 | (EXT_RECORDED_ALLOCATED >> 30)) | 562 | (EXT_RECORDED_ALLOCATED >> 30)) |
562 | { | 563 | { |
563 | block = eloc.logicalBlockNum + ((elen - 1) >> | 564 | block = eloc.logicalBlockNum + ((elen - 1) >> |
@@ -566,7 +567,7 @@ add: | |||
566 | else | 567 | else |
567 | block ++; | 568 | block ++; |
568 | 569 | ||
569 | udf_release_data(fibh->sbh); | 570 | brelse(fibh->sbh); |
570 | fibh->sbh = fibh->ebh; | 571 | fibh->sbh = fibh->ebh; |
571 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); | 572 | fi = (struct fileIdentDesc *)(fibh->sbh->b_data); |
572 | } | 573 | } |
@@ -587,7 +588,7 @@ add: | |||
587 | cfi->lengthOfImpUse = cpu_to_le16(0); | 588 | cfi->lengthOfImpUse = cpu_to_le16(0); |
588 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) | 589 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) |
589 | { | 590 | { |
590 | udf_release_data(bh); | 591 | brelse(epos.bh); |
591 | dir->i_size += nfidlen; | 592 | dir->i_size += nfidlen; |
592 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 593 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
593 | UDF_I_LENALLOC(dir) += nfidlen; | 594 | UDF_I_LENALLOC(dir) += nfidlen; |
@@ -596,10 +597,10 @@ add: | |||
596 | } | 597 | } |
597 | else | 598 | else |
598 | { | 599 | { |
599 | udf_release_data(bh); | 600 | brelse(epos.bh); |
600 | if (fibh->sbh != fibh->ebh) | 601 | if (fibh->sbh != fibh->ebh) |
601 | udf_release_data(fibh->ebh); | 602 | brelse(fibh->ebh); |
602 | udf_release_data(fibh->sbh); | 603 | brelse(fibh->sbh); |
603 | *err = -EIO; | 604 | *err = -EIO; |
604 | return NULL; | 605 | return NULL; |
605 | } | 606 | } |
@@ -656,8 +657,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct | |||
656 | mark_inode_dirty(dir); | 657 | mark_inode_dirty(dir); |
657 | } | 658 | } |
658 | if (fibh.sbh != fibh.ebh) | 659 | if (fibh.sbh != fibh.ebh) |
659 | udf_release_data(fibh.ebh); | 660 | brelse(fibh.ebh); |
660 | udf_release_data(fibh.sbh); | 661 | brelse(fibh.sbh); |
661 | unlock_kernel(); | 662 | unlock_kernel(); |
662 | d_instantiate(dentry, inode); | 663 | d_instantiate(dentry, inode); |
663 | return 0; | 664 | return 0; |
@@ -701,8 +702,8 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t | |||
701 | mark_inode_dirty(inode); | 702 | mark_inode_dirty(inode); |
702 | 703 | ||
703 | if (fibh.sbh != fibh.ebh) | 704 | if (fibh.sbh != fibh.ebh) |
704 | udf_release_data(fibh.ebh); | 705 | brelse(fibh.ebh); |
705 | udf_release_data(fibh.sbh); | 706 | brelse(fibh.sbh); |
706 | d_instantiate(dentry, inode); | 707 | d_instantiate(dentry, inode); |
707 | err = 0; | 708 | err = 0; |
708 | out: | 709 | out: |
@@ -743,7 +744,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
743 | cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL); | 744 | cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL); |
744 | cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; | 745 | cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; |
745 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); | 746 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); |
746 | udf_release_data(fibh.sbh); | 747 | brelse(fibh.sbh); |
747 | inode->i_mode = S_IFDIR | mode; | 748 | inode->i_mode = S_IFDIR | mode; |
748 | if (dir->i_mode & S_ISGID) | 749 | if (dir->i_mode & S_ISGID) |
749 | inode->i_mode |= S_ISGID; | 750 | inode->i_mode |= S_ISGID; |
@@ -766,8 +767,8 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
766 | mark_inode_dirty(dir); | 767 | mark_inode_dirty(dir); |
767 | d_instantiate(dentry, inode); | 768 | d_instantiate(dentry, inode); |
768 | if (fibh.sbh != fibh.ebh) | 769 | if (fibh.sbh != fibh.ebh) |
769 | udf_release_data(fibh.ebh); | 770 | brelse(fibh.ebh); |
770 | udf_release_data(fibh.sbh); | 771 | brelse(fibh.sbh); |
771 | err = 0; | 772 | err = 0; |
772 | out: | 773 | out: |
773 | unlock_kernel(); | 774 | unlock_kernel(); |
@@ -781,9 +782,10 @@ static int empty_dir(struct inode *dir) | |||
781 | loff_t f_pos; | 782 | loff_t f_pos; |
782 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 783 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; |
783 | int block; | 784 | int block; |
784 | kernel_lb_addr bloc, eloc; | 785 | kernel_lb_addr eloc; |
785 | uint32_t extoffset, elen, offset; | 786 | uint32_t elen; |
786 | struct buffer_head *bh = NULL; | 787 | sector_t offset; |
788 | struct extent_position epos = { NULL, 0, { 0, 0}}; | ||
787 | 789 | ||
788 | f_pos = (udf_ext0_offset(dir) >> 2); | 790 | f_pos = (udf_ext0_offset(dir) >> 2); |
789 | 791 | ||
@@ -792,59 +794,58 @@ static int empty_dir(struct inode *dir) | |||
792 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 794 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
793 | fibh.sbh = fibh.ebh = NULL; | 795 | fibh.sbh = fibh.ebh = NULL; |
794 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), | 796 | else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), |
795 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 797 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
796 | { | 798 | { |
797 | offset >>= dir->i_sb->s_blocksize_bits; | ||
798 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 799 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
799 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 800 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) |
800 | { | 801 | { |
801 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 802 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
802 | extoffset -= sizeof(short_ad); | 803 | epos.offset -= sizeof(short_ad); |
803 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 804 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
804 | extoffset -= sizeof(long_ad); | 805 | epos.offset -= sizeof(long_ad); |
805 | } | 806 | } |
806 | else | 807 | else |
807 | offset = 0; | 808 | offset = 0; |
808 | 809 | ||
809 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) | 810 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) |
810 | { | 811 | { |
811 | udf_release_data(bh); | 812 | brelse(epos.bh); |
812 | return 0; | 813 | return 0; |
813 | } | 814 | } |
814 | } | 815 | } |
815 | else | 816 | else |
816 | { | 817 | { |
817 | udf_release_data(bh); | 818 | brelse(epos.bh); |
818 | return 0; | 819 | return 0; |
819 | } | 820 | } |
820 | 821 | ||
821 | 822 | ||
822 | while ( (f_pos < size) ) | 823 | while ( (f_pos < size) ) |
823 | { | 824 | { |
824 | fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 825 | fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); |
825 | 826 | ||
826 | if (!fi) | 827 | if (!fi) |
827 | { | 828 | { |
828 | if (fibh.sbh != fibh.ebh) | 829 | if (fibh.sbh != fibh.ebh) |
829 | udf_release_data(fibh.ebh); | 830 | brelse(fibh.ebh); |
830 | udf_release_data(fibh.sbh); | 831 | brelse(fibh.sbh); |
831 | udf_release_data(bh); | 832 | brelse(epos.bh); |
832 | return 0; | 833 | return 0; |
833 | } | 834 | } |
834 | 835 | ||
835 | if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) | 836 | if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) |
836 | { | 837 | { |
837 | if (fibh.sbh != fibh.ebh) | 838 | if (fibh.sbh != fibh.ebh) |
838 | udf_release_data(fibh.ebh); | 839 | brelse(fibh.ebh); |
839 | udf_release_data(fibh.sbh); | 840 | brelse(fibh.sbh); |
840 | udf_release_data(bh); | 841 | brelse(epos.bh); |
841 | return 0; | 842 | return 0; |
842 | } | 843 | } |
843 | } | 844 | } |
844 | if (fibh.sbh != fibh.ebh) | 845 | if (fibh.sbh != fibh.ebh) |
845 | udf_release_data(fibh.ebh); | 846 | brelse(fibh.ebh); |
846 | udf_release_data(fibh.sbh); | 847 | brelse(fibh.sbh); |
847 | udf_release_data(bh); | 848 | brelse(epos.bh); |
848 | return 1; | 849 | return 1; |
849 | } | 850 | } |
850 | 851 | ||
@@ -878,14 +879,14 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) | |||
878 | inode->i_nlink); | 879 | inode->i_nlink); |
879 | clear_nlink(inode); | 880 | clear_nlink(inode); |
880 | inode->i_size = 0; | 881 | inode->i_size = 0; |
881 | inode_dec_link_count(inode); | 882 | inode_dec_link_count(dir); |
882 | inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); | 883 | inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); |
883 | mark_inode_dirty(dir); | 884 | mark_inode_dirty(dir); |
884 | 885 | ||
885 | end_rmdir: | 886 | end_rmdir: |
886 | if (fibh.sbh != fibh.ebh) | 887 | if (fibh.sbh != fibh.ebh) |
887 | udf_release_data(fibh.ebh); | 888 | brelse(fibh.ebh); |
888 | udf_release_data(fibh.sbh); | 889 | brelse(fibh.sbh); |
889 | out: | 890 | out: |
890 | unlock_kernel(); | 891 | unlock_kernel(); |
891 | return retval; | 892 | return retval; |
@@ -928,8 +929,8 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry) | |||
928 | 929 | ||
929 | end_unlink: | 930 | end_unlink: |
930 | if (fibh.sbh != fibh.ebh) | 931 | if (fibh.sbh != fibh.ebh) |
931 | udf_release_data(fibh.ebh); | 932 | brelse(fibh.ebh); |
932 | udf_release_data(fibh.sbh); | 933 | brelse(fibh.sbh); |
933 | out: | 934 | out: |
934 | unlock_kernel(); | 935 | unlock_kernel(); |
935 | return retval; | 936 | return retval; |
@@ -941,7 +942,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
941 | struct pathComponent *pc; | 942 | struct pathComponent *pc; |
942 | char *compstart; | 943 | char *compstart; |
943 | struct udf_fileident_bh fibh; | 944 | struct udf_fileident_bh fibh; |
944 | struct buffer_head *bh = NULL; | 945 | struct extent_position epos = { NULL, 0, {0, 0}}; |
945 | int eoffset, elen = 0; | 946 | int eoffset, elen = 0; |
946 | struct fileIdentDesc *fi; | 947 | struct fileIdentDesc *fi; |
947 | struct fileIdentDesc cfi; | 948 | struct fileIdentDesc cfi; |
@@ -961,33 +962,33 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
961 | 962 | ||
962 | if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) | 963 | if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) |
963 | { | 964 | { |
964 | struct buffer_head *bh = NULL; | 965 | kernel_lb_addr eloc; |
965 | kernel_lb_addr bloc, eloc; | 966 | uint32_t elen; |
966 | uint32_t elen, extoffset; | ||
967 | 967 | ||
968 | block = udf_new_block(inode->i_sb, inode, | 968 | block = udf_new_block(inode->i_sb, inode, |
969 | UDF_I_LOCATION(inode).partitionReferenceNum, | 969 | UDF_I_LOCATION(inode).partitionReferenceNum, |
970 | UDF_I_LOCATION(inode).logicalBlockNum, &err); | 970 | UDF_I_LOCATION(inode).logicalBlockNum, &err); |
971 | if (!block) | 971 | if (!block) |
972 | goto out_no_entry; | 972 | goto out_no_entry; |
973 | bloc = UDF_I_LOCATION(inode); | 973 | epos.block = UDF_I_LOCATION(inode); |
974 | epos.offset = udf_file_entry_alloc_offset(inode); | ||
975 | epos.bh = NULL; | ||
974 | eloc.logicalBlockNum = block; | 976 | eloc.logicalBlockNum = block; |
975 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; | 977 | eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; |
976 | elen = inode->i_sb->s_blocksize; | 978 | elen = inode->i_sb->s_blocksize; |
977 | UDF_I_LENEXTENTS(inode) = elen; | 979 | UDF_I_LENEXTENTS(inode) = elen; |
978 | extoffset = udf_file_entry_alloc_offset(inode); | 980 | udf_add_aext(inode, &epos, eloc, elen, 0); |
979 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0); | 981 | brelse(epos.bh); |
980 | udf_release_data(bh); | ||
981 | 982 | ||
982 | block = udf_get_pblock(inode->i_sb, block, | 983 | block = udf_get_pblock(inode->i_sb, block, |
983 | UDF_I_LOCATION(inode).partitionReferenceNum, 0); | 984 | UDF_I_LOCATION(inode).partitionReferenceNum, 0); |
984 | bh = udf_tread(inode->i_sb, block); | 985 | epos.bh = udf_tread(inode->i_sb, block); |
985 | lock_buffer(bh); | 986 | lock_buffer(epos.bh); |
986 | memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); | 987 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); |
987 | set_buffer_uptodate(bh); | 988 | set_buffer_uptodate(epos.bh); |
988 | unlock_buffer(bh); | 989 | unlock_buffer(epos.bh); |
989 | mark_buffer_dirty_inode(bh, inode); | 990 | mark_buffer_dirty_inode(epos.bh, inode); |
990 | ea = bh->b_data + udf_ext0_offset(inode); | 991 | ea = epos.bh->b_data + udf_ext0_offset(inode); |
991 | } | 992 | } |
992 | else | 993 | else |
993 | ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); | 994 | ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); |
@@ -1060,7 +1061,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
1060 | } | 1061 | } |
1061 | } | 1062 | } |
1062 | 1063 | ||
1063 | udf_release_data(bh); | 1064 | brelse(epos.bh); |
1064 | inode->i_size = elen; | 1065 | inode->i_size = elen; |
1065 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) | 1066 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) |
1066 | UDF_I_LENALLOC(inode) = inode->i_size; | 1067 | UDF_I_LENALLOC(inode) = inode->i_size; |
@@ -1089,8 +1090,8 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * | |||
1089 | mark_inode_dirty(dir); | 1090 | mark_inode_dirty(dir); |
1090 | } | 1091 | } |
1091 | if (fibh.sbh != fibh.ebh) | 1092 | if (fibh.sbh != fibh.ebh) |
1092 | udf_release_data(fibh.ebh); | 1093 | brelse(fibh.ebh); |
1093 | udf_release_data(fibh.sbh); | 1094 | brelse(fibh.sbh); |
1094 | d_instantiate(dentry, inode); | 1095 | d_instantiate(dentry, inode); |
1095 | err = 0; | 1096 | err = 0; |
1096 | 1097 | ||
@@ -1145,8 +1146,8 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir, | |||
1145 | mark_inode_dirty(dir); | 1146 | mark_inode_dirty(dir); |
1146 | } | 1147 | } |
1147 | if (fibh.sbh != fibh.ebh) | 1148 | if (fibh.sbh != fibh.ebh) |
1148 | udf_release_data(fibh.ebh); | 1149 | brelse(fibh.ebh); |
1149 | udf_release_data(fibh.sbh); | 1150 | brelse(fibh.sbh); |
1150 | inc_nlink(inode); | 1151 | inc_nlink(inode); |
1151 | inode->i_ctime = current_fs_time(inode->i_sb); | 1152 | inode->i_ctime = current_fs_time(inode->i_sb); |
1152 | mark_inode_dirty(inode); | 1153 | mark_inode_dirty(inode); |
@@ -1174,8 +1175,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1174 | if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) | 1175 | if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) |
1175 | { | 1176 | { |
1176 | if (ofibh.sbh != ofibh.ebh) | 1177 | if (ofibh.sbh != ofibh.ebh) |
1177 | udf_release_data(ofibh.ebh); | 1178 | brelse(ofibh.ebh); |
1178 | udf_release_data(ofibh.sbh); | 1179 | brelse(ofibh.sbh); |
1179 | } | 1180 | } |
1180 | tloc = lelb_to_cpu(ocfi.icb.extLocation); | 1181 | tloc = lelb_to_cpu(ocfi.icb.extLocation); |
1181 | if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0) | 1182 | if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0) |
@@ -1188,8 +1189,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1188 | if (!new_inode) | 1189 | if (!new_inode) |
1189 | { | 1190 | { |
1190 | if (nfibh.sbh != nfibh.ebh) | 1191 | if (nfibh.sbh != nfibh.ebh) |
1191 | udf_release_data(nfibh.ebh); | 1192 | brelse(nfibh.ebh); |
1192 | udf_release_data(nfibh.sbh); | 1193 | brelse(nfibh.sbh); |
1193 | nfi = NULL; | 1194 | nfi = NULL; |
1194 | } | 1195 | } |
1195 | } | 1196 | } |
@@ -1290,19 +1291,19 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1290 | if (ofi) | 1291 | if (ofi) |
1291 | { | 1292 | { |
1292 | if (ofibh.sbh != ofibh.ebh) | 1293 | if (ofibh.sbh != ofibh.ebh) |
1293 | udf_release_data(ofibh.ebh); | 1294 | brelse(ofibh.ebh); |
1294 | udf_release_data(ofibh.sbh); | 1295 | brelse(ofibh.sbh); |
1295 | } | 1296 | } |
1296 | 1297 | ||
1297 | retval = 0; | 1298 | retval = 0; |
1298 | 1299 | ||
1299 | end_rename: | 1300 | end_rename: |
1300 | udf_release_data(dir_bh); | 1301 | brelse(dir_bh); |
1301 | if (nfi) | 1302 | if (nfi) |
1302 | { | 1303 | { |
1303 | if (nfibh.sbh != nfibh.ebh) | 1304 | if (nfibh.sbh != nfibh.ebh) |
1304 | udf_release_data(nfibh.ebh); | 1305 | brelse(nfibh.ebh); |
1305 | udf_release_data(nfibh.sbh); | 1306 | brelse(nfibh.sbh); |
1306 | } | 1307 | } |
1307 | unlock_kernel(); | 1308 | unlock_kernel(); |
1308 | return retval; | 1309 | return retval; |
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index dabf2b841d..467a26171c 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -81,7 +81,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t | |||
81 | 81 | ||
82 | loc = le32_to_cpu(((__le32 *)bh->b_data)[index]); | 82 | loc = le32_to_cpu(((__le32 *)bh->b_data)[index]); |
83 | 83 | ||
84 | udf_release_data(bh); | 84 | brelse(bh); |
85 | 85 | ||
86 | if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) | 86 | if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) |
87 | { | 87 | { |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 023b304fdd..6658afb41c 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -134,10 +134,8 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
134 | { | 134 | { |
135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; | 135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; |
136 | 136 | ||
137 | if (flags & SLAB_CTOR_CONSTRUCTOR) { | 137 | ei->i_ext.i_data = NULL; |
138 | ei->i_ext.i_data = NULL; | 138 | inode_init_once(&ei->vfs_inode); |
139 | inode_init_once(&ei->vfs_inode); | ||
140 | } | ||
141 | } | 139 | } |
142 | 140 | ||
143 | static int init_inodecache(void) | 141 | static int init_inodecache(void) |
@@ -563,7 +561,7 @@ udf_vrs(struct super_block *sb, int silent) | |||
563 | 561 | ||
564 | if (vsd->stdIdent[0] == 0) | 562 | if (vsd->stdIdent[0] == 0) |
565 | { | 563 | { |
566 | udf_release_data(bh); | 564 | brelse(bh); |
567 | break; | 565 | break; |
568 | } | 566 | } |
569 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) | 567 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) |
@@ -596,7 +594,7 @@ udf_vrs(struct super_block *sb, int silent) | |||
596 | } | 594 | } |
597 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) | 595 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) |
598 | { | 596 | { |
599 | udf_release_data(bh); | 597 | brelse(bh); |
600 | break; | 598 | break; |
601 | } | 599 | } |
602 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) | 600 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) |
@@ -607,7 +605,7 @@ udf_vrs(struct super_block *sb, int silent) | |||
607 | { | 605 | { |
608 | nsr03 = sector; | 606 | nsr03 = sector; |
609 | } | 607 | } |
610 | udf_release_data(bh); | 608 | brelse(bh); |
611 | } | 609 | } |
612 | 610 | ||
613 | if (nsr03) | 611 | if (nsr03) |
@@ -673,7 +671,7 @@ udf_find_anchor(struct super_block *sb) | |||
673 | { | 671 | { |
674 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 672 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
675 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 673 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
676 | udf_release_data(bh); | 674 | brelse(bh); |
677 | } | 675 | } |
678 | 676 | ||
679 | if (ident == TAG_IDENT_AVDP) | 677 | if (ident == TAG_IDENT_AVDP) |
@@ -708,7 +706,7 @@ udf_find_anchor(struct super_block *sb) | |||
708 | { | 706 | { |
709 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 707 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
710 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 708 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
711 | udf_release_data(bh); | 709 | brelse(bh); |
712 | } | 710 | } |
713 | 711 | ||
714 | if (ident == TAG_IDENT_AVDP && | 712 | if (ident == TAG_IDENT_AVDP && |
@@ -727,7 +725,7 @@ udf_find_anchor(struct super_block *sb) | |||
727 | { | 725 | { |
728 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 726 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
729 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 727 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
730 | udf_release_data(bh); | 728 | brelse(bh); |
731 | } | 729 | } |
732 | 730 | ||
733 | if (ident == TAG_IDENT_AVDP && | 731 | if (ident == TAG_IDENT_AVDP && |
@@ -749,7 +747,7 @@ udf_find_anchor(struct super_block *sb) | |||
749 | { | 747 | { |
750 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); | 748 | ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); |
751 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); | 749 | location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); |
752 | udf_release_data(bh); | 750 | brelse(bh); |
753 | 751 | ||
754 | if (ident == TAG_IDENT_AVDP && location == 256) | 752 | if (ident == TAG_IDENT_AVDP && location == 256) |
755 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | 753 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); |
@@ -766,7 +764,7 @@ udf_find_anchor(struct super_block *sb) | |||
766 | } | 764 | } |
767 | else | 765 | else |
768 | { | 766 | { |
769 | udf_release_data(bh); | 767 | brelse(bh); |
770 | if ((ident != TAG_IDENT_AVDP) && (i || | 768 | if ((ident != TAG_IDENT_AVDP) && (i || |
771 | (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE))) | 769 | (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE))) |
772 | { | 770 | { |
@@ -795,7 +793,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
795 | return 1; | 793 | return 1; |
796 | else if (ident != TAG_IDENT_FSD) | 794 | else if (ident != TAG_IDENT_FSD) |
797 | { | 795 | { |
798 | udf_release_data(bh); | 796 | brelse(bh); |
799 | return 1; | 797 | return 1; |
800 | } | 798 | } |
801 | 799 | ||
@@ -834,7 +832,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
834 | newfileset.logicalBlockNum += 1 + | 832 | newfileset.logicalBlockNum += 1 + |
835 | ((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1) | 833 | ((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1) |
836 | >> sb->s_blocksize_bits); | 834 | >> sb->s_blocksize_bits); |
837 | udf_release_data(bh); | 835 | brelse(bh); |
838 | break; | 836 | break; |
839 | } | 837 | } |
840 | case TAG_IDENT_FSD: | 838 | case TAG_IDENT_FSD: |
@@ -845,7 +843,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
845 | default: | 843 | default: |
846 | { | 844 | { |
847 | newfileset.logicalBlockNum ++; | 845 | newfileset.logicalBlockNum ++; |
848 | udf_release_data(bh); | 846 | brelse(bh); |
849 | bh = NULL; | 847 | bh = NULL; |
850 | break; | 848 | break; |
851 | } | 849 | } |
@@ -865,7 +863,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr | |||
865 | 863 | ||
866 | UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum; | 864 | UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum; |
867 | udf_load_fileset(sb, bh, root); | 865 | udf_load_fileset(sb, bh, root); |
868 | udf_release_data(bh); | 866 | brelse(bh); |
869 | return 0; | 867 | return 0; |
870 | } | 868 | } |
871 | return 1; | 869 | return 1; |
@@ -1083,7 +1081,7 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a | |||
1083 | if (ident != 0 || | 1081 | if (ident != 0 || |
1084 | strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) | 1082 | strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) |
1085 | { | 1083 | { |
1086 | udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]); | 1084 | brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]); |
1087 | UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL; | 1085 | UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL; |
1088 | } | 1086 | } |
1089 | } | 1087 | } |
@@ -1137,12 +1135,12 @@ udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) | |||
1137 | udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt)); | 1135 | udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt)); |
1138 | 1136 | ||
1139 | if (UDF_SB_LVIDBH(sb) != bh) | 1137 | if (UDF_SB_LVIDBH(sb) != bh) |
1140 | udf_release_data(bh); | 1138 | brelse(bh); |
1141 | loc.extLength -= sb->s_blocksize; | 1139 | loc.extLength -= sb->s_blocksize; |
1142 | loc.extLocation ++; | 1140 | loc.extLocation ++; |
1143 | } | 1141 | } |
1144 | if (UDF_SB_LVIDBH(sb) != bh) | 1142 | if (UDF_SB_LVIDBH(sb) != bh) |
1145 | udf_release_data(bh); | 1143 | brelse(bh); |
1146 | } | 1144 | } |
1147 | 1145 | ||
1148 | /* | 1146 | /* |
@@ -1245,7 +1243,7 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_ | |||
1245 | done = 1; | 1243 | done = 1; |
1246 | break; | 1244 | break; |
1247 | } | 1245 | } |
1248 | udf_release_data(bh); | 1246 | brelse(bh); |
1249 | } | 1247 | } |
1250 | for (i=0; i<VDS_POS_LENGTH; i++) | 1248 | for (i=0; i<VDS_POS_LENGTH; i++) |
1251 | { | 1249 | { |
@@ -1267,10 +1265,10 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_ | |||
1267 | gd = (struct generic_desc *)bh2->b_data; | 1265 | gd = (struct generic_desc *)bh2->b_data; |
1268 | if (ident == TAG_IDENT_PD) | 1266 | if (ident == TAG_IDENT_PD) |
1269 | udf_load_partdesc(sb, bh2); | 1267 | udf_load_partdesc(sb, bh2); |
1270 | udf_release_data(bh2); | 1268 | brelse(bh2); |
1271 | } | 1269 | } |
1272 | } | 1270 | } |
1273 | udf_release_data(bh); | 1271 | brelse(bh); |
1274 | } | 1272 | } |
1275 | } | 1273 | } |
1276 | 1274 | ||
@@ -1333,7 +1331,7 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
1333 | reserve_e = reserve_e >> sb->s_blocksize_bits; | 1331 | reserve_e = reserve_e >> sb->s_blocksize_bits; |
1334 | reserve_e += reserve_s; | 1332 | reserve_e += reserve_s; |
1335 | 1333 | ||
1336 | udf_release_data(bh); | 1334 | brelse(bh); |
1337 | 1335 | ||
1338 | /* Process the main & reserve sequences */ | 1336 | /* Process the main & reserve sequences */ |
1339 | /* responsible for finding the PartitionDesc(s) */ | 1337 | /* responsible for finding the PartitionDesc(s) */ |
@@ -1353,7 +1351,7 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
1353 | 1351 | ||
1354 | for (i=0; i<UDF_SB_NUMPARTS(sb); i++) | 1352 | for (i=0; i<UDF_SB_NUMPARTS(sb); i++) |
1355 | { | 1353 | { |
1356 | switch UDF_SB_PARTTYPE(sb, i) | 1354 | switch (UDF_SB_PARTTYPE(sb, i)) |
1357 | { | 1355 | { |
1358 | case UDF_VIRTUAL_MAP15: | 1356 | case UDF_VIRTUAL_MAP15: |
1359 | case UDF_VIRTUAL_MAP20: | 1357 | case UDF_VIRTUAL_MAP20: |
@@ -1403,12 +1401,14 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
1403 | 1401 | ||
1404 | pos = udf_block_map(UDF_SB_VAT(sb), 0); | 1402 | pos = udf_block_map(UDF_SB_VAT(sb), 0); |
1405 | bh = sb_bread(sb, pos); | 1403 | bh = sb_bread(sb, pos); |
1404 | if (!bh) | ||
1405 | return 1; | ||
1406 | UDF_SB_TYPEVIRT(sb,i).s_start_offset = | 1406 | UDF_SB_TYPEVIRT(sb,i).s_start_offset = |
1407 | le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) + | 1407 | le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) + |
1408 | udf_ext0_offset(UDF_SB_VAT(sb)); | 1408 | udf_ext0_offset(UDF_SB_VAT(sb)); |
1409 | UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - | 1409 | UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - |
1410 | UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2; | 1410 | UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2; |
1411 | udf_release_data(bh); | 1411 | brelse(bh); |
1412 | } | 1412 | } |
1413 | UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0); | 1413 | UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0); |
1414 | UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum); | 1414 | UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum); |
@@ -1661,7 +1661,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1661 | iput(inode); | 1661 | iput(inode); |
1662 | goto error_out; | 1662 | goto error_out; |
1663 | } | 1663 | } |
1664 | sb->s_maxbytes = 1<<30; | 1664 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
1665 | return 0; | 1665 | return 0; |
1666 | 1666 | ||
1667 | error_out: | 1667 | error_out: |
@@ -1680,7 +1680,7 @@ error_out: | |||
1680 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) | 1680 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) |
1681 | { | 1681 | { |
1682 | for (i=0; i<4; i++) | 1682 | for (i=0; i<4; i++) |
1683 | udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); | 1683 | brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); |
1684 | } | 1684 | } |
1685 | } | 1685 | } |
1686 | #ifdef CONFIG_UDF_NLS | 1686 | #ifdef CONFIG_UDF_NLS |
@@ -1689,7 +1689,7 @@ error_out: | |||
1689 | #endif | 1689 | #endif |
1690 | if (!(sb->s_flags & MS_RDONLY)) | 1690 | if (!(sb->s_flags & MS_RDONLY)) |
1691 | udf_close_lvid(sb); | 1691 | udf_close_lvid(sb); |
1692 | udf_release_data(UDF_SB_LVIDBH(sb)); | 1692 | brelse(UDF_SB_LVIDBH(sb)); |
1693 | UDF_SB_FREE(sb); | 1693 | UDF_SB_FREE(sb); |
1694 | kfree(sbi); | 1694 | kfree(sbi); |
1695 | sb->s_fs_info = NULL; | 1695 | sb->s_fs_info = NULL; |
@@ -1758,7 +1758,7 @@ udf_put_super(struct super_block *sb) | |||
1758 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) | 1758 | if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) |
1759 | { | 1759 | { |
1760 | for (i=0; i<4; i++) | 1760 | for (i=0; i<4; i++) |
1761 | udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); | 1761 | brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); |
1762 | } | 1762 | } |
1763 | } | 1763 | } |
1764 | #ifdef CONFIG_UDF_NLS | 1764 | #ifdef CONFIG_UDF_NLS |
@@ -1767,7 +1767,7 @@ udf_put_super(struct super_block *sb) | |||
1767 | #endif | 1767 | #endif |
1768 | if (!(sb->s_flags & MS_RDONLY)) | 1768 | if (!(sb->s_flags & MS_RDONLY)) |
1769 | udf_close_lvid(sb); | 1769 | udf_close_lvid(sb); |
1770 | udf_release_data(UDF_SB_LVIDBH(sb)); | 1770 | brelse(UDF_SB_LVIDBH(sb)); |
1771 | UDF_SB_FREE(sb); | 1771 | UDF_SB_FREE(sb); |
1772 | kfree(sb->s_fs_info); | 1772 | kfree(sb->s_fs_info); |
1773 | sb->s_fs_info = NULL; | 1773 | sb->s_fs_info = NULL; |
@@ -1837,7 +1837,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) | |||
1837 | } | 1837 | } |
1838 | else if (ident != TAG_IDENT_SBD) | 1838 | else if (ident != TAG_IDENT_SBD) |
1839 | { | 1839 | { |
1840 | udf_release_data(bh); | 1840 | brelse(bh); |
1841 | printk(KERN_ERR "udf: udf_count_free failed\n"); | 1841 | printk(KERN_ERR "udf: udf_count_free failed\n"); |
1842 | goto out; | 1842 | goto out; |
1843 | } | 1843 | } |
@@ -1859,7 +1859,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) | |||
1859 | } | 1859 | } |
1860 | if ( bytes ) | 1860 | if ( bytes ) |
1861 | { | 1861 | { |
1862 | udf_release_data(bh); | 1862 | brelse(bh); |
1863 | newblock = udf_get_lb_pblock(sb, loc, ++block); | 1863 | newblock = udf_get_lb_pblock(sb, loc, ++block); |
1864 | bh = udf_tread(sb, newblock); | 1864 | bh = udf_tread(sb, newblock); |
1865 | if (!bh) | 1865 | if (!bh) |
@@ -1871,7 +1871,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) | |||
1871 | ptr = (uint8_t *)bh->b_data; | 1871 | ptr = (uint8_t *)bh->b_data; |
1872 | } | 1872 | } |
1873 | } | 1873 | } |
1874 | udf_release_data(bh); | 1874 | brelse(bh); |
1875 | 1875 | ||
1876 | out: | 1876 | out: |
1877 | unlock_kernel(); | 1877 | unlock_kernel(); |
@@ -1883,21 +1883,20 @@ static unsigned int | |||
1883 | udf_count_free_table(struct super_block *sb, struct inode * table) | 1883 | udf_count_free_table(struct super_block *sb, struct inode * table) |
1884 | { | 1884 | { |
1885 | unsigned int accum = 0; | 1885 | unsigned int accum = 0; |
1886 | uint32_t extoffset, elen; | 1886 | uint32_t elen; |
1887 | kernel_lb_addr bloc, eloc; | 1887 | kernel_lb_addr eloc; |
1888 | int8_t etype; | 1888 | int8_t etype; |
1889 | struct buffer_head *bh = NULL; | 1889 | struct extent_position epos; |
1890 | 1890 | ||
1891 | lock_kernel(); | 1891 | lock_kernel(); |
1892 | 1892 | ||
1893 | bloc = UDF_I_LOCATION(table); | 1893 | epos.block = UDF_I_LOCATION(table); |
1894 | extoffset = sizeof(struct unallocSpaceEntry); | 1894 | epos.offset = sizeof(struct unallocSpaceEntry); |
1895 | epos.bh = NULL; | ||
1895 | 1896 | ||
1896 | while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 1897 | while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
1897 | { | ||
1898 | accum += (elen >> table->i_sb->s_blocksize_bits); | 1898 | accum += (elen >> table->i_sb->s_blocksize_bits); |
1899 | } | 1899 | brelse(epos.bh); |
1900 | udf_release_data(bh); | ||
1901 | 1900 | ||
1902 | unlock_kernel(); | 1901 | unlock_kernel(); |
1903 | 1902 | ||
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index ba068a7865..12613b680c 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -95,7 +95,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); | 97 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); |
98 | udf_release_data(bh); | 98 | brelse(bh); |
99 | 99 | ||
100 | unlock_kernel(); | 100 | unlock_kernel(); |
101 | SetPageUptodate(page); | 101 | SetPageUptodate(page); |
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 0abd66ce36..60d2776442 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -28,8 +28,8 @@ | |||
28 | #include "udf_i.h" | 28 | #include "udf_i.h" |
29 | #include "udf_sb.h" | 29 | #include "udf_sb.h" |
30 | 30 | ||
31 | static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffset, | 31 | static void extent_trunc(struct inode * inode, struct extent_position *epos, |
32 | kernel_lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen) | 32 | kernel_lb_addr eloc, int8_t etype, uint32_t elen, uint32_t nelen) |
33 | { | 33 | { |
34 | kernel_lb_addr neloc = { 0, 0 }; | 34 | kernel_lb_addr neloc = { 0, 0 }; |
35 | int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; | 35 | int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; |
@@ -49,7 +49,7 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse | |||
49 | 49 | ||
50 | if (elen != nelen) | 50 | if (elen != nelen) |
51 | { | 51 | { |
52 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0); | 52 | udf_write_aext(inode, epos, neloc, nelen, 0); |
53 | if (last_block - first_block > 0) | 53 | if (last_block - first_block > 0) |
54 | { | 54 | { |
55 | if (etype == (EXT_RECORDED_ALLOCATED >> 30)) | 55 | if (etype == (EXT_RECORDED_ALLOCATED >> 30)) |
@@ -61,74 +61,125 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse | |||
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | void udf_discard_prealloc(struct inode * inode) | 64 | /* |
65 | * Truncate the last extent to match i_size. This function assumes | ||
66 | * that preallocation extent is already truncated. | ||
67 | */ | ||
68 | void udf_truncate_tail_extent(struct inode *inode) | ||
65 | { | 69 | { |
66 | kernel_lb_addr bloc, eloc; | 70 | struct extent_position epos = { NULL, 0, {0, 0}}; |
67 | uint32_t extoffset = 0, elen, nelen; | 71 | kernel_lb_addr eloc; |
72 | uint32_t elen, nelen; | ||
68 | uint64_t lbcount = 0; | 73 | uint64_t lbcount = 0; |
69 | int8_t etype = -1, netype; | 74 | int8_t etype = -1, netype; |
70 | struct buffer_head *bh = NULL; | ||
71 | int adsize; | 75 | int adsize; |
72 | 76 | ||
73 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || | 77 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || |
74 | inode->i_size == UDF_I_LENEXTENTS(inode)) | 78 | inode->i_size == UDF_I_LENEXTENTS(inode)) |
75 | { | 79 | return; |
80 | /* Are we going to delete the file anyway? */ | ||
81 | if (inode->i_nlink == 0) | ||
76 | return; | 82 | return; |
77 | } | ||
78 | 83 | ||
79 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 84 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
80 | adsize = sizeof(short_ad); | 85 | adsize = sizeof(short_ad); |
81 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 86 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) |
82 | adsize = sizeof(long_ad); | 87 | adsize = sizeof(long_ad); |
83 | else | 88 | else |
84 | adsize = 0; | 89 | BUG(); |
85 | 90 | ||
86 | bloc = UDF_I_LOCATION(inode); | 91 | /* Find the last extent in the file */ |
87 | 92 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) | |
88 | while ((netype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | ||
89 | { | 93 | { |
90 | etype = netype; | 94 | etype = netype; |
91 | lbcount += elen; | 95 | lbcount += elen; |
92 | if (lbcount > inode->i_size && lbcount - inode->i_size < inode->i_sb->s_blocksize) | 96 | if (lbcount > inode->i_size) { |
93 | { | 97 | if (lbcount - inode->i_size >= inode->i_sb->s_blocksize) |
98 | printk(KERN_WARNING | ||
99 | "udf_truncate_tail_extent(): Too long " | ||
100 | "extent after EOF in inode %u: i_size: " | ||
101 | "%Ld lbcount: %Ld extent %u+%u\n", | ||
102 | (unsigned)inode->i_ino, | ||
103 | (long long)inode->i_size, | ||
104 | (long long)lbcount, | ||
105 | (unsigned)eloc.logicalBlockNum, | ||
106 | (unsigned)elen); | ||
94 | nelen = elen - (lbcount - inode->i_size); | 107 | nelen = elen - (lbcount - inode->i_size); |
95 | extent_trunc(inode, bloc, extoffset-adsize, eloc, etype, elen, bh, nelen); | 108 | epos.offset -= adsize; |
96 | lbcount = inode->i_size; | 109 | extent_trunc(inode, &epos, eloc, etype, elen, nelen); |
110 | epos.offset += adsize; | ||
111 | if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1) | ||
112 | printk(KERN_ERR "udf_truncate_tail_extent(): " | ||
113 | "Extent after EOF in inode %u.\n", | ||
114 | (unsigned)inode->i_ino); | ||
115 | break; | ||
97 | } | 116 | } |
98 | } | 117 | } |
99 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | 118 | /* This inode entry is in-memory only and thus we don't have to mark |
100 | { | 119 | * the inode dirty */ |
101 | extoffset -= adsize; | 120 | UDF_I_LENEXTENTS(inode) = inode->i_size; |
121 | brelse(epos.bh); | ||
122 | } | ||
123 | |||
124 | void udf_discard_prealloc(struct inode *inode) | ||
125 | { | ||
126 | struct extent_position epos = { NULL, 0, {0, 0}}; | ||
127 | kernel_lb_addr eloc; | ||
128 | uint32_t elen; | ||
129 | uint64_t lbcount = 0; | ||
130 | int8_t etype = -1, netype; | ||
131 | int adsize; | ||
132 | |||
133 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || | ||
134 | inode->i_size == UDF_I_LENEXTENTS(inode)) | ||
135 | return; | ||
136 | |||
137 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | ||
138 | adsize = sizeof(short_ad); | ||
139 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | ||
140 | adsize = sizeof(long_ad); | ||
141 | else | ||
142 | adsize = 0; | ||
143 | |||
144 | epos.block = UDF_I_LOCATION(inode); | ||
145 | |||
146 | /* Find the last extent in the file */ | ||
147 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { | ||
148 | etype = netype; | ||
149 | lbcount += elen; | ||
150 | } | ||
151 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { | ||
152 | epos.offset -= adsize; | ||
102 | lbcount -= elen; | 153 | lbcount -= elen; |
103 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); | 154 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
104 | if (!bh) | 155 | if (!epos.bh) { |
105 | { | 156 | UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode); |
106 | UDF_I_LENALLOC(inode) = extoffset - udf_file_entry_alloc_offset(inode); | ||
107 | mark_inode_dirty(inode); | 157 | mark_inode_dirty(inode); |
108 | } | 158 | } else { |
109 | else | 159 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
110 | { | 160 | aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc)); |
111 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | ||
112 | aed->lengthAllocDescs = cpu_to_le32(extoffset - sizeof(struct allocExtDesc)); | ||
113 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 161 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
114 | udf_update_tag(bh->b_data, extoffset); | 162 | udf_update_tag(epos.bh->b_data, epos.offset); |
115 | else | 163 | else |
116 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 164 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
117 | mark_buffer_dirty_inode(bh, inode); | 165 | mark_buffer_dirty_inode(epos.bh, inode); |
118 | } | 166 | } |
119 | } | 167 | } |
168 | /* This inode entry is in-memory only and thus we don't have to mark | ||
169 | * the inode dirty */ | ||
120 | UDF_I_LENEXTENTS(inode) = lbcount; | 170 | UDF_I_LENEXTENTS(inode) = lbcount; |
121 | 171 | brelse(epos.bh); | |
122 | udf_release_data(bh); | ||
123 | } | 172 | } |
124 | 173 | ||
125 | void udf_truncate_extents(struct inode * inode) | 174 | void udf_truncate_extents(struct inode * inode) |
126 | { | 175 | { |
127 | kernel_lb_addr bloc, eloc, neloc = { 0, 0 }; | 176 | struct extent_position epos; |
128 | uint32_t extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc; | 177 | kernel_lb_addr eloc, neloc = { 0, 0 }; |
178 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; | ||
129 | int8_t etype; | 179 | int8_t etype; |
130 | int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits; | 180 | struct super_block *sb = inode->i_sb; |
131 | struct buffer_head *bh = NULL; | 181 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; |
182 | loff_t byte_offset; | ||
132 | int adsize; | 183 | int adsize; |
133 | 184 | ||
134 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 185 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
@@ -136,158 +187,130 @@ void udf_truncate_extents(struct inode * inode) | |||
136 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 187 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) |
137 | adsize = sizeof(long_ad); | 188 | adsize = sizeof(long_ad); |
138 | else | 189 | else |
139 | adsize = 0; | 190 | BUG(); |
140 | 191 | ||
141 | etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 192 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
142 | offset += (inode->i_size & (inode->i_sb->s_blocksize - 1)); | 193 | byte_offset = (offset << sb->s_blocksize_bits) + (inode->i_size & (sb->s_blocksize-1)); |
143 | if (etype != -1) | 194 | if (etype != -1) |
144 | { | 195 | { |
145 | extoffset -= adsize; | 196 | epos.offset -= adsize; |
146 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset); | 197 | extent_trunc(inode, &epos, eloc, etype, elen, byte_offset); |
147 | extoffset += adsize; | 198 | epos.offset += adsize; |
148 | 199 | if (byte_offset) | |
149 | if (offset) | 200 | lenalloc = epos.offset; |
150 | lenalloc = extoffset; | ||
151 | else | 201 | else |
152 | lenalloc = extoffset - adsize; | 202 | lenalloc = epos.offset - adsize; |
153 | 203 | ||
154 | if (!bh) | 204 | if (!epos.bh) |
155 | lenalloc -= udf_file_entry_alloc_offset(inode); | 205 | lenalloc -= udf_file_entry_alloc_offset(inode); |
156 | else | 206 | else |
157 | lenalloc -= sizeof(struct allocExtDesc); | 207 | lenalloc -= sizeof(struct allocExtDesc); |
158 | 208 | ||
159 | while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1) | 209 | while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) |
160 | { | 210 | { |
161 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) | 211 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
162 | { | 212 | { |
163 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0); | 213 | udf_write_aext(inode, &epos, neloc, nelen, 0); |
164 | extoffset = 0; | 214 | if (indirect_ext_len) |
165 | if (lelen) | ||
166 | { | 215 | { |
167 | if (!bh) | 216 | /* We managed to free all extents in the |
217 | * indirect extent - free it too */ | ||
218 | if (!epos.bh) | ||
168 | BUG(); | 219 | BUG(); |
169 | else | 220 | udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len); |
170 | memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); | ||
171 | udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); | ||
172 | } | 221 | } |
173 | else | 222 | else |
174 | { | 223 | { |
175 | if (!bh) | 224 | if (!epos.bh) |
176 | { | 225 | { |
177 | UDF_I_LENALLOC(inode) = lenalloc; | 226 | UDF_I_LENALLOC(inode) = lenalloc; |
178 | mark_inode_dirty(inode); | 227 | mark_inode_dirty(inode); |
179 | } | 228 | } |
180 | else | 229 | else |
181 | { | 230 | { |
182 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 231 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
183 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 232 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
184 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 233 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201) |
185 | udf_update_tag(bh->b_data, lenalloc + | 234 | udf_update_tag(epos.bh->b_data, lenalloc + |
186 | sizeof(struct allocExtDesc)); | 235 | sizeof(struct allocExtDesc)); |
187 | else | 236 | else |
188 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 237 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
189 | mark_buffer_dirty_inode(bh, inode); | 238 | mark_buffer_dirty_inode(epos.bh, inode); |
190 | } | 239 | } |
191 | } | 240 | } |
192 | 241 | brelse(epos.bh); | |
193 | udf_release_data(bh); | 242 | epos.offset = sizeof(struct allocExtDesc); |
194 | extoffset = sizeof(struct allocExtDesc); | 243 | epos.block = eloc; |
195 | bloc = eloc; | 244 | epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0)); |
196 | bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0)); | ||
197 | if (elen) | 245 | if (elen) |
198 | lelen = (elen + inode->i_sb->s_blocksize - 1) >> | 246 | indirect_ext_len = (elen + |
199 | inode->i_sb->s_blocksize_bits; | 247 | sb->s_blocksize - 1) >> |
248 | sb->s_blocksize_bits; | ||
200 | else | 249 | else |
201 | lelen = 1; | 250 | indirect_ext_len = 1; |
202 | } | 251 | } |
203 | else | 252 | else |
204 | { | 253 | { |
205 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); | 254 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
206 | extoffset += adsize; | 255 | epos.offset += adsize; |
207 | } | 256 | } |
208 | } | 257 | } |
209 | 258 | ||
210 | if (lelen) | 259 | if (indirect_ext_len) |
211 | { | 260 | { |
212 | if (!bh) | 261 | if (!epos.bh) |
213 | BUG(); | 262 | BUG(); |
214 | else | 263 | udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len); |
215 | memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); | ||
216 | udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); | ||
217 | } | 264 | } |
218 | else | 265 | else |
219 | { | 266 | { |
220 | if (!bh) | 267 | if (!epos.bh) |
221 | { | 268 | { |
222 | UDF_I_LENALLOC(inode) = lenalloc; | 269 | UDF_I_LENALLOC(inode) = lenalloc; |
223 | mark_inode_dirty(inode); | 270 | mark_inode_dirty(inode); |
224 | } | 271 | } |
225 | else | 272 | else |
226 | { | 273 | { |
227 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 274 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
228 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 275 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
229 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 276 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201) |
230 | udf_update_tag(bh->b_data, lenalloc + | 277 | udf_update_tag(epos.bh->b_data, lenalloc + |
231 | sizeof(struct allocExtDesc)); | 278 | sizeof(struct allocExtDesc)); |
232 | else | 279 | else |
233 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 280 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
234 | mark_buffer_dirty_inode(bh, inode); | 281 | mark_buffer_dirty_inode(epos.bh, inode); |
235 | } | 282 | } |
236 | } | 283 | } |
237 | } | 284 | } |
238 | else if (inode->i_size) | 285 | else if (inode->i_size) |
239 | { | 286 | { |
240 | if (offset) | 287 | if (byte_offset) |
241 | { | 288 | { |
289 | kernel_long_ad extent; | ||
290 | |||
242 | /* | 291 | /* |
243 | * OK, there is not extent covering inode->i_size and | 292 | * OK, there is not extent covering inode->i_size and |
244 | * no extent above inode->i_size => truncate is | 293 | * no extent above inode->i_size => truncate is |
245 | * extending the file by 'offset'. | 294 | * extending the file by 'offset' blocks. |
246 | */ | 295 | */ |
247 | if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) || | 296 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || |
248 | (bh && extoffset == sizeof(struct allocExtDesc))) { | 297 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { |
249 | /* File has no extents at all! */ | 298 | /* File has no extents at all or has empty last |
250 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | 299 | * indirect extent! Create a fake extent... */ |
251 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; | 300 | extent.extLocation.logicalBlockNum = 0; |
252 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); | 301 | extent.extLocation.partitionReferenceNum = 0; |
302 | extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; | ||
253 | } | 303 | } |
254 | else { | 304 | else { |
255 | extoffset -= adsize; | 305 | epos.offset -= adsize; |
256 | etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); | 306 | etype = udf_next_aext(inode, &epos, |
257 | if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) | 307 | &extent.extLocation, &extent.extLength, 0); |
258 | { | 308 | extent.extLength |= etype << 30; |
259 | extoffset -= adsize; | ||
260 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset); | ||
261 | udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); | ||
262 | } | ||
263 | else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | ||
264 | { | ||
265 | kernel_lb_addr neloc = { 0, 0 }; | ||
266 | extoffset -= adsize; | ||
267 | nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | | ||
268 | ((elen + offset + inode->i_sb->s_blocksize - 1) & | ||
269 | ~(inode->i_sb->s_blocksize - 1)); | ||
270 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); | ||
271 | udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); | ||
272 | } | ||
273 | else | ||
274 | { | ||
275 | if (elen & (inode->i_sb->s_blocksize - 1)) | ||
276 | { | ||
277 | extoffset -= adsize; | ||
278 | elen = EXT_RECORDED_ALLOCATED | | ||
279 | ((elen + inode->i_sb->s_blocksize - 1) & | ||
280 | ~(inode->i_sb->s_blocksize - 1)); | ||
281 | udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); | ||
282 | } | ||
283 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | ||
284 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; | ||
285 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); | ||
286 | } | ||
287 | } | 309 | } |
310 | udf_extend_file(inode, &epos, &extent, offset+((inode->i_size & (sb->s_blocksize-1)) != 0)); | ||
288 | } | 311 | } |
289 | } | 312 | } |
290 | UDF_I_LENEXTENTS(inode) = inode->i_size; | 313 | UDF_I_LENEXTENTS(inode) = inode->i_size; |
291 | 314 | ||
292 | udf_release_data(bh); | 315 | brelse(epos.bh); |
293 | } | 316 | } |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 110f8d6261..3b2e6c8cb1 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -93,7 +93,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb) | |||
93 | for (i=0; i<nr_groups; i++)\ | 93 | for (i=0; i<nr_groups; i++)\ |
94 | {\ | 94 | {\ |
95 | if (UDF_SB_BITMAP(X,Y,Z,i))\ | 95 | if (UDF_SB_BITMAP(X,Y,Z,i))\ |
96 | udf_release_data(UDF_SB_BITMAP(X,Y,Z,i));\ | 96 | brelse(UDF_SB_BITMAP(X,Y,Z,i));\ |
97 | }\ | 97 | }\ |
98 | if (size <= PAGE_SIZE)\ | 98 | if (size <= PAGE_SIZE)\ |
99 | kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\ | 99 | kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\ |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index ee1dece1f6..f581f2f69c 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -77,6 +77,13 @@ struct ustr | |||
77 | uint8_t u_len; | 77 | uint8_t u_len; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | struct extent_position { | ||
81 | struct buffer_head *bh; | ||
82 | uint32_t offset; | ||
83 | kernel_lb_addr block; | ||
84 | }; | ||
85 | |||
86 | |||
80 | /* super.c */ | 87 | /* super.c */ |
81 | extern void udf_error(struct super_block *, const char *, const char *, ...); | 88 | extern void udf_error(struct super_block *, const char *, const char *, ...); |
82 | extern void udf_warning(struct super_block *, const char *, const char *, ...); | 89 | extern void udf_warning(struct super_block *, const char *, const char *, ...); |
@@ -98,13 +105,14 @@ extern void udf_read_inode(struct inode *); | |||
98 | extern void udf_delete_inode(struct inode *); | 105 | extern void udf_delete_inode(struct inode *); |
99 | extern void udf_clear_inode(struct inode *); | 106 | extern void udf_clear_inode(struct inode *); |
100 | extern int udf_write_inode(struct inode *, int); | 107 | extern int udf_write_inode(struct inode *, int); |
101 | extern long udf_block_map(struct inode *, long); | 108 | extern long udf_block_map(struct inode *, sector_t); |
102 | extern int8_t inode_bmap(struct inode *, int, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **); | 109 | extern int udf_extend_file(struct inode *, struct extent_position *, kernel_long_ad *, sector_t); |
103 | extern int8_t udf_add_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr, uint32_t, struct buffer_head **, int); | 110 | extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *); |
104 | extern int8_t udf_write_aext(struct inode *, kernel_lb_addr, int *, kernel_lb_addr, uint32_t, struct buffer_head *, int); | 111 | extern int8_t udf_add_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int); |
105 | extern int8_t udf_delete_aext(struct inode *, kernel_lb_addr, int, kernel_lb_addr, uint32_t, struct buffer_head *); | 112 | extern int8_t udf_write_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int); |
106 | extern int8_t udf_next_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int); | 113 | extern int8_t udf_delete_aext(struct inode *, struct extent_position, kernel_lb_addr, uint32_t); |
107 | extern int8_t udf_current_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int); | 114 | extern int8_t udf_next_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); |
115 | extern int8_t udf_current_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); | ||
108 | 116 | ||
109 | /* misc.c */ | 117 | /* misc.c */ |
110 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); | 118 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); |
@@ -113,7 +121,6 @@ extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, uint | |||
113 | extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t); | 121 | extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t); |
114 | extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *); | 122 | extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *); |
115 | extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *); | 123 | extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *); |
116 | extern void udf_release_data(struct buffer_head *); | ||
117 | extern void udf_update_tag(char *, int); | 124 | extern void udf_update_tag(char *, int); |
118 | extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); | 125 | extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); |
119 | 126 | ||
@@ -139,6 +146,7 @@ extern void udf_free_inode(struct inode *); | |||
139 | extern struct inode * udf_new_inode (struct inode *, int, int *); | 146 | extern struct inode * udf_new_inode (struct inode *, int, int *); |
140 | 147 | ||
141 | /* truncate.c */ | 148 | /* truncate.c */ |
149 | extern void udf_truncate_tail_extent(struct inode *); | ||
142 | extern void udf_discard_prealloc(struct inode *); | 150 | extern void udf_discard_prealloc(struct inode *); |
143 | extern void udf_truncate_extents(struct inode *); | 151 | extern void udf_truncate_extents(struct inode *); |
144 | 152 | ||
@@ -151,7 +159,7 @@ extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_ | |||
151 | extern int udf_fsync_file(struct file *, struct dentry *, int); | 159 | extern int udf_fsync_file(struct file *, struct dentry *, int); |
152 | 160 | ||
153 | /* directory.c */ | 161 | /* directory.c */ |
154 | extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **); | 162 | extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *); |
155 | extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset); | 163 | extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset); |
156 | extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int); | 164 | extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int); |
157 | extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int); | 165 | extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int); |