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