diff options
author | Jan Kara <jack@suse.cz> | 2007-05-08 03:35:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:21 -0400 |
commit | ff116fc8d1d43927c7651b91d5aec41eb30c4429 (patch) | |
tree | 9b452298e6f070be35b2d366ce4a10e4a1384d17 /fs | |
parent | 60448b1d6db4e82946ff9a2ac88df341f5fa87a2 (diff) |
UDF: introduce struct extent_position
Introduce a structure extent_position to store a position of an extent and
the corresponding buffer_head in one place.
Signed-off-by: Jan Kara <jack@suse.cz>
Acked-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/udf/balloc.c | 172 | ||||
-rw-r--r-- | fs/udf/dir.c | 25 | ||||
-rw-r--r-- | fs/udf/directory.c | 20 | ||||
-rw-r--r-- | fs/udf/inode.c | 343 | ||||
-rw-r--r-- | fs/udf/namei.c | 122 | ||||
-rw-r--r-- | fs/udf/super.c | 17 | ||||
-rw-r--r-- | fs/udf/truncate.c | 159 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 21 |
8 files changed, 434 insertions, 445 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index ea521f846d97..756dbbf0eafd 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 | udf_release_data(oepos.bh); |
513 | atomic_inc(&nbh->b_count); | 512 | atomic_inc(&epos.bh->b_count); |
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 | udf_release_data(oepos.bh); |
551 | udf_release_data(nbh); | 550 | udf_release_data(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 | udf_release_data(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 | udf_release_data(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 | udf_release_data(epos.bh); |
665 | udf_release_data(obh); | 662 | udf_release_data(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 | udf_release_data(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 | udf_release_data(goal_epos.bh); |
799 | goal_bh = bh; | 793 | goal_epos.bh = epos.bh; |
800 | atomic_inc(&goal_bh->b_count); | 794 | atomic_inc(&goal_epos.bh->b_count); |
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 | udf_release_data(epos.bh); |
810 | 804 | ||
811 | if (spread == 0xFFFFFFFF) | 805 | if (spread == 0xFFFFFFFF) |
812 | { | 806 | { |
813 | udf_release_data(goal_bh); | 807 | udf_release_data(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 | udf_release_data(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 | udf_release_data(goal_epos.bh); |
840 | 834 | ||
841 | if (UDF_SB_LVIDBH(sb)) | 835 | if (UDF_SB_LVIDBH(sb)) |
842 | { | 836 | { |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 3c50b82a2307..00c15d3dd756 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -111,12 +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; | 116 | uint32_t elen; |
117 | sector_t offset; | 117 | sector_t offset; |
118 | int i, num; | 118 | int i, num; |
119 | unsigned int dt_type; | 119 | unsigned int dt_type; |
120 | struct extent_position epos = { NULL, 0, {0, 0}}; | ||
120 | 121 | ||
121 | if (nf_pos >= size) | 122 | if (nf_pos >= size) |
122 | return 0; | 123 | return 0; |
@@ -128,22 +129,22 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
128 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 129 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
129 | fibh.sbh = fibh.ebh = NULL; | 130 | fibh.sbh = fibh.ebh = NULL; |
130 | 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), |
131 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 132 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
132 | { | 133 | { |
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 | udf_release_data(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 | udf_release_data(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 | udf_release_data(fibh.ebh); |
188 | udf_release_data(fibh.sbh); | 189 | udf_release_data(fibh.sbh); |
189 | udf_release_data(bh); | 190 | udf_release_data(epos.bh); |
190 | return 0; | 191 | return 0; |
191 | } | 192 | } |
192 | 193 | ||
@@ -246,7 +247,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
246 | if (fibh.sbh != fibh.ebh) | 247 | if (fibh.sbh != fibh.ebh) |
247 | udf_release_data(fibh.ebh); | 248 | udf_release_data(fibh.ebh); |
248 | udf_release_data(fibh.sbh); | 249 | udf_release_data(fibh.sbh); |
249 | udf_release_data(bh); | 250 | udf_release_data(epos.bh); |
250 | return 0; | 251 | return 0; |
251 | } | 252 | } |
252 | } | 253 | } |
@@ -257,7 +258,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
257 | if (fibh.sbh != fibh.ebh) | 258 | if (fibh.sbh != fibh.ebh) |
258 | udf_release_data(fibh.ebh); | 259 | udf_release_data(fibh.ebh); |
259 | udf_release_data(fibh.sbh); | 260 | udf_release_data(fibh.sbh); |
260 | udf_release_data(bh); | 261 | udf_release_data(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 024ccac8b7f4..9f66cfe124c6 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c | |||
@@ -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 | sector_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,7 +118,7 @@ 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 | udf_release_data(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))) |
@@ -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/inode.c b/fs/udf/inode.c index 6b094250d805..a106acb58292 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -51,8 +51,8 @@ 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 *, sector_t, 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,13 +238,13 @@ 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 | udf_release_data(dbh); |
@@ -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 | udf_release_data(epos.bh); |
279 | mark_inode_dirty(inode); | 281 | mark_inode_dirty(inode); |
280 | return dbh; | 282 | return dbh; |
281 | } | 283 | } |
@@ -357,12 +359,12 @@ udf_getblk(struct inode *inode, long block, int create, int *err) | |||
357 | static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | 359 | static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, |
358 | int *err, long *phys, int *new) | 360 | int *err, long *phys, int *new) |
359 | { | 361 | { |
360 | struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL; | 362 | struct buffer_head *result = NULL; |
361 | kernel_long_ad laarr[EXTENT_MERGE_SIZE]; | 363 | kernel_long_ad laarr[EXTENT_MERGE_SIZE]; |
362 | uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0; | 364 | struct extent_position prev_epos, cur_epos, next_epos; |
363 | int count = 0, startnum = 0, endnum = 0; | 365 | int count = 0, startnum = 0, endnum = 0; |
364 | uint32_t elen = 0; | 366 | uint32_t elen = 0; |
365 | kernel_lb_addr eloc, pbloc, cbloc, nbloc; | 367 | kernel_lb_addr eloc; |
366 | int c = 1; | 368 | int c = 1; |
367 | loff_t lbcount = 0, b_off = 0; | 369 | loff_t lbcount = 0, b_off = 0; |
368 | uint32_t newblocknum, newblock; | 370 | uint32_t newblocknum, newblock; |
@@ -371,37 +373,39 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | |||
371 | int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; | 373 | int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; |
372 | char lastblock = 0; | 374 | char lastblock = 0; |
373 | 375 | ||
374 | pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode); | 376 | prev_epos.offset = udf_file_entry_alloc_offset(inode); |
377 | prev_epos.block = UDF_I_LOCATION(inode); | ||
378 | prev_epos.bh = NULL; | ||
379 | cur_epos = next_epos = prev_epos; | ||
375 | b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; | 380 | b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; |
376 | pbloc = cbloc = nbloc = UDF_I_LOCATION(inode); | ||
377 | 381 | ||
378 | /* find the extent which contains the block we are looking for. | 382 | /* find the extent which contains the block we are looking for. |
379 | alternate between laarr[0] and laarr[1] for locations of the | 383 | alternate between laarr[0] and laarr[1] for locations of the |
380 | current extent, and the previous extent */ | 384 | current extent, and the previous extent */ |
381 | do | 385 | do |
382 | { | 386 | { |
383 | if (pbh != cbh) | 387 | if (prev_epos.bh != cur_epos.bh) |
384 | { | 388 | { |
385 | udf_release_data(pbh); | 389 | udf_release_data(prev_epos.bh); |
386 | atomic_inc(&cbh->b_count); | 390 | atomic_inc(&cur_epos.bh->b_count); |
387 | pbh = cbh; | 391 | prev_epos.bh = cur_epos.bh; |
388 | } | 392 | } |
389 | if (cbh != nbh) | 393 | if (cur_epos.bh != next_epos.bh) |
390 | { | 394 | { |
391 | udf_release_data(cbh); | 395 | udf_release_data(cur_epos.bh); |
392 | atomic_inc(&nbh->b_count); | 396 | atomic_inc(&next_epos.bh->b_count); |
393 | cbh = nbh; | 397 | cur_epos.bh = next_epos.bh; |
394 | } | 398 | } |
395 | 399 | ||
396 | lbcount += elen; | 400 | lbcount += elen; |
397 | 401 | ||
398 | pbloc = cbloc; | 402 | prev_epos.block = cur_epos.block; |
399 | cbloc = nbloc; | 403 | cur_epos.block = next_epos.block; |
400 | 404 | ||
401 | pextoffset = cextoffset; | 405 | prev_epos.offset = cur_epos.offset; |
402 | cextoffset = nextoffset; | 406 | cur_epos.offset = next_epos.offset; |
403 | 407 | ||
404 | if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1) | 408 | if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1) |
405 | break; | 409 | break; |
406 | 410 | ||
407 | c = !c; | 411 | c = !c; |
@@ -430,11 +434,11 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | |||
430 | elen = EXT_RECORDED_ALLOCATED | | 434 | elen = EXT_RECORDED_ALLOCATED | |
431 | ((elen + inode->i_sb->s_blocksize - 1) & | 435 | ((elen + inode->i_sb->s_blocksize - 1) & |
432 | ~(inode->i_sb->s_blocksize - 1)); | 436 | ~(inode->i_sb->s_blocksize - 1)); |
433 | etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1); | 437 | etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1); |
434 | } | 438 | } |
435 | udf_release_data(pbh); | 439 | udf_release_data(prev_epos.bh); |
436 | udf_release_data(cbh); | 440 | udf_release_data(cur_epos.bh); |
437 | udf_release_data(nbh); | 441 | udf_release_data(next_epos.bh); |
438 | newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); | 442 | newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
439 | *phys = newblock; | 443 | *phys = newblock; |
440 | return NULL; | 444 | return NULL; |
@@ -477,7 +481,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | |||
477 | /* if the current block is located in a extent, read the next extent */ | 481 | /* if the current block is located in a extent, read the next extent */ |
478 | if (etype != -1) | 482 | if (etype != -1) |
479 | { | 483 | { |
480 | if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1) | 484 | if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) |
481 | { | 485 | { |
482 | laarr[c+1].extLength = (etype << 30) | elen; | 486 | laarr[c+1].extLength = (etype << 30) | elen; |
483 | laarr[c+1].extLocation = eloc; | 487 | laarr[c+1].extLocation = eloc; |
@@ -488,8 +492,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | |||
488 | else | 492 | else |
489 | lastblock = 1; | 493 | lastblock = 1; |
490 | } | 494 | } |
491 | udf_release_data(cbh); | 495 | udf_release_data(cur_epos.bh); |
492 | udf_release_data(nbh); | 496 | udf_release_data(next_epos.bh); |
493 | 497 | ||
494 | /* if the current extent is not recorded but allocated, get the | 498 | /* if the current extent is not recorded but allocated, get the |
495 | block in the extent corresponding to the requested block */ | 499 | block in the extent corresponding to the requested block */ |
@@ -509,7 +513,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | |||
509 | if (!(newblocknum = udf_new_block(inode->i_sb, inode, | 513 | if (!(newblocknum = udf_new_block(inode->i_sb, inode, |
510 | UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) | 514 | UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) |
511 | { | 515 | { |
512 | udf_release_data(pbh); | 516 | udf_release_data(prev_epos.bh); |
513 | *err = -ENOSPC; | 517 | *err = -ENOSPC; |
514 | return NULL; | 518 | return NULL; |
515 | } | 519 | } |
@@ -532,9 +536,9 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, | |||
532 | /* write back the new extents, inserting new extents if the new number | 536 | /* write back the new extents, inserting new extents if the new number |
533 | of extents is greater than the old number, and deleting extents if | 537 | of extents is greater than the old number, and deleting extents if |
534 | the new number of extents is less than the old number */ | 538 | the new number of extents is less than the old number */ |
535 | udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh); | 539 | udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); |
536 | 540 | ||
537 | udf_release_data(pbh); | 541 | udf_release_data(prev_epos.bh); |
538 | 542 | ||
539 | if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, | 543 | if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, |
540 | UDF_I_LOCATION(inode).partitionReferenceNum, 0))) | 544 | UDF_I_LOCATION(inode).partitionReferenceNum, 0))) |
@@ -796,7 +800,7 @@ static void udf_merge_extents(struct inode *inode, | |||
796 | 800 | ||
797 | static void udf_update_extents(struct inode *inode, | 801 | static void udf_update_extents(struct inode *inode, |
798 | kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, | 802 | kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, |
799 | kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh) | 803 | struct extent_position *epos) |
800 | { | 804 | { |
801 | int start = 0, i; | 805 | int start = 0, i; |
802 | kernel_lb_addr tmploc; | 806 | kernel_lb_addr tmploc; |
@@ -805,28 +809,26 @@ static void udf_update_extents(struct inode *inode, | |||
805 | if (startnum > endnum) | 809 | if (startnum > endnum) |
806 | { | 810 | { |
807 | for (i=0; i<(startnum-endnum); i++) | 811 | for (i=0; i<(startnum-endnum); i++) |
808 | { | 812 | udf_delete_aext(inode, *epos, laarr[i].extLocation, |
809 | udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation, | 813 | laarr[i].extLength); |
810 | laarr[i].extLength, *pbh); | ||
811 | } | ||
812 | } | 814 | } |
813 | else if (startnum < endnum) | 815 | else if (startnum < endnum) |
814 | { | 816 | { |
815 | for (i=0; i<(endnum-startnum); i++) | 817 | for (i=0; i<(endnum-startnum); i++) |
816 | { | 818 | { |
817 | udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation, | 819 | udf_insert_aext(inode, *epos, laarr[i].extLocation, |
818 | laarr[i].extLength, *pbh); | 820 | laarr[i].extLength); |
819 | udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation, | 821 | udf_next_aext(inode, epos, &laarr[i].extLocation, |
820 | &laarr[i].extLength, pbh, 1); | 822 | &laarr[i].extLength, 1); |
821 | start ++; | 823 | start ++; |
822 | } | 824 | } |
823 | } | 825 | } |
824 | 826 | ||
825 | for (i=start; i<endnum; i++) | 827 | for (i=start; i<endnum; i++) |
826 | { | 828 | { |
827 | udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0); | 829 | udf_next_aext(inode, epos, &tmploc, &tmplen, 0); |
828 | udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation, | 830 | udf_write_aext(inode, epos, laarr[i].extLocation, |
829 | laarr[i].extLength, *pbh, 1); | 831 | laarr[i].extLength, 1); |
830 | } | 832 | } |
831 | } | 833 | } |
832 | 834 | ||
@@ -1557,8 +1559,8 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino) | |||
1557 | return NULL; | 1559 | return NULL; |
1558 | } | 1560 | } |
1559 | 1561 | ||
1560 | int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1562 | int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, |
1561 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) | 1563 | kernel_lb_addr eloc, uint32_t elen, int inc) |
1562 | { | 1564 | { |
1563 | int adsize; | 1565 | int adsize; |
1564 | short_ad *sad = NULL; | 1566 | short_ad *sad = NULL; |
@@ -1567,10 +1569,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1567 | int8_t etype; | 1569 | int8_t etype; |
1568 | uint8_t *ptr; | 1570 | uint8_t *ptr; |
1569 | 1571 | ||
1570 | if (!*bh) | 1572 | if (!epos->bh) |
1571 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1573 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1572 | else | 1574 | else |
1573 | ptr = (*bh)->b_data + *extoffset; | 1575 | ptr = epos->bh->b_data + epos->offset; |
1574 | 1576 | ||
1575 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 1577 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
1576 | adsize = sizeof(short_ad); | 1578 | adsize = sizeof(short_ad); |
@@ -1579,20 +1581,20 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1579 | else | 1581 | else |
1580 | return -1; | 1582 | return -1; |
1581 | 1583 | ||
1582 | if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize) | 1584 | if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) |
1583 | { | 1585 | { |
1584 | char *sptr, *dptr; | 1586 | char *sptr, *dptr; |
1585 | struct buffer_head *nbh; | 1587 | struct buffer_head *nbh; |
1586 | int err, loffset; | 1588 | int err, loffset; |
1587 | kernel_lb_addr obloc = *bloc; | 1589 | kernel_lb_addr obloc = epos->block; |
1588 | 1590 | ||
1589 | if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL, | 1591 | if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, |
1590 | obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) | 1592 | obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) |
1591 | { | 1593 | { |
1592 | return -1; | 1594 | return -1; |
1593 | } | 1595 | } |
1594 | if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, | 1596 | if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, |
1595 | *bloc, 0)))) | 1597 | epos->block, 0)))) |
1596 | { | 1598 | { |
1597 | return -1; | 1599 | return -1; |
1598 | } | 1600 | } |
@@ -1605,25 +1607,25 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1605 | aed = (struct allocExtDesc *)(nbh->b_data); | 1607 | aed = (struct allocExtDesc *)(nbh->b_data); |
1606 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) | 1608 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) |
1607 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); | 1609 | aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); |
1608 | if (*extoffset + adsize > inode->i_sb->s_blocksize) | 1610 | if (epos->offset + adsize > inode->i_sb->s_blocksize) |
1609 | { | 1611 | { |
1610 | loffset = *extoffset; | 1612 | loffset = epos->offset; |
1611 | aed->lengthAllocDescs = cpu_to_le32(adsize); | 1613 | aed->lengthAllocDescs = cpu_to_le32(adsize); |
1612 | sptr = ptr - adsize; | 1614 | sptr = ptr - adsize; |
1613 | dptr = nbh->b_data + sizeof(struct allocExtDesc); | 1615 | dptr = nbh->b_data + sizeof(struct allocExtDesc); |
1614 | memcpy(dptr, sptr, adsize); | 1616 | memcpy(dptr, sptr, adsize); |
1615 | *extoffset = sizeof(struct allocExtDesc) + adsize; | 1617 | epos->offset = sizeof(struct allocExtDesc) + adsize; |
1616 | } | 1618 | } |
1617 | else | 1619 | else |
1618 | { | 1620 | { |
1619 | loffset = *extoffset + adsize; | 1621 | loffset = epos->offset + adsize; |
1620 | aed->lengthAllocDescs = cpu_to_le32(0); | 1622 | aed->lengthAllocDescs = cpu_to_le32(0); |
1621 | sptr = ptr; | 1623 | sptr = ptr; |
1622 | *extoffset = sizeof(struct allocExtDesc); | 1624 | epos->offset = sizeof(struct allocExtDesc); |
1623 | 1625 | ||
1624 | if (*bh) | 1626 | if (epos->bh) |
1625 | { | 1627 | { |
1626 | aed = (struct allocExtDesc *)(*bh)->b_data; | 1628 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1627 | aed->lengthAllocDescs = | 1629 | aed->lengthAllocDescs = |
1628 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 1630 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1629 | } | 1631 | } |
@@ -1635,10 +1637,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1635 | } | 1637 | } |
1636 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) | 1638 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) |
1637 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, | 1639 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, |
1638 | bloc->logicalBlockNum, sizeof(tag)); | 1640 | epos->block.logicalBlockNum, sizeof(tag)); |
1639 | else | 1641 | else |
1640 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, | 1642 | udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, |
1641 | bloc->logicalBlockNum, sizeof(tag)); | 1643 | epos->block.logicalBlockNum, sizeof(tag)); |
1642 | switch (UDF_I_ALLOCTYPE(inode)) | 1644 | switch (UDF_I_ALLOCTYPE(inode)) |
1643 | { | 1645 | { |
1644 | case ICBTAG_FLAG_AD_SHORT: | 1646 | case ICBTAG_FLAG_AD_SHORT: |
@@ -1647,7 +1649,7 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1647 | sad->extLength = cpu_to_le32( | 1649 | sad->extLength = cpu_to_le32( |
1648 | EXT_NEXT_EXTENT_ALLOCDECS | | 1650 | EXT_NEXT_EXTENT_ALLOCDECS | |
1649 | inode->i_sb->s_blocksize); | 1651 | inode->i_sb->s_blocksize); |
1650 | sad->extPosition = cpu_to_le32(bloc->logicalBlockNum); | 1652 | sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum); |
1651 | break; | 1653 | break; |
1652 | } | 1654 | } |
1653 | case ICBTAG_FLAG_AD_LONG: | 1655 | case ICBTAG_FLAG_AD_LONG: |
@@ -1656,60 +1658,57 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1656 | lad->extLength = cpu_to_le32( | 1658 | lad->extLength = cpu_to_le32( |
1657 | EXT_NEXT_EXTENT_ALLOCDECS | | 1659 | EXT_NEXT_EXTENT_ALLOCDECS | |
1658 | inode->i_sb->s_blocksize); | 1660 | inode->i_sb->s_blocksize); |
1659 | lad->extLocation = cpu_to_lelb(*bloc); | 1661 | lad->extLocation = cpu_to_lelb(epos->block); |
1660 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); | 1662 | memset(lad->impUse, 0x00, sizeof(lad->impUse)); |
1661 | break; | 1663 | break; |
1662 | } | 1664 | } |
1663 | } | 1665 | } |
1664 | if (*bh) | 1666 | if (epos->bh) |
1665 | { | 1667 | { |
1666 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1668 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1667 | udf_update_tag((*bh)->b_data, loffset); | 1669 | udf_update_tag(epos->bh->b_data, loffset); |
1668 | else | 1670 | else |
1669 | udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); | 1671 | udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
1670 | mark_buffer_dirty_inode(*bh, inode); | 1672 | mark_buffer_dirty_inode(epos->bh, inode); |
1671 | udf_release_data(*bh); | 1673 | udf_release_data(epos->bh); |
1672 | } | 1674 | } |
1673 | else | 1675 | else |
1674 | mark_inode_dirty(inode); | 1676 | mark_inode_dirty(inode); |
1675 | *bh = nbh; | 1677 | epos->bh = nbh; |
1676 | } | 1678 | } |
1677 | 1679 | ||
1678 | etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc); | 1680 | etype = udf_write_aext(inode, epos, eloc, elen, inc); |
1679 | 1681 | ||
1680 | if (!*bh) | 1682 | if (!epos->bh) |
1681 | { | 1683 | { |
1682 | UDF_I_LENALLOC(inode) += adsize; | 1684 | UDF_I_LENALLOC(inode) += adsize; |
1683 | mark_inode_dirty(inode); | 1685 | mark_inode_dirty(inode); |
1684 | } | 1686 | } |
1685 | else | 1687 | else |
1686 | { | 1688 | { |
1687 | aed = (struct allocExtDesc *)(*bh)->b_data; | 1689 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1688 | aed->lengthAllocDescs = | 1690 | aed->lengthAllocDescs = |
1689 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); | 1691 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); |
1690 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1692 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1691 | udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize)); | 1693 | udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize)); |
1692 | else | 1694 | else |
1693 | udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); | 1695 | udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); |
1694 | mark_buffer_dirty_inode(*bh, inode); | 1696 | mark_buffer_dirty_inode(epos->bh, inode); |
1695 | } | 1697 | } |
1696 | 1698 | ||
1697 | return etype; | 1699 | return etype; |
1698 | } | 1700 | } |
1699 | 1701 | ||
1700 | int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, | 1702 | int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, |
1701 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) | 1703 | kernel_lb_addr eloc, uint32_t elen, int inc) |
1702 | { | 1704 | { |
1703 | int adsize; | 1705 | int adsize; |
1704 | uint8_t *ptr; | 1706 | uint8_t *ptr; |
1705 | 1707 | ||
1706 | if (!bh) | 1708 | if (!epos->bh) |
1707 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1709 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1708 | else | 1710 | else |
1709 | { | 1711 | ptr = epos->bh->b_data + epos->offset; |
1710 | ptr = bh->b_data + *extoffset; | ||
1711 | atomic_inc(&bh->b_count); | ||
1712 | } | ||
1713 | 1712 | ||
1714 | switch (UDF_I_ALLOCTYPE(inode)) | 1713 | switch (UDF_I_ALLOCTYPE(inode)) |
1715 | { | 1714 | { |
@@ -1734,40 +1733,39 @@ int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, | |||
1734 | return -1; | 1733 | return -1; |
1735 | } | 1734 | } |
1736 | 1735 | ||
1737 | if (bh) | 1736 | if (epos->bh) |
1738 | { | 1737 | { |
1739 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1738 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1740 | { | 1739 | { |
1741 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data; | 1740 | struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data; |
1742 | udf_update_tag((bh)->b_data, | 1741 | udf_update_tag(epos->bh->b_data, |
1743 | le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); | 1742 | le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); |
1744 | } | 1743 | } |
1745 | mark_buffer_dirty_inode(bh, inode); | 1744 | mark_buffer_dirty_inode(epos->bh, inode); |
1746 | udf_release_data(bh); | ||
1747 | } | 1745 | } |
1748 | else | 1746 | else |
1749 | mark_inode_dirty(inode); | 1747 | mark_inode_dirty(inode); |
1750 | 1748 | ||
1751 | if (inc) | 1749 | if (inc) |
1752 | *extoffset += adsize; | 1750 | epos->offset += adsize; |
1753 | return (elen >> 30); | 1751 | return (elen >> 30); |
1754 | } | 1752 | } |
1755 | 1753 | ||
1756 | int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1754 | int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, |
1757 | kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) | 1755 | kernel_lb_addr *eloc, uint32_t *elen, int inc) |
1758 | { | 1756 | { |
1759 | int8_t etype; | 1757 | int8_t etype; |
1760 | 1758 | ||
1761 | while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) == | 1759 | while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == |
1762 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) | 1760 | (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
1763 | { | 1761 | { |
1764 | *bloc = *eloc; | 1762 | epos->block = *eloc; |
1765 | *extoffset = sizeof(struct allocExtDesc); | 1763 | epos->offset = sizeof(struct allocExtDesc); |
1766 | udf_release_data(*bh); | 1764 | udf_release_data(epos->bh); |
1767 | if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) | 1765 | if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0)))) |
1768 | { | 1766 | { |
1769 | udf_debug("reading block %d failed!\n", | 1767 | udf_debug("reading block %d failed!\n", |
1770 | udf_get_lb_pblock(inode->i_sb, *bloc, 0)); | 1768 | udf_get_lb_pblock(inode->i_sb, epos->block, 0)); |
1771 | return -1; | 1769 | return -1; |
1772 | } | 1770 | } |
1773 | } | 1771 | } |
@@ -1775,26 +1773,26 @@ int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | |||
1775 | return etype; | 1773 | return etype; |
1776 | } | 1774 | } |
1777 | 1775 | ||
1778 | int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, | 1776 | int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, |
1779 | kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) | 1777 | kernel_lb_addr *eloc, uint32_t *elen, int inc) |
1780 | { | 1778 | { |
1781 | int alen; | 1779 | int alen; |
1782 | int8_t etype; | 1780 | int8_t etype; |
1783 | uint8_t *ptr; | 1781 | uint8_t *ptr; |
1784 | 1782 | ||
1785 | if (!*bh) | 1783 | if (!epos->bh) |
1786 | { | 1784 | { |
1787 | if (!(*extoffset)) | 1785 | if (!epos->offset) |
1788 | *extoffset = udf_file_entry_alloc_offset(inode); | 1786 | epos->offset = udf_file_entry_alloc_offset(inode); |
1789 | ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); | 1787 | ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); |
1790 | alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); | 1788 | alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); |
1791 | } | 1789 | } |
1792 | else | 1790 | else |
1793 | { | 1791 | { |
1794 | if (!(*extoffset)) | 1792 | if (!epos->offset) |
1795 | *extoffset = sizeof(struct allocExtDesc); | 1793 | epos->offset = sizeof(struct allocExtDesc); |
1796 | ptr = (*bh)->b_data + *extoffset; | 1794 | ptr = epos->bh->b_data + epos->offset; |
1797 | alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); | 1795 | alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs); |
1798 | } | 1796 | } |
1799 | 1797 | ||
1800 | switch (UDF_I_ALLOCTYPE(inode)) | 1798 | switch (UDF_I_ALLOCTYPE(inode)) |
@@ -1803,7 +1801,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1803 | { | 1801 | { |
1804 | short_ad *sad; | 1802 | short_ad *sad; |
1805 | 1803 | ||
1806 | if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc))) | 1804 | if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc))) |
1807 | return -1; | 1805 | return -1; |
1808 | 1806 | ||
1809 | etype = le32_to_cpu(sad->extLength) >> 30; | 1807 | etype = le32_to_cpu(sad->extLength) >> 30; |
@@ -1816,7 +1814,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1816 | { | 1814 | { |
1817 | long_ad *lad; | 1815 | long_ad *lad; |
1818 | 1816 | ||
1819 | if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc))) | 1817 | if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc))) |
1820 | return -1; | 1818 | return -1; |
1821 | 1819 | ||
1822 | etype = le32_to_cpu(lad->extLength) >> 30; | 1820 | etype = le32_to_cpu(lad->extLength) >> 30; |
@@ -1835,41 +1833,40 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse | |||
1835 | } | 1833 | } |
1836 | 1834 | ||
1837 | static int8_t | 1835 | static int8_t |
1838 | udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset, | 1836 | udf_insert_aext(struct inode *inode, struct extent_position epos, |
1839 | kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh) | 1837 | kernel_lb_addr neloc, uint32_t nelen) |
1840 | { | 1838 | { |
1841 | kernel_lb_addr oeloc; | 1839 | kernel_lb_addr oeloc; |
1842 | uint32_t oelen; | 1840 | uint32_t oelen; |
1843 | int8_t etype; | 1841 | int8_t etype; |
1844 | 1842 | ||
1845 | if (bh) | 1843 | if (epos.bh) |
1846 | atomic_inc(&bh->b_count); | 1844 | atomic_inc(&epos.bh->b_count); |
1847 | 1845 | ||
1848 | while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1) | 1846 | while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) |
1849 | { | 1847 | { |
1850 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); | 1848 | udf_write_aext(inode, &epos, neloc, nelen, 1); |
1851 | 1849 | ||
1852 | neloc = oeloc; | 1850 | neloc = oeloc; |
1853 | nelen = (etype << 30) | oelen; | 1851 | nelen = (etype << 30) | oelen; |
1854 | } | 1852 | } |
1855 | udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1); | 1853 | udf_add_aext(inode, &epos, neloc, nelen, 1); |
1856 | udf_release_data(bh); | 1854 | udf_release_data(epos.bh); |
1857 | return (nelen >> 30); | 1855 | return (nelen >> 30); |
1858 | } | 1856 | } |
1859 | 1857 | ||
1860 | int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset, | 1858 | int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, |
1861 | kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh) | 1859 | kernel_lb_addr eloc, uint32_t elen) |
1862 | { | 1860 | { |
1863 | struct buffer_head *obh; | 1861 | struct extent_position oepos; |
1864 | kernel_lb_addr obloc; | 1862 | int adsize; |
1865 | int oextoffset, adsize; | ||
1866 | int8_t etype; | 1863 | int8_t etype; |
1867 | struct allocExtDesc *aed; | 1864 | struct allocExtDesc *aed; |
1868 | 1865 | ||
1869 | if (nbh) | 1866 | if (epos.bh) |
1870 | { | 1867 | { |
1871 | atomic_inc(&nbh->b_count); | 1868 | atomic_inc(&epos.bh->b_count); |
1872 | atomic_inc(&nbh->b_count); | 1869 | atomic_inc(&epos.bh->b_count); |
1873 | } | 1870 | } |
1874 | 1871 | ||
1875 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 1872 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
@@ -1879,78 +1876,75 @@ int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset | |||
1879 | else | 1876 | else |
1880 | adsize = 0; | 1877 | adsize = 0; |
1881 | 1878 | ||
1882 | obh = nbh; | 1879 | oepos = epos; |
1883 | obloc = nbloc; | 1880 | if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) |
1884 | oextoffset = nextoffset; | ||
1885 | |||
1886 | if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1) | ||
1887 | return -1; | 1881 | return -1; |
1888 | 1882 | ||
1889 | while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) | 1883 | while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) |
1890 | { | 1884 | { |
1891 | udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1); | 1885 | udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1); |
1892 | if (obh != nbh) | 1886 | if (oepos.bh != epos.bh) |
1893 | { | 1887 | { |
1894 | obloc = nbloc; | 1888 | oepos.block = epos.block; |
1895 | udf_release_data(obh); | 1889 | udf_release_data(oepos.bh); |
1896 | atomic_inc(&nbh->b_count); | 1890 | atomic_inc(&epos.bh->b_count); |
1897 | obh = nbh; | 1891 | oepos.bh = epos.bh; |
1898 | oextoffset = nextoffset - adsize; | 1892 | oepos.offset = epos.offset - adsize; |
1899 | } | 1893 | } |
1900 | } | 1894 | } |
1901 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | 1895 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); |
1902 | elen = 0; | 1896 | elen = 0; |
1903 | 1897 | ||
1904 | if (nbh != obh) | 1898 | if (epos.bh != oepos.bh) |
1905 | { | 1899 | { |
1906 | udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1); | 1900 | udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1); |
1907 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 1901 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1908 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 1902 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1909 | if (!obh) | 1903 | if (!oepos.bh) |
1910 | { | 1904 | { |
1911 | UDF_I_LENALLOC(inode) -= (adsize * 2); | 1905 | UDF_I_LENALLOC(inode) -= (adsize * 2); |
1912 | mark_inode_dirty(inode); | 1906 | mark_inode_dirty(inode); |
1913 | } | 1907 | } |
1914 | else | 1908 | else |
1915 | { | 1909 | { |
1916 | aed = (struct allocExtDesc *)(obh)->b_data; | 1910 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
1917 | aed->lengthAllocDescs = | 1911 | aed->lengthAllocDescs = |
1918 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); | 1912 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); |
1919 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1913 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1920 | udf_update_tag((obh)->b_data, oextoffset - (2*adsize)); | 1914 | udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize)); |
1921 | else | 1915 | else |
1922 | udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); | 1916 | udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
1923 | mark_buffer_dirty_inode(obh, inode); | 1917 | mark_buffer_dirty_inode(oepos.bh, inode); |
1924 | } | 1918 | } |
1925 | } | 1919 | } |
1926 | else | 1920 | else |
1927 | { | 1921 | { |
1928 | udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); | 1922 | udf_write_aext(inode, &oepos, eloc, elen, 1); |
1929 | if (!obh) | 1923 | if (!oepos.bh) |
1930 | { | 1924 | { |
1931 | UDF_I_LENALLOC(inode) -= adsize; | 1925 | UDF_I_LENALLOC(inode) -= adsize; |
1932 | mark_inode_dirty(inode); | 1926 | mark_inode_dirty(inode); |
1933 | } | 1927 | } |
1934 | else | 1928 | else |
1935 | { | 1929 | { |
1936 | aed = (struct allocExtDesc *)(obh)->b_data; | 1930 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
1937 | aed->lengthAllocDescs = | 1931 | aed->lengthAllocDescs = |
1938 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); | 1932 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); |
1939 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 1933 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
1940 | udf_update_tag((obh)->b_data, oextoffset - adsize); | 1934 | udf_update_tag(oepos.bh->b_data, epos.offset - adsize); |
1941 | else | 1935 | else |
1942 | udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); | 1936 | udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); |
1943 | mark_buffer_dirty_inode(obh, inode); | 1937 | mark_buffer_dirty_inode(oepos.bh, inode); |
1944 | } | 1938 | } |
1945 | } | 1939 | } |
1946 | 1940 | ||
1947 | udf_release_data(nbh); | 1941 | udf_release_data(epos.bh); |
1948 | udf_release_data(obh); | 1942 | udf_release_data(oepos.bh); |
1949 | return (elen >> 30); | 1943 | return (elen >> 30); |
1950 | } | 1944 | } |
1951 | 1945 | ||
1952 | int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uint32_t *extoffset, | 1946 | int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos, |
1953 | kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset, struct buffer_head **bh) | 1947 | kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) |
1954 | { | 1948 | { |
1955 | loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits; | 1949 | loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits; |
1956 | int8_t etype; | 1950 | int8_t etype; |
@@ -1961,13 +1955,14 @@ int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uin | |||
1961 | return -1; | 1955 | return -1; |
1962 | } | 1956 | } |
1963 | 1957 | ||
1964 | *extoffset = 0; | 1958 | pos->offset = 0; |
1959 | pos->block = UDF_I_LOCATION(inode); | ||
1960 | pos->bh = NULL; | ||
1965 | *elen = 0; | 1961 | *elen = 0; |
1966 | *bloc = UDF_I_LOCATION(inode); | ||
1967 | 1962 | ||
1968 | do | 1963 | do |
1969 | { | 1964 | { |
1970 | if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1) | 1965 | if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) |
1971 | { | 1966 | { |
1972 | *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits; | 1967 | *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits; |
1973 | UDF_I_LENEXTENTS(inode) = lbcount; | 1968 | UDF_I_LENEXTENTS(inode) = lbcount; |
@@ -1983,21 +1978,21 @@ int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uin | |||
1983 | 1978 | ||
1984 | long udf_block_map(struct inode *inode, sector_t block) | 1979 | long udf_block_map(struct inode *inode, sector_t block) |
1985 | { | 1980 | { |
1986 | kernel_lb_addr eloc, bloc; | 1981 | kernel_lb_addr eloc; |
1987 | uint32_t extoffset, elen; | 1982 | uint32_t elen; |
1988 | sector_t offset; | 1983 | sector_t offset; |
1989 | struct buffer_head *bh = NULL; | 1984 | struct extent_position epos = { NULL, 0, { 0, 0}}; |
1990 | int ret; | 1985 | int ret; |
1991 | 1986 | ||
1992 | lock_kernel(); | 1987 | lock_kernel(); |
1993 | 1988 | ||
1994 | if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 1989 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
1995 | ret = udf_get_lb_pblock(inode->i_sb, eloc, offset); | 1990 | ret = udf_get_lb_pblock(inode->i_sb, eloc, offset); |
1996 | else | 1991 | else |
1997 | ret = 0; | 1992 | ret = 0; |
1998 | 1993 | ||
1999 | unlock_kernel(); | 1994 | unlock_kernel(); |
2000 | udf_release_data(bh); | 1995 | udf_release_data(epos.bh); |
2001 | 1996 | ||
2002 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 1997 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |
2003 | return udf_fixed_to_variable(ret); | 1998 | return udf_fixed_to_variable(ret); |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index b9859ac169c4..f85ad13b3dff 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -155,10 +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; | 159 | uint32_t elen; |
160 | sector_t offset; | 160 | sector_t offset; |
161 | struct buffer_head *bh = NULL; | 161 | struct extent_position epos = { NULL, 0, { 0, 0}}; |
162 | 162 | ||
163 | size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 163 | size = (udf_ext0_offset(dir) + dir->i_size) >> 2; |
164 | f_pos = (udf_ext0_offset(dir) >> 2); | 164 | f_pos = (udf_ext0_offset(dir) >> 2); |
@@ -167,41 +167,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
167 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 167 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
168 | fibh->sbh = fibh->ebh = NULL; | 168 | fibh->sbh = fibh->ebh = NULL; |
169 | 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), |
170 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 170 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
171 | { | 171 | { |
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 | udf_release_data(epos.bh); |
186 | return NULL; | 186 | return NULL; |
187 | } | 187 | } |
188 | } | 188 | } |
189 | else | 189 | else |
190 | { | 190 | { |
191 | udf_release_data(bh); | 191 | udf_release_data(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 | udf_release_data(fibh->ebh); |
203 | udf_release_data(fibh->sbh); | 203 | udf_release_data(fibh->sbh); |
204 | udf_release_data(bh); | 204 | udf_release_data(epos.bh); |
205 | return NULL; | 205 | return NULL; |
206 | } | 206 | } |
207 | 207 | ||
@@ -247,7 +247,7 @@ 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 | udf_release_data(epos.bh); |
251 | return fi; | 251 | return fi; |
252 | } | 252 | } |
253 | } | 253 | } |
@@ -255,7 +255,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
255 | if (fibh->sbh != fibh->ebh) | 255 | if (fibh->sbh != fibh->ebh) |
256 | udf_release_data(fibh->ebh); | 256 | udf_release_data(fibh->ebh); |
257 | udf_release_data(fibh->sbh); | 257 | udf_release_data(fibh->sbh); |
258 | udf_release_data(bh); | 258 | udf_release_data(epos.bh); |
259 | return NULL; | 259 | return NULL; |
260 | } | 260 | } |
261 | 261 | ||
@@ -353,10 +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; | 357 | uint32_t elen; |
358 | sector_t offset; | 358 | sector_t offset; |
359 | struct buffer_head *bh = NULL; | 359 | struct extent_position epos = { NULL, 0, { 0, 0 }}; |
360 | 360 | ||
361 | sb = dir->i_sb; | 361 | sb = dir->i_sb; |
362 | 362 | ||
@@ -385,22 +385,22 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
385 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 385 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
386 | fibh->sbh = fibh->ebh = NULL; | 386 | fibh->sbh = fibh->ebh = NULL; |
387 | 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), |
388 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 388 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
389 | { | 389 | { |
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 | udf_release_data(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 | udf_release_data(fibh->ebh); |
427 | udf_release_data(fibh->sbh); | 427 | udf_release_data(fibh->sbh); |
428 | udf_release_data(bh); | 428 | udf_release_data(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 | udf_release_data(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; |
@@ -480,7 +480,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, | |||
480 | if (fibh->sbh != fibh->ebh) | 480 | if (fibh->sbh != fibh->ebh) |
481 | udf_release_data(fibh->ebh); | 481 | udf_release_data(fibh->ebh); |
482 | udf_release_data(fibh->sbh); | 482 | udf_release_data(fibh->sbh); |
483 | udf_release_data(bh); | 483 | udf_release_data(epos.bh); |
484 | *err = -EEXIST; | 484 | *err = -EEXIST; |
485 | return NULL; | 485 | return NULL; |
486 | } | 486 | } |
@@ -492,8 +492,8 @@ 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 | udf_release_data(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); |
@@ -502,15 +502,15 @@ add: | |||
502 | udf_release_data(fibh->sbh); | 502 | udf_release_data(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) |
@@ -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 | udf_release_data(epos.bh); |
554 | udf_release_data(fibh->sbh); | 554 | udf_release_data(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) >> |
@@ -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 | udf_release_data(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,7 +596,7 @@ add: | |||
596 | } | 596 | } |
597 | else | 597 | else |
598 | { | 598 | { |
599 | udf_release_data(bh); | 599 | udf_release_data(epos.bh); |
600 | if (fibh->sbh != fibh->ebh) | 600 | if (fibh->sbh != fibh->ebh) |
601 | udf_release_data(fibh->ebh); | 601 | udf_release_data(fibh->ebh); |
602 | udf_release_data(fibh->sbh); | 602 | udf_release_data(fibh->sbh); |
@@ -781,10 +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; | 785 | uint32_t elen; |
786 | sector_t offset; | 786 | sector_t offset; |
787 | struct buffer_head *bh = NULL; | 787 | struct extent_position epos = { NULL, 0, { 0, 0}}; |
788 | 788 | ||
789 | f_pos = (udf_ext0_offset(dir) >> 2); | 789 | f_pos = (udf_ext0_offset(dir) >> 2); |
790 | 790 | ||
@@ -793,42 +793,42 @@ static int empty_dir(struct inode *dir) | |||
793 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 793 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
794 | fibh.sbh = fibh.ebh = NULL; | 794 | fibh.sbh = fibh.ebh = NULL; |
795 | 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), |
796 | &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) | 796 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) |
797 | { | 797 | { |
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 | udf_release_data(epos.bh); |
812 | return 0; | 812 | return 0; |
813 | } | 813 | } |
814 | } | 814 | } |
815 | else | 815 | else |
816 | { | 816 | { |
817 | udf_release_data(bh); | 817 | udf_release_data(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 | udf_release_data(fibh.ebh); |
830 | udf_release_data(fibh.sbh); | 830 | udf_release_data(fibh.sbh); |
831 | udf_release_data(bh); | 831 | udf_release_data(epos.bh); |
832 | return 0; | 832 | return 0; |
833 | } | 833 | } |
834 | 834 | ||
@@ -837,14 +837,14 @@ static int empty_dir(struct inode *dir) | |||
837 | if (fibh.sbh != fibh.ebh) | 837 | if (fibh.sbh != fibh.ebh) |
838 | udf_release_data(fibh.ebh); | 838 | udf_release_data(fibh.ebh); |
839 | udf_release_data(fibh.sbh); | 839 | udf_release_data(fibh.sbh); |
840 | udf_release_data(bh); | 840 | udf_release_data(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 | udf_release_data(fibh.ebh); |
846 | udf_release_data(fibh.sbh); | 846 | udf_release_data(fibh.sbh); |
847 | udf_release_data(bh); | 847 | udf_release_data(epos.bh); |
848 | return 1; | 848 | return 1; |
849 | } | 849 | } |
850 | 850 | ||
@@ -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 | udf_release_data(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 | udf_release_data(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; |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 023b304fdd99..dafa05f0110b 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1883,21 +1883,20 @@ static unsigned int | |||
1883 | udf_count_free_table(struct super_block *sb, struct inode * table) | 1883 | udf_count_free_table(struct super_block *sb, struct inode * table) |
1884 | { | 1884 | { |
1885 | unsigned int accum = 0; | 1885 | unsigned int accum = 0; |
1886 | uint32_t extoffset, elen; | 1886 | uint32_t elen; |
1887 | kernel_lb_addr bloc, eloc; | 1887 | kernel_lb_addr eloc; |
1888 | int8_t etype; | 1888 | int8_t etype; |
1889 | struct buffer_head *bh = NULL; | 1889 | struct extent_position epos; |
1890 | 1890 | ||
1891 | lock_kernel(); | 1891 | lock_kernel(); |
1892 | 1892 | ||
1893 | bloc = UDF_I_LOCATION(table); | 1893 | epos.block = UDF_I_LOCATION(table); |
1894 | extoffset = sizeof(struct unallocSpaceEntry); | 1894 | epos.offset = sizeof(struct unallocSpaceEntry); |
1895 | epos.bh = NULL; | ||
1895 | 1896 | ||
1896 | while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) | 1897 | while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
1897 | { | ||
1898 | accum += (elen >> table->i_sb->s_blocksize_bits); | 1898 | accum += (elen >> table->i_sb->s_blocksize_bits); |
1899 | } | 1899 | udf_release_data(epos.bh); |
1900 | udf_release_data(bh); | ||
1901 | 1900 | ||
1902 | unlock_kernel(); | 1901 | unlock_kernel(); |
1903 | 1902 | ||
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index ebd0f37f8b16..84191801f4c9 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,53 +81,55 @@ 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 - inode->i_size < inode->i_sb->s_blocksize) |
93 | { | 92 | { |
94 | nelen = elen - (lbcount - inode->i_size); | 93 | nelen = elen - (lbcount - inode->i_size); |
95 | extent_trunc(inode, bloc, extoffset-adsize, eloc, etype, elen, bh, nelen); | 94 | epos.offset -= adsize; |
95 | extent_trunc(inode, &epos, eloc, etype, elen, nelen); | ||
96 | epos.offset += adsize; | ||
96 | lbcount = inode->i_size; | 97 | lbcount = inode->i_size; |
97 | } | 98 | } |
98 | } | 99 | } |
99 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | 100 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
100 | { | 101 | epos.offset -= adsize; |
101 | extoffset -= adsize; | ||
102 | lbcount -= elen; | 102 | lbcount -= elen; |
103 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); | 103 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
104 | if (!bh) | 104 | if (!epos.bh) |
105 | { | 105 | { |
106 | UDF_I_LENALLOC(inode) = extoffset - udf_file_entry_alloc_offset(inode); | 106 | UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode); |
107 | mark_inode_dirty(inode); | 107 | mark_inode_dirty(inode); |
108 | } | 108 | } |
109 | else | 109 | else |
110 | { | 110 | { |
111 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 111 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
112 | aed->lengthAllocDescs = cpu_to_le32(extoffset - sizeof(struct allocExtDesc)); | 112 | 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) | 113 | 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); | 114 | udf_update_tag(epos.bh->b_data, epos.offset); |
115 | else | 115 | else |
116 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 116 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
117 | mark_buffer_dirty_inode(bh, inode); | 117 | mark_buffer_dirty_inode(epos.bh, inode); |
118 | } | 118 | } |
119 | } | 119 | } |
120 | UDF_I_LENEXTENTS(inode) = lbcount; | 120 | UDF_I_LENEXTENTS(inode) = lbcount; |
121 | 121 | ||
122 | udf_release_data(bh); | 122 | udf_release_data(epos.bh); |
123 | } | 123 | } |
124 | 124 | ||
125 | void udf_truncate_extents(struct inode * inode) | 125 | void udf_truncate_extents(struct inode * inode) |
126 | { | 126 | { |
127 | kernel_lb_addr bloc, eloc, neloc = { 0, 0 }; | 127 | struct extent_position epos; |
128 | uint32_t extoffset, elen, nelen = 0, lelen = 0, lenalloc; | 128 | kernel_lb_addr eloc, neloc = { 0, 0 }; |
129 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; | ||
129 | int8_t etype; | 130 | int8_t etype; |
130 | sector_t first_block = inode->i_size >> inode->i_sb->s_blocksize_bits, offset; | 131 | sector_t first_block = inode->i_size >> inode->i_sb->s_blocksize_bits, offset; |
131 | loff_t byte_offset; | 132 | loff_t byte_offset; |
132 | struct buffer_head *bh = NULL; | ||
133 | int adsize; | 133 | int adsize; |
134 | 134 | ||
135 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 135 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
@@ -137,102 +137,98 @@ void udf_truncate_extents(struct inode * inode) | |||
137 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 137 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) |
138 | adsize = sizeof(long_ad); | 138 | adsize = sizeof(long_ad); |
139 | else | 139 | else |
140 | adsize = 0; | 140 | BUG(); |
141 | 141 | ||
142 | etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh); | 142 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
143 | byte_offset = (offset << inode->i_sb->s_blocksize_bits) + (inode->i_size & (inode->i_sb->s_blocksize-1)); | 143 | byte_offset = (offset << inode->i_sb->s_blocksize_bits) + (inode->i_size & (inode->i_sb->s_blocksize-1)); |
144 | if (etype != -1) | 144 | if (etype != -1) |
145 | { | 145 | { |
146 | extoffset -= adsize; | 146 | epos.offset -= adsize; |
147 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, byte_offset); | 147 | extent_trunc(inode, &epos, eloc, etype, elen, byte_offset); |
148 | extoffset += adsize; | 148 | epos.offset += adsize; |
149 | |||
150 | if (byte_offset) | 149 | if (byte_offset) |
151 | lenalloc = extoffset; | 150 | lenalloc = epos.offset; |
152 | else | 151 | else |
153 | lenalloc = extoffset - adsize; | 152 | lenalloc = epos.offset - adsize; |
154 | 153 | ||
155 | if (!bh) | 154 | if (!epos.bh) |
156 | lenalloc -= udf_file_entry_alloc_offset(inode); | 155 | lenalloc -= udf_file_entry_alloc_offset(inode); |
157 | else | 156 | else |
158 | lenalloc -= sizeof(struct allocExtDesc); | 157 | lenalloc -= sizeof(struct allocExtDesc); |
159 | 158 | ||
160 | while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1) | 159 | while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) |
161 | { | 160 | { |
162 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) | 161 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) |
163 | { | 162 | { |
164 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0); | 163 | udf_write_aext(inode, &epos, neloc, nelen, 0); |
165 | extoffset = 0; | 164 | if (indirect_ext_len) |
166 | if (lelen) | ||
167 | { | 165 | { |
168 | if (!bh) | 166 | /* We managed to free all extents in the |
167 | * indirect extent - free it too */ | ||
168 | if (!epos.bh) | ||
169 | BUG(); | 169 | BUG(); |
170 | else | 170 | udf_free_blocks(inode->i_sb, inode, epos.block, 0, indirect_ext_len); |
171 | memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); | ||
172 | udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); | ||
173 | } | 171 | } |
174 | else | 172 | else |
175 | { | 173 | { |
176 | if (!bh) | 174 | if (!epos.bh) |
177 | { | 175 | { |
178 | UDF_I_LENALLOC(inode) = lenalloc; | 176 | UDF_I_LENALLOC(inode) = lenalloc; |
179 | mark_inode_dirty(inode); | 177 | mark_inode_dirty(inode); |
180 | } | 178 | } |
181 | else | 179 | else |
182 | { | 180 | { |
183 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 181 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
184 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 182 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
185 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 183 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
186 | udf_update_tag(bh->b_data, lenalloc + | 184 | udf_update_tag(epos.bh->b_data, lenalloc + |
187 | sizeof(struct allocExtDesc)); | 185 | sizeof(struct allocExtDesc)); |
188 | else | 186 | else |
189 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 187 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
190 | mark_buffer_dirty_inode(bh, inode); | 188 | mark_buffer_dirty_inode(epos.bh, inode); |
191 | } | 189 | } |
192 | } | 190 | } |
193 | 191 | brelse(epos.bh); | |
194 | udf_release_data(bh); | 192 | epos.offset = sizeof(struct allocExtDesc); |
195 | extoffset = sizeof(struct allocExtDesc); | 193 | epos.block = eloc; |
196 | bloc = eloc; | 194 | epos.bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, eloc, 0)); |
197 | bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0)); | ||
198 | if (elen) | 195 | if (elen) |
199 | lelen = (elen + inode->i_sb->s_blocksize - 1) >> | 196 | indirect_ext_len = (elen + |
197 | inode->i_sb->s_blocksize - 1) >> | ||
200 | inode->i_sb->s_blocksize_bits; | 198 | inode->i_sb->s_blocksize_bits; |
201 | else | 199 | else |
202 | lelen = 1; | 200 | indirect_ext_len = 1; |
203 | } | 201 | } |
204 | else | 202 | else |
205 | { | 203 | { |
206 | extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); | 204 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
207 | extoffset += adsize; | 205 | epos.offset += adsize; |
208 | } | 206 | } |
209 | } | 207 | } |
210 | 208 | ||
211 | if (lelen) | 209 | if (indirect_ext_len) |
212 | { | 210 | { |
213 | if (!bh) | 211 | if (!epos.bh) |
214 | BUG(); | 212 | BUG(); |
215 | else | 213 | udf_free_blocks(inode->i_sb, inode, epos.block, 0, indirect_ext_len); |
216 | memset(bh->b_data, 0x00, sizeof(struct allocExtDesc)); | ||
217 | udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen); | ||
218 | } | 214 | } |
219 | else | 215 | else |
220 | { | 216 | { |
221 | if (!bh) | 217 | if (!epos.bh) |
222 | { | 218 | { |
223 | UDF_I_LENALLOC(inode) = lenalloc; | 219 | UDF_I_LENALLOC(inode) = lenalloc; |
224 | mark_inode_dirty(inode); | 220 | mark_inode_dirty(inode); |
225 | } | 221 | } |
226 | else | 222 | else |
227 | { | 223 | { |
228 | struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); | 224 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
229 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 225 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
230 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 226 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
231 | udf_update_tag(bh->b_data, lenalloc + | 227 | udf_update_tag(epos.bh->b_data, lenalloc + |
232 | sizeof(struct allocExtDesc)); | 228 | sizeof(struct allocExtDesc)); |
233 | else | 229 | else |
234 | udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); | 230 | udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); |
235 | mark_buffer_dirty_inode(bh, inode); | 231 | mark_buffer_dirty_inode(epos.bh, inode); |
236 | } | 232 | } |
237 | } | 233 | } |
238 | } | 234 | } |
@@ -245,50 +241,51 @@ void udf_truncate_extents(struct inode * inode) | |||
245 | * no extent above inode->i_size => truncate is | 241 | * no extent above inode->i_size => truncate is |
246 | * extending the file by 'offset'. | 242 | * extending the file by 'offset'. |
247 | */ | 243 | */ |
248 | if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) || | 244 | if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || |
249 | (bh && extoffset == sizeof(struct allocExtDesc))) { | 245 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { |
250 | /* File has no extents at all! */ | 246 | /* File has no extents at all! */ |
251 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | 247 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); |
252 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset; | 248 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset; |
253 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); | 249 | udf_add_aext(inode, &epos, eloc, elen, 1); |
254 | } | 250 | } |
255 | else { | 251 | else { |
256 | extoffset -= adsize; | 252 | epos.offset -= adsize; |
257 | etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); | 253 | etype = udf_next_aext(inode, &epos, &eloc, &elen, 1); |
254 | |||
258 | if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) | 255 | if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) |
259 | { | 256 | { |
260 | extoffset -= adsize; | 257 | epos.offset -= adsize; |
261 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + byte_offset); | 258 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + byte_offset); |
262 | udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); | 259 | udf_write_aext(inode, &epos, eloc, elen, 0); |
263 | } | 260 | } |
264 | else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) | 261 | else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) |
265 | { | 262 | { |
266 | kernel_lb_addr neloc = { 0, 0 }; | 263 | kernel_lb_addr neloc = { 0, 0 }; |
267 | extoffset -= adsize; | 264 | epos.offset -= adsize; |
268 | nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | | 265 | nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | |
269 | ((elen + byte_offset + inode->i_sb->s_blocksize - 1) & | 266 | ((elen + byte_offset + inode->i_sb->s_blocksize - 1) & |
270 | ~(inode->i_sb->s_blocksize - 1)); | 267 | ~(inode->i_sb->s_blocksize - 1)); |
271 | udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); | 268 | udf_write_aext(inode, &epos, neloc, nelen, 1); |
272 | udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); | 269 | udf_add_aext(inode, &epos, eloc, (etype << 30) | elen, 1); |
273 | } | 270 | } |
274 | else | 271 | else |
275 | { | 272 | { |
276 | if (elen & (inode->i_sb->s_blocksize - 1)) | 273 | if (elen & (inode->i_sb->s_blocksize - 1)) |
277 | { | 274 | { |
278 | extoffset -= adsize; | 275 | epos.offset -= adsize; |
279 | elen = EXT_RECORDED_ALLOCATED | | 276 | elen = EXT_RECORDED_ALLOCATED | |
280 | ((elen + inode->i_sb->s_blocksize - 1) & | 277 | ((elen + inode->i_sb->s_blocksize - 1) & |
281 | ~(inode->i_sb->s_blocksize - 1)); | 278 | ~(inode->i_sb->s_blocksize - 1)); |
282 | udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); | 279 | udf_write_aext(inode, &epos, eloc, elen, 1); |
283 | } | 280 | } |
284 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); | 281 | memset(&eloc, 0x00, sizeof(kernel_lb_addr)); |
285 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset; | 282 | elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset; |
286 | udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); | 283 | udf_add_aext(inode, &epos, eloc, elen, 1); |
287 | } | 284 | } |
288 | } | 285 | } |
289 | } | 286 | } |
290 | } | 287 | } |
291 | UDF_I_LENEXTENTS(inode) = inode->i_size; | 288 | UDF_I_LENEXTENTS(inode) = inode->i_size; |
292 | 289 | ||
293 | udf_release_data(bh); | 290 | udf_release_data(epos.bh); |
294 | } | 291 | } |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index d3deb32b53eb..a89f454de1c2 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 *, ...); |
@@ -99,12 +106,12 @@ 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 *, sector_t); | 108 | extern long udf_block_map(struct inode *, sector_t); |
102 | extern int8_t inode_bmap(struct inode *, sector_t, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, sector_t *, struct buffer_head **); | 109 | extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, kernel_lb_addr *, uint32_t *, 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 udf_add_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int); |
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_write_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_delete_aext(struct inode *, struct extent_position, kernel_lb_addr, uint32_t); |
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_next_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); |
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_current_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); |
108 | 115 | ||
109 | /* misc.c */ | 116 | /* misc.c */ |
110 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); | 117 | extern struct buffer_head *udf_tgetblk(struct super_block *, int); |
@@ -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 *, sector_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); |