diff options
Diffstat (limited to 'fs/udf/super.c')
| -rw-r--r-- | fs/udf/super.c | 1262 |
1 files changed, 668 insertions, 594 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index f3ac4abfc946..b564fc140fe4 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
| @@ -55,9 +55,10 @@ | |||
| 55 | #include <linux/errno.h> | 55 | #include <linux/errno.h> |
| 56 | #include <linux/mount.h> | 56 | #include <linux/mount.h> |
| 57 | #include <linux/seq_file.h> | 57 | #include <linux/seq_file.h> |
| 58 | #include <linux/bitmap.h> | ||
| 59 | #include <linux/crc-itu-t.h> | ||
| 58 | #include <asm/byteorder.h> | 60 | #include <asm/byteorder.h> |
| 59 | 61 | ||
| 60 | #include <linux/udf_fs.h> | ||
| 61 | #include "udf_sb.h" | 62 | #include "udf_sb.h" |
| 62 | #include "udf_i.h" | 63 | #include "udf_i.h" |
| 63 | 64 | ||
| @@ -84,22 +85,19 @@ static void udf_write_super(struct super_block *); | |||
| 84 | static int udf_remount_fs(struct super_block *, int *, char *); | 85 | static int udf_remount_fs(struct super_block *, int *, char *); |
| 85 | static int udf_check_valid(struct super_block *, int, int); | 86 | static int udf_check_valid(struct super_block *, int, int); |
| 86 | static int udf_vrs(struct super_block *sb, int silent); | 87 | static int udf_vrs(struct super_block *sb, int silent); |
| 87 | static int udf_load_partition(struct super_block *, kernel_lb_addr *); | ||
| 88 | static int udf_load_logicalvol(struct super_block *, struct buffer_head *, | ||
| 89 | kernel_lb_addr *); | ||
| 90 | static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); | 88 | static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); |
| 91 | static void udf_find_anchor(struct super_block *); | 89 | static void udf_find_anchor(struct super_block *); |
| 92 | static int udf_find_fileset(struct super_block *, kernel_lb_addr *, | 90 | static int udf_find_fileset(struct super_block *, kernel_lb_addr *, |
| 93 | kernel_lb_addr *); | 91 | kernel_lb_addr *); |
| 94 | static void udf_load_pvoldesc(struct super_block *, struct buffer_head *); | ||
| 95 | static void udf_load_fileset(struct super_block *, struct buffer_head *, | 92 | static void udf_load_fileset(struct super_block *, struct buffer_head *, |
| 96 | kernel_lb_addr *); | 93 | kernel_lb_addr *); |
| 97 | static int udf_load_partdesc(struct super_block *, struct buffer_head *); | ||
| 98 | static void udf_open_lvid(struct super_block *); | 94 | static void udf_open_lvid(struct super_block *); |
| 99 | static void udf_close_lvid(struct super_block *); | 95 | static void udf_close_lvid(struct super_block *); |
| 100 | static unsigned int udf_count_free(struct super_block *); | 96 | static unsigned int udf_count_free(struct super_block *); |
| 101 | static int udf_statfs(struct dentry *, struct kstatfs *); | 97 | static int udf_statfs(struct dentry *, struct kstatfs *); |
| 102 | static int udf_show_options(struct seq_file *, struct vfsmount *); | 98 | static int udf_show_options(struct seq_file *, struct vfsmount *); |
| 99 | static void udf_error(struct super_block *sb, const char *function, | ||
| 100 | const char *fmt, ...); | ||
| 103 | 101 | ||
| 104 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) | 102 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) |
| 105 | { | 103 | { |
| @@ -587,48 +585,10 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
| 587 | return 0; | 585 | return 0; |
| 588 | } | 586 | } |
| 589 | 587 | ||
| 590 | /* | ||
| 591 | * udf_set_blocksize | ||
| 592 | * | ||
| 593 | * PURPOSE | ||
| 594 | * Set the block size to be used in all transfers. | ||
| 595 | * | ||
| 596 | * DESCRIPTION | ||
| 597 | * To allow room for a DMA transfer, it is best to guess big when unsure. | ||
| 598 | * This routine picks 2048 bytes as the blocksize when guessing. This | ||
| 599 | * should be adequate until devices with larger block sizes become common. | ||
| 600 | * | ||
| 601 | * Note that the Linux kernel can currently only deal with blocksizes of | ||
| 602 | * 512, 1024, 2048, 4096, and 8192 bytes. | ||
| 603 | * | ||
| 604 | * PRE-CONDITIONS | ||
| 605 | * sb Pointer to _locked_ superblock. | ||
| 606 | * | ||
| 607 | * POST-CONDITIONS | ||
| 608 | * sb->s_blocksize Blocksize. | ||
| 609 | * sb->s_blocksize_bits log2 of blocksize. | ||
| 610 | * <return> 0 Blocksize is valid. | ||
| 611 | * <return> 1 Blocksize is invalid. | ||
| 612 | * | ||
| 613 | * HISTORY | ||
| 614 | * July 1, 1997 - Andrew E. Mileski | ||
| 615 | * Written, tested, and released. | ||
| 616 | */ | ||
| 617 | static int udf_set_blocksize(struct super_block *sb, int bsize) | ||
| 618 | { | ||
| 619 | if (!sb_min_blocksize(sb, bsize)) { | ||
| 620 | udf_debug("Bad block size (%d)\n", bsize); | ||
| 621 | printk(KERN_ERR "udf: bad block size (%d)\n", bsize); | ||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | |||
| 625 | return sb->s_blocksize; | ||
| 626 | } | ||
| 627 | |||
| 628 | static int udf_vrs(struct super_block *sb, int silent) | 588 | static int udf_vrs(struct super_block *sb, int silent) |
| 629 | { | 589 | { |
| 630 | struct volStructDesc *vsd = NULL; | 590 | struct volStructDesc *vsd = NULL; |
| 631 | int sector = 32768; | 591 | loff_t sector = 32768; |
| 632 | int sectorsize; | 592 | int sectorsize; |
| 633 | struct buffer_head *bh = NULL; | 593 | struct buffer_head *bh = NULL; |
| 634 | int iso9660 = 0; | 594 | int iso9660 = 0; |
| @@ -649,7 +609,8 @@ static int udf_vrs(struct super_block *sb, int silent) | |||
| 649 | sector += (sbi->s_session << sb->s_blocksize_bits); | 609 | sector += (sbi->s_session << sb->s_blocksize_bits); |
| 650 | 610 | ||
| 651 | udf_debug("Starting at sector %u (%ld byte sectors)\n", | 611 | udf_debug("Starting at sector %u (%ld byte sectors)\n", |
| 652 | (sector >> sb->s_blocksize_bits), sb->s_blocksize); | 612 | (unsigned int)(sector >> sb->s_blocksize_bits), |
| 613 | sb->s_blocksize); | ||
| 653 | /* Process the sequence (if applicable) */ | 614 | /* Process the sequence (if applicable) */ |
| 654 | for (; !nsr02 && !nsr03; sector += sectorsize) { | 615 | for (; !nsr02 && !nsr03; sector += sectorsize) { |
| 655 | /* Read a block */ | 616 | /* Read a block */ |
| @@ -719,162 +680,140 @@ static int udf_vrs(struct super_block *sb, int silent) | |||
| 719 | } | 680 | } |
| 720 | 681 | ||
| 721 | /* | 682 | /* |
| 722 | * udf_find_anchor | 683 | * Check whether there is an anchor block in the given block |
| 723 | * | ||
| 724 | * PURPOSE | ||
| 725 | * Find an anchor volume descriptor. | ||
| 726 | * | ||
| 727 | * PRE-CONDITIONS | ||
| 728 | * sb Pointer to _locked_ superblock. | ||
| 729 | * lastblock Last block on media. | ||
| 730 | * | ||
| 731 | * POST-CONDITIONS | ||
| 732 | * <return> 1 if not found, 0 if ok | ||
| 733 | * | ||
| 734 | * HISTORY | ||
| 735 | * July 1, 1997 - Andrew E. Mileski | ||
| 736 | * Written, tested, and released. | ||
| 737 | */ | 684 | */ |
| 738 | static void udf_find_anchor(struct super_block *sb) | 685 | static int udf_check_anchor_block(struct super_block *sb, sector_t block, |
| 686 | bool varconv) | ||
| 739 | { | 687 | { |
| 740 | int lastblock; | ||
| 741 | struct buffer_head *bh = NULL; | 688 | struct buffer_head *bh = NULL; |
| 689 | tag *t; | ||
| 742 | uint16_t ident; | 690 | uint16_t ident; |
| 743 | uint32_t location; | 691 | uint32_t location; |
| 744 | int i; | ||
| 745 | struct udf_sb_info *sbi; | ||
| 746 | 692 | ||
| 747 | sbi = UDF_SB(sb); | 693 | if (varconv) { |
| 748 | lastblock = sbi->s_last_block; | 694 | if (udf_fixed_to_variable(block) >= |
| 695 | sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) | ||
| 696 | return 0; | ||
| 697 | bh = sb_bread(sb, udf_fixed_to_variable(block)); | ||
| 698 | } | ||
| 699 | else | ||
| 700 | bh = sb_bread(sb, block); | ||
| 749 | 701 | ||
| 750 | if (lastblock) { | 702 | if (!bh) |
| 751 | int varlastblock = udf_variable_to_fixed(lastblock); | 703 | return 0; |
| 752 | int last[] = { lastblock, lastblock - 2, | ||
| 753 | lastblock - 150, lastblock - 152, | ||
| 754 | varlastblock, varlastblock - 2, | ||
| 755 | varlastblock - 150, varlastblock - 152 }; | ||
| 756 | |||
| 757 | lastblock = 0; | ||
| 758 | |||
| 759 | /* Search for an anchor volume descriptor pointer */ | ||
| 760 | |||
| 761 | /* according to spec, anchor is in either: | ||
| 762 | * block 256 | ||
| 763 | * lastblock-256 | ||
| 764 | * lastblock | ||
| 765 | * however, if the disc isn't closed, it could be 512 */ | ||
| 766 | |||
| 767 | for (i = 0; !lastblock && i < ARRAY_SIZE(last); i++) { | ||
| 768 | ident = location = 0; | ||
| 769 | if (last[i] >= 0) { | ||
| 770 | bh = sb_bread(sb, last[i]); | ||
| 771 | if (bh) { | ||
| 772 | tag *t = (tag *)bh->b_data; | ||
| 773 | ident = le16_to_cpu(t->tagIdent); | ||
| 774 | location = le32_to_cpu(t->tagLocation); | ||
| 775 | brelse(bh); | ||
| 776 | } | ||
| 777 | } | ||
| 778 | 704 | ||
| 779 | if (ident == TAG_IDENT_AVDP) { | 705 | t = (tag *)bh->b_data; |
| 780 | if (location == last[i] - sbi->s_session) { | 706 | ident = le16_to_cpu(t->tagIdent); |
| 781 | lastblock = last[i] - sbi->s_session; | 707 | location = le32_to_cpu(t->tagLocation); |
| 782 | sbi->s_anchor[0] = lastblock; | 708 | brelse(bh); |
| 783 | sbi->s_anchor[1] = lastblock - 256; | 709 | if (ident != TAG_IDENT_AVDP) |
| 784 | } else if (location == | 710 | return 0; |
| 785 | udf_variable_to_fixed(last[i]) - | 711 | return location == block; |
| 786 | sbi->s_session) { | 712 | } |
| 787 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
| 788 | lastblock = | ||
| 789 | udf_variable_to_fixed(last[i]) - | ||
| 790 | sbi->s_session; | ||
| 791 | sbi->s_anchor[0] = lastblock; | ||
| 792 | sbi->s_anchor[1] = lastblock - 256 - | ||
| 793 | sbi->s_session; | ||
| 794 | } else { | ||
| 795 | udf_debug("Anchor found at block %d, " | ||
| 796 | "location mismatch %d.\n", | ||
| 797 | last[i], location); | ||
| 798 | } | ||
| 799 | } else if (ident == TAG_IDENT_FE || | ||
| 800 | ident == TAG_IDENT_EFE) { | ||
| 801 | lastblock = last[i]; | ||
| 802 | sbi->s_anchor[3] = 512; | ||
| 803 | } else { | ||
| 804 | ident = location = 0; | ||
| 805 | if (last[i] >= 256) { | ||
| 806 | bh = sb_bread(sb, last[i] - 256); | ||
| 807 | if (bh) { | ||
| 808 | tag *t = (tag *)bh->b_data; | ||
| 809 | ident = le16_to_cpu( | ||
| 810 | t->tagIdent); | ||
| 811 | location = le32_to_cpu( | ||
| 812 | t->tagLocation); | ||
| 813 | brelse(bh); | ||
| 814 | } | ||
| 815 | } | ||
| 816 | 713 | ||
| 817 | if (ident == TAG_IDENT_AVDP && | 714 | /* Search for an anchor volume descriptor pointer */ |
| 818 | location == last[i] - 256 - | 715 | static sector_t udf_scan_anchors(struct super_block *sb, bool varconv, |
| 819 | sbi->s_session) { | 716 | sector_t lastblock) |
| 820 | lastblock = last[i]; | 717 | { |
| 821 | sbi->s_anchor[1] = last[i] - 256; | 718 | sector_t last[6]; |
| 822 | } else { | 719 | int i; |
| 823 | ident = location = 0; | 720 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 824 | if (last[i] >= 312 + sbi->s_session) { | ||
| 825 | bh = sb_bread(sb, | ||
| 826 | last[i] - 312 - | ||
| 827 | sbi->s_session); | ||
| 828 | if (bh) { | ||
| 829 | tag *t = (tag *) | ||
| 830 | bh->b_data; | ||
| 831 | ident = le16_to_cpu( | ||
| 832 | t->tagIdent); | ||
| 833 | location = le32_to_cpu( | ||
| 834 | t->tagLocation); | ||
| 835 | brelse(bh); | ||
| 836 | } | ||
| 837 | } | ||
| 838 | 721 | ||
| 839 | if (ident == TAG_IDENT_AVDP && | 722 | last[0] = lastblock; |
| 840 | location == udf_variable_to_fixed(last[i]) - 256) { | 723 | last[1] = last[0] - 1; |
| 841 | UDF_SET_FLAG(sb, | 724 | last[2] = last[0] + 1; |
| 842 | UDF_FLAG_VARCONV); | 725 | last[3] = last[0] - 2; |
| 843 | lastblock = udf_variable_to_fixed(last[i]); | 726 | last[4] = last[0] - 150; |
| 844 | sbi->s_anchor[1] = lastblock - 256; | 727 | last[5] = last[0] - 152; |
| 845 | } | 728 | |
| 846 | } | 729 | /* according to spec, anchor is in either: |
| 847 | } | 730 | * block 256 |
| 731 | * lastblock-256 | ||
| 732 | * lastblock | ||
| 733 | * however, if the disc isn't closed, it could be 512 */ | ||
| 734 | |||
| 735 | for (i = 0; i < ARRAY_SIZE(last); i++) { | ||
| 736 | if (last[i] < 0) | ||
| 737 | continue; | ||
| 738 | if (last[i] >= sb->s_bdev->bd_inode->i_size >> | ||
| 739 | sb->s_blocksize_bits) | ||
| 740 | continue; | ||
| 741 | |||
| 742 | if (udf_check_anchor_block(sb, last[i], varconv)) { | ||
| 743 | sbi->s_anchor[0] = last[i]; | ||
| 744 | sbi->s_anchor[1] = last[i] - 256; | ||
| 745 | return last[i]; | ||
| 848 | } | 746 | } |
| 849 | } | ||
| 850 | 747 | ||
| 851 | if (!lastblock) { | 748 | if (last[i] < 256) |
| 852 | /* We haven't found the lastblock. check 312 */ | 749 | continue; |
| 853 | bh = sb_bread(sb, 312 + sbi->s_session); | ||
| 854 | if (bh) { | ||
| 855 | tag *t = (tag *)bh->b_data; | ||
| 856 | ident = le16_to_cpu(t->tagIdent); | ||
| 857 | location = le32_to_cpu(t->tagLocation); | ||
| 858 | brelse(bh); | ||
| 859 | 750 | ||
| 860 | if (ident == TAG_IDENT_AVDP && location == 256) | 751 | if (udf_check_anchor_block(sb, last[i] - 256, varconv)) { |
| 861 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | 752 | sbi->s_anchor[1] = last[i] - 256; |
| 753 | return last[i]; | ||
| 862 | } | 754 | } |
| 863 | } | 755 | } |
| 864 | 756 | ||
| 757 | if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) { | ||
| 758 | sbi->s_anchor[0] = sbi->s_session + 256; | ||
| 759 | return last[0]; | ||
| 760 | } | ||
| 761 | if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) { | ||
| 762 | sbi->s_anchor[0] = sbi->s_session + 512; | ||
| 763 | return last[0]; | ||
| 764 | } | ||
| 765 | return 0; | ||
| 766 | } | ||
| 767 | |||
| 768 | /* | ||
| 769 | * Find an anchor volume descriptor. The function expects sbi->s_lastblock to | ||
| 770 | * be the last block on the media. | ||
| 771 | * | ||
| 772 | * Return 1 if not found, 0 if ok | ||
| 773 | * | ||
| 774 | */ | ||
| 775 | static void udf_find_anchor(struct super_block *sb) | ||
| 776 | { | ||
| 777 | sector_t lastblock; | ||
| 778 | struct buffer_head *bh = NULL; | ||
| 779 | uint16_t ident; | ||
| 780 | int i; | ||
| 781 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
| 782 | |||
| 783 | lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block); | ||
| 784 | if (lastblock) | ||
| 785 | goto check_anchor; | ||
| 786 | |||
| 787 | /* No anchor found? Try VARCONV conversion of block numbers */ | ||
| 788 | /* Firstly, we try to not convert number of the last block */ | ||
| 789 | lastblock = udf_scan_anchors(sb, 1, | ||
| 790 | udf_variable_to_fixed(sbi->s_last_block)); | ||
| 791 | if (lastblock) { | ||
| 792 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
| 793 | goto check_anchor; | ||
| 794 | } | ||
| 795 | |||
| 796 | /* Secondly, we try with converted number of the last block */ | ||
| 797 | lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block); | ||
| 798 | if (lastblock) | ||
| 799 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
| 800 | |||
| 801 | check_anchor: | ||
| 802 | /* | ||
| 803 | * Check located anchors and the anchor block supplied via | ||
| 804 | * mount options | ||
| 805 | */ | ||
| 865 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { | 806 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { |
| 866 | if (sbi->s_anchor[i]) { | 807 | if (!sbi->s_anchor[i]) |
| 867 | bh = udf_read_tagged(sb, sbi->s_anchor[i], | 808 | continue; |
| 868 | sbi->s_anchor[i], &ident); | 809 | bh = udf_read_tagged(sb, sbi->s_anchor[i], |
| 869 | if (!bh) | 810 | sbi->s_anchor[i], &ident); |
| 811 | if (!bh) | ||
| 812 | sbi->s_anchor[i] = 0; | ||
| 813 | else { | ||
| 814 | brelse(bh); | ||
| 815 | if (ident != TAG_IDENT_AVDP) | ||
| 870 | sbi->s_anchor[i] = 0; | 816 | sbi->s_anchor[i] = 0; |
| 871 | else { | ||
| 872 | brelse(bh); | ||
| 873 | if ((ident != TAG_IDENT_AVDP) && | ||
| 874 | (i || (ident != TAG_IDENT_FE && | ||
| 875 | ident != TAG_IDENT_EFE))) | ||
| 876 | sbi->s_anchor[i] = 0; | ||
| 877 | } | ||
| 878 | } | 817 | } |
| 879 | } | 818 | } |
| 880 | 819 | ||
| @@ -971,27 +910,30 @@ static int udf_find_fileset(struct super_block *sb, | |||
| 971 | return 1; | 910 | return 1; |
| 972 | } | 911 | } |
| 973 | 912 | ||
| 974 | static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh) | 913 | static int udf_load_pvoldesc(struct super_block *sb, sector_t block) |
| 975 | { | 914 | { |
| 976 | struct primaryVolDesc *pvoldesc; | 915 | struct primaryVolDesc *pvoldesc; |
| 977 | time_t recording; | ||
| 978 | long recording_usec; | ||
| 979 | struct ustr instr; | 916 | struct ustr instr; |
| 980 | struct ustr outstr; | 917 | struct ustr outstr; |
| 918 | struct buffer_head *bh; | ||
| 919 | uint16_t ident; | ||
| 920 | |||
| 921 | bh = udf_read_tagged(sb, block, block, &ident); | ||
| 922 | if (!bh) | ||
| 923 | return 1; | ||
| 924 | BUG_ON(ident != TAG_IDENT_PVD); | ||
| 981 | 925 | ||
| 982 | pvoldesc = (struct primaryVolDesc *)bh->b_data; | 926 | pvoldesc = (struct primaryVolDesc *)bh->b_data; |
| 983 | 927 | ||
| 984 | if (udf_stamp_to_time(&recording, &recording_usec, | 928 | if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, |
| 985 | lets_to_cpu(pvoldesc->recordingDateAndTime))) { | 929 | pvoldesc->recordingDateAndTime)) { |
| 986 | kernel_timestamp ts; | 930 | #ifdef UDFFS_DEBUG |
| 987 | ts = lets_to_cpu(pvoldesc->recordingDateAndTime); | 931 | timestamp *ts = &pvoldesc->recordingDateAndTime; |
| 988 | udf_debug("recording time %ld/%ld, %04u/%02u/%02u" | 932 | udf_debug("recording time %04u/%02u/%02u" |
| 989 | " %02u:%02u (%x)\n", | 933 | " %02u:%02u (%x)\n", |
| 990 | recording, recording_usec, | 934 | le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, |
| 991 | ts.year, ts.month, ts.day, ts.hour, | 935 | ts->minute, le16_to_cpu(ts->typeAndTimezone)); |
| 992 | ts.minute, ts.typeAndTimezone); | 936 | #endif |
| 993 | UDF_SB(sb)->s_record_time.tv_sec = recording; | ||
| 994 | UDF_SB(sb)->s_record_time.tv_nsec = recording_usec * 1000; | ||
| 995 | } | 937 | } |
| 996 | 938 | ||
| 997 | if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) | 939 | if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) |
| @@ -1005,6 +947,104 @@ static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh) | |||
| 1005 | if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) | 947 | if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) |
| 1006 | if (udf_CS0toUTF8(&outstr, &instr)) | 948 | if (udf_CS0toUTF8(&outstr, &instr)) |
| 1007 | udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); | 949 | udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); |
| 950 | |||
| 951 | brelse(bh); | ||
| 952 | return 0; | ||
| 953 | } | ||
| 954 | |||
| 955 | static int udf_load_metadata_files(struct super_block *sb, int partition) | ||
| 956 | { | ||
| 957 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
| 958 | struct udf_part_map *map; | ||
| 959 | struct udf_meta_data *mdata; | ||
| 960 | kernel_lb_addr addr; | ||
| 961 | int fe_error = 0; | ||
| 962 | |||
| 963 | map = &sbi->s_partmaps[partition]; | ||
| 964 | mdata = &map->s_type_specific.s_metadata; | ||
| 965 | |||
| 966 | /* metadata address */ | ||
| 967 | addr.logicalBlockNum = mdata->s_meta_file_loc; | ||
| 968 | addr.partitionReferenceNum = map->s_partition_num; | ||
| 969 | |||
| 970 | udf_debug("Metadata file location: block = %d part = %d\n", | ||
| 971 | addr.logicalBlockNum, addr.partitionReferenceNum); | ||
| 972 | |||
| 973 | mdata->s_metadata_fe = udf_iget(sb, addr); | ||
| 974 | |||
| 975 | if (mdata->s_metadata_fe == NULL) { | ||
| 976 | udf_warning(sb, __func__, "metadata inode efe not found, " | ||
| 977 | "will try mirror inode."); | ||
| 978 | fe_error = 1; | ||
| 979 | } else if (UDF_I(mdata->s_metadata_fe)->i_alloc_type != | ||
| 980 | ICBTAG_FLAG_AD_SHORT) { | ||
| 981 | udf_warning(sb, __func__, "metadata inode efe does not have " | ||
| 982 | "short allocation descriptors!"); | ||
| 983 | fe_error = 1; | ||
| 984 | iput(mdata->s_metadata_fe); | ||
| 985 | mdata->s_metadata_fe = NULL; | ||
| 986 | } | ||
| 987 | |||
| 988 | /* mirror file entry */ | ||
| 989 | addr.logicalBlockNum = mdata->s_mirror_file_loc; | ||
| 990 | addr.partitionReferenceNum = map->s_partition_num; | ||
| 991 | |||
| 992 | udf_debug("Mirror metadata file location: block = %d part = %d\n", | ||
| 993 | addr.logicalBlockNum, addr.partitionReferenceNum); | ||
| 994 | |||
| 995 | mdata->s_mirror_fe = udf_iget(sb, addr); | ||
| 996 | |||
| 997 | if (mdata->s_mirror_fe == NULL) { | ||
| 998 | if (fe_error) { | ||
| 999 | udf_error(sb, __func__, "mirror inode efe not found " | ||
| 1000 | "and metadata inode is missing too, exiting..."); | ||
| 1001 | goto error_exit; | ||
| 1002 | } else | ||
| 1003 | udf_warning(sb, __func__, "mirror inode efe not found," | ||
| 1004 | " but metadata inode is OK"); | ||
| 1005 | } else if (UDF_I(mdata->s_mirror_fe)->i_alloc_type != | ||
| 1006 | ICBTAG_FLAG_AD_SHORT) { | ||
| 1007 | udf_warning(sb, __func__, "mirror inode efe does not have " | ||
| 1008 | "short allocation descriptors!"); | ||
| 1009 | iput(mdata->s_mirror_fe); | ||
| 1010 | mdata->s_mirror_fe = NULL; | ||
| 1011 | if (fe_error) | ||
| 1012 | goto error_exit; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | /* | ||
| 1016 | * bitmap file entry | ||
| 1017 | * Note: | ||
| 1018 | * Load only if bitmap file location differs from 0xFFFFFFFF (DCN-5102) | ||
| 1019 | */ | ||
| 1020 | if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) { | ||
| 1021 | addr.logicalBlockNum = mdata->s_bitmap_file_loc; | ||
| 1022 | addr.partitionReferenceNum = map->s_partition_num; | ||
| 1023 | |||
| 1024 | udf_debug("Bitmap file location: block = %d part = %d\n", | ||
| 1025 | addr.logicalBlockNum, addr.partitionReferenceNum); | ||
| 1026 | |||
| 1027 | mdata->s_bitmap_fe = udf_iget(sb, addr); | ||
| 1028 | |||
| 1029 | if (mdata->s_bitmap_fe == NULL) { | ||
| 1030 | if (sb->s_flags & MS_RDONLY) | ||
| 1031 | udf_warning(sb, __func__, "bitmap inode efe " | ||
| 1032 | "not found but it's ok since the disc" | ||
| 1033 | " is mounted read-only"); | ||
| 1034 | else { | ||
| 1035 | udf_error(sb, __func__, "bitmap inode efe not " | ||
| 1036 | "found and attempted read-write mount"); | ||
| 1037 | goto error_exit; | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | udf_debug("udf_load_metadata_files Ok\n"); | ||
| 1043 | |||
| 1044 | return 0; | ||
| 1045 | |||
| 1046 | error_exit: | ||
| 1047 | return 1; | ||
| 1008 | } | 1048 | } |
| 1009 | 1049 | ||
| 1010 | static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, | 1050 | static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, |
| @@ -1025,10 +1065,9 @@ static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, | |||
| 1025 | int udf_compute_nr_groups(struct super_block *sb, u32 partition) | 1065 | int udf_compute_nr_groups(struct super_block *sb, u32 partition) |
| 1026 | { | 1066 | { |
| 1027 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; | 1067 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
| 1028 | return (map->s_partition_len + | 1068 | return DIV_ROUND_UP(map->s_partition_len + |
| 1029 | (sizeof(struct spaceBitmapDesc) << 3) + | 1069 | (sizeof(struct spaceBitmapDesc) << 3), |
| 1030 | (sb->s_blocksize * 8) - 1) / | 1070 | sb->s_blocksize * 8); |
| 1031 | (sb->s_blocksize * 8); | ||
| 1032 | } | 1071 | } |
| 1033 | 1072 | ||
| 1034 | static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | 1073 | static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) |
| @@ -1059,134 +1098,241 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
| 1059 | return bitmap; | 1098 | return bitmap; |
| 1060 | } | 1099 | } |
| 1061 | 1100 | ||
| 1062 | static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) | 1101 | static int udf_fill_partdesc_info(struct super_block *sb, |
| 1102 | struct partitionDesc *p, int p_index) | ||
| 1103 | { | ||
| 1104 | struct udf_part_map *map; | ||
| 1105 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
| 1106 | struct partitionHeaderDesc *phd; | ||
| 1107 | |||
| 1108 | map = &sbi->s_partmaps[p_index]; | ||
| 1109 | |||
| 1110 | map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */ | ||
| 1111 | map->s_partition_root = le32_to_cpu(p->partitionStartingLocation); | ||
| 1112 | |||
| 1113 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY)) | ||
| 1114 | map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY; | ||
| 1115 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE)) | ||
| 1116 | map->s_partition_flags |= UDF_PART_FLAG_WRITE_ONCE; | ||
| 1117 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE)) | ||
| 1118 | map->s_partition_flags |= UDF_PART_FLAG_REWRITABLE; | ||
| 1119 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE)) | ||
| 1120 | map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE; | ||
| 1121 | |||
| 1122 | udf_debug("Partition (%d type %x) starts at physical %d, " | ||
| 1123 | "block length %d\n", p_index, | ||
| 1124 | map->s_partition_type, map->s_partition_root, | ||
| 1125 | map->s_partition_len); | ||
| 1126 | |||
| 1127 | if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) && | ||
| 1128 | strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) | ||
| 1129 | return 0; | ||
| 1130 | |||
| 1131 | phd = (struct partitionHeaderDesc *)p->partitionContentsUse; | ||
| 1132 | if (phd->unallocSpaceTable.extLength) { | ||
| 1133 | kernel_lb_addr loc = { | ||
| 1134 | .logicalBlockNum = le32_to_cpu( | ||
| 1135 | phd->unallocSpaceTable.extPosition), | ||
| 1136 | .partitionReferenceNum = p_index, | ||
| 1137 | }; | ||
| 1138 | |||
| 1139 | map->s_uspace.s_table = udf_iget(sb, loc); | ||
| 1140 | if (!map->s_uspace.s_table) { | ||
| 1141 | udf_debug("cannot load unallocSpaceTable (part %d)\n", | ||
| 1142 | p_index); | ||
| 1143 | return 1; | ||
| 1144 | } | ||
| 1145 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE; | ||
| 1146 | udf_debug("unallocSpaceTable (part %d) @ %ld\n", | ||
| 1147 | p_index, map->s_uspace.s_table->i_ino); | ||
| 1148 | } | ||
| 1149 | |||
| 1150 | if (phd->unallocSpaceBitmap.extLength) { | ||
| 1151 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); | ||
| 1152 | if (!bitmap) | ||
| 1153 | return 1; | ||
| 1154 | map->s_uspace.s_bitmap = bitmap; | ||
| 1155 | bitmap->s_extLength = le32_to_cpu( | ||
| 1156 | phd->unallocSpaceBitmap.extLength); | ||
| 1157 | bitmap->s_extPosition = le32_to_cpu( | ||
| 1158 | phd->unallocSpaceBitmap.extPosition); | ||
| 1159 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; | ||
| 1160 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", p_index, | ||
| 1161 | bitmap->s_extPosition); | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | if (phd->partitionIntegrityTable.extLength) | ||
| 1165 | udf_debug("partitionIntegrityTable (part %d)\n", p_index); | ||
| 1166 | |||
| 1167 | if (phd->freedSpaceTable.extLength) { | ||
| 1168 | kernel_lb_addr loc = { | ||
| 1169 | .logicalBlockNum = le32_to_cpu( | ||
| 1170 | phd->freedSpaceTable.extPosition), | ||
| 1171 | .partitionReferenceNum = p_index, | ||
| 1172 | }; | ||
| 1173 | |||
| 1174 | map->s_fspace.s_table = udf_iget(sb, loc); | ||
| 1175 | if (!map->s_fspace.s_table) { | ||
| 1176 | udf_debug("cannot load freedSpaceTable (part %d)\n", | ||
| 1177 | p_index); | ||
| 1178 | return 1; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE; | ||
| 1182 | udf_debug("freedSpaceTable (part %d) @ %ld\n", | ||
| 1183 | p_index, map->s_fspace.s_table->i_ino); | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | if (phd->freedSpaceBitmap.extLength) { | ||
| 1187 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); | ||
| 1188 | if (!bitmap) | ||
| 1189 | return 1; | ||
| 1190 | map->s_fspace.s_bitmap = bitmap; | ||
| 1191 | bitmap->s_extLength = le32_to_cpu( | ||
| 1192 | phd->freedSpaceBitmap.extLength); | ||
| 1193 | bitmap->s_extPosition = le32_to_cpu( | ||
| 1194 | phd->freedSpaceBitmap.extPosition); | ||
| 1195 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; | ||
| 1196 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", p_index, | ||
| 1197 | bitmap->s_extPosition); | ||
| 1198 | } | ||
| 1199 | return 0; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) | ||
| 1203 | { | ||
| 1204 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
| 1205 | struct udf_part_map *map = &sbi->s_partmaps[p_index]; | ||
| 1206 | kernel_lb_addr ino; | ||
| 1207 | struct buffer_head *bh = NULL; | ||
| 1208 | struct udf_inode_info *vati; | ||
| 1209 | uint32_t pos; | ||
| 1210 | struct virtualAllocationTable20 *vat20; | ||
| 1211 | |||
| 1212 | /* VAT file entry is in the last recorded block */ | ||
| 1213 | ino.partitionReferenceNum = type1_index; | ||
| 1214 | ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root; | ||
| 1215 | sbi->s_vat_inode = udf_iget(sb, ino); | ||
| 1216 | if (!sbi->s_vat_inode) | ||
| 1217 | return 1; | ||
| 1218 | |||
| 1219 | if (map->s_partition_type == UDF_VIRTUAL_MAP15) { | ||
| 1220 | map->s_type_specific.s_virtual.s_start_offset = 0; | ||
| 1221 | map->s_type_specific.s_virtual.s_num_entries = | ||
| 1222 | (sbi->s_vat_inode->i_size - 36) >> 2; | ||
| 1223 | } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) { | ||
| 1224 | vati = UDF_I(sbi->s_vat_inode); | ||
| 1225 | if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||
| 1226 | pos = udf_block_map(sbi->s_vat_inode, 0); | ||
| 1227 | bh = sb_bread(sb, pos); | ||
| 1228 | if (!bh) | ||
| 1229 | return 1; | ||
| 1230 | vat20 = (struct virtualAllocationTable20 *)bh->b_data; | ||
| 1231 | } else { | ||
| 1232 | vat20 = (struct virtualAllocationTable20 *) | ||
| 1233 | vati->i_ext.i_data; | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | map->s_type_specific.s_virtual.s_start_offset = | ||
| 1237 | le16_to_cpu(vat20->lengthHeader); | ||
| 1238 | map->s_type_specific.s_virtual.s_num_entries = | ||
| 1239 | (sbi->s_vat_inode->i_size - | ||
| 1240 | map->s_type_specific.s_virtual. | ||
| 1241 | s_start_offset) >> 2; | ||
| 1242 | brelse(bh); | ||
| 1243 | } | ||
| 1244 | return 0; | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | static int udf_load_partdesc(struct super_block *sb, sector_t block) | ||
| 1063 | { | 1248 | { |
| 1249 | struct buffer_head *bh; | ||
| 1064 | struct partitionDesc *p; | 1250 | struct partitionDesc *p; |
| 1065 | int i; | ||
| 1066 | struct udf_part_map *map; | 1251 | struct udf_part_map *map; |
| 1067 | struct udf_sb_info *sbi; | 1252 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 1253 | int i, type1_idx; | ||
| 1254 | uint16_t partitionNumber; | ||
| 1255 | uint16_t ident; | ||
| 1256 | int ret = 0; | ||
| 1257 | |||
| 1258 | bh = udf_read_tagged(sb, block, block, &ident); | ||
| 1259 | if (!bh) | ||
| 1260 | return 1; | ||
| 1261 | if (ident != TAG_IDENT_PD) | ||
| 1262 | goto out_bh; | ||
| 1068 | 1263 | ||
| 1069 | p = (struct partitionDesc *)bh->b_data; | 1264 | p = (struct partitionDesc *)bh->b_data; |
| 1070 | sbi = UDF_SB(sb); | 1265 | partitionNumber = le16_to_cpu(p->partitionNumber); |
| 1071 | 1266 | ||
| 1267 | /* First scan for TYPE1, SPARABLE and METADATA partitions */ | ||
| 1072 | for (i = 0; i < sbi->s_partitions; i++) { | 1268 | for (i = 0; i < sbi->s_partitions; i++) { |
| 1073 | map = &sbi->s_partmaps[i]; | 1269 | map = &sbi->s_partmaps[i]; |
| 1074 | udf_debug("Searching map: (%d == %d)\n", | 1270 | udf_debug("Searching map: (%d == %d)\n", |
| 1075 | map->s_partition_num, | 1271 | map->s_partition_num, partitionNumber); |
| 1076 | le16_to_cpu(p->partitionNumber)); | 1272 | if (map->s_partition_num == partitionNumber && |
| 1077 | if (map->s_partition_num == | 1273 | (map->s_partition_type == UDF_TYPE1_MAP15 || |
| 1078 | le16_to_cpu(p->partitionNumber)) { | 1274 | map->s_partition_type == UDF_SPARABLE_MAP15)) |
| 1079 | map->s_partition_len = | ||
| 1080 | le32_to_cpu(p->partitionLength); /* blocks */ | ||
| 1081 | map->s_partition_root = | ||
| 1082 | le32_to_cpu(p->partitionStartingLocation); | ||
| 1083 | if (p->accessType == | ||
| 1084 | cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY)) | ||
| 1085 | map->s_partition_flags |= | ||
| 1086 | UDF_PART_FLAG_READ_ONLY; | ||
| 1087 | if (p->accessType == | ||
| 1088 | cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE)) | ||
| 1089 | map->s_partition_flags |= | ||
| 1090 | UDF_PART_FLAG_WRITE_ONCE; | ||
| 1091 | if (p->accessType == | ||
| 1092 | cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE)) | ||
| 1093 | map->s_partition_flags |= | ||
| 1094 | UDF_PART_FLAG_REWRITABLE; | ||
| 1095 | if (p->accessType == | ||
| 1096 | cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE)) | ||
| 1097 | map->s_partition_flags |= | ||
| 1098 | UDF_PART_FLAG_OVERWRITABLE; | ||
| 1099 | |||
| 1100 | if (!strcmp(p->partitionContents.ident, | ||
| 1101 | PD_PARTITION_CONTENTS_NSR02) || | ||
| 1102 | !strcmp(p->partitionContents.ident, | ||
| 1103 | PD_PARTITION_CONTENTS_NSR03)) { | ||
| 1104 | struct partitionHeaderDesc *phd; | ||
| 1105 | |||
| 1106 | phd = (struct partitionHeaderDesc *) | ||
| 1107 | (p->partitionContentsUse); | ||
| 1108 | if (phd->unallocSpaceTable.extLength) { | ||
| 1109 | kernel_lb_addr loc = { | ||
| 1110 | .logicalBlockNum = le32_to_cpu(phd->unallocSpaceTable.extPosition), | ||
| 1111 | .partitionReferenceNum = i, | ||
| 1112 | }; | ||
| 1113 | |||
| 1114 | map->s_uspace.s_table = | ||
| 1115 | udf_iget(sb, loc); | ||
| 1116 | if (!map->s_uspace.s_table) { | ||
| 1117 | udf_debug("cannot load unallocSpaceTable (part %d)\n", i); | ||
| 1118 | return 1; | ||
| 1119 | } | ||
| 1120 | map->s_partition_flags |= | ||
| 1121 | UDF_PART_FLAG_UNALLOC_TABLE; | ||
| 1122 | udf_debug("unallocSpaceTable (part %d) @ %ld\n", | ||
| 1123 | i, map->s_uspace.s_table->i_ino); | ||
| 1124 | } | ||
| 1125 | if (phd->unallocSpaceBitmap.extLength) { | ||
| 1126 | struct udf_bitmap *bitmap = | ||
| 1127 | udf_sb_alloc_bitmap(sb, i); | ||
| 1128 | map->s_uspace.s_bitmap = bitmap; | ||
| 1129 | if (bitmap != NULL) { | ||
| 1130 | bitmap->s_extLength = | ||
| 1131 | le32_to_cpu(phd->unallocSpaceBitmap.extLength); | ||
| 1132 | bitmap->s_extPosition = | ||
| 1133 | le32_to_cpu(phd->unallocSpaceBitmap.extPosition); | ||
| 1134 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; | ||
| 1135 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", | ||
| 1136 | i, bitmap->s_extPosition); | ||
| 1137 | } | ||
| 1138 | } | ||
| 1139 | if (phd->partitionIntegrityTable.extLength) | ||
| 1140 | udf_debug("partitionIntegrityTable (part %d)\n", i); | ||
| 1141 | if (phd->freedSpaceTable.extLength) { | ||
| 1142 | kernel_lb_addr loc = { | ||
| 1143 | .logicalBlockNum = le32_to_cpu(phd->freedSpaceTable.extPosition), | ||
| 1144 | .partitionReferenceNum = i, | ||
| 1145 | }; | ||
| 1146 | |||
| 1147 | map->s_fspace.s_table = | ||
| 1148 | udf_iget(sb, loc); | ||
| 1149 | if (!map->s_fspace.s_table) { | ||
| 1150 | udf_debug("cannot load freedSpaceTable (part %d)\n", i); | ||
| 1151 | return 1; | ||
| 1152 | } | ||
| 1153 | map->s_partition_flags |= | ||
| 1154 | UDF_PART_FLAG_FREED_TABLE; | ||
| 1155 | udf_debug("freedSpaceTable (part %d) @ %ld\n", | ||
| 1156 | i, map->s_fspace.s_table->i_ino); | ||
| 1157 | } | ||
| 1158 | if (phd->freedSpaceBitmap.extLength) { | ||
| 1159 | struct udf_bitmap *bitmap = | ||
| 1160 | udf_sb_alloc_bitmap(sb, i); | ||
| 1161 | map->s_fspace.s_bitmap = bitmap; | ||
| 1162 | if (bitmap != NULL) { | ||
| 1163 | bitmap->s_extLength = | ||
| 1164 | le32_to_cpu(phd->freedSpaceBitmap.extLength); | ||
| 1165 | bitmap->s_extPosition = | ||
| 1166 | le32_to_cpu(phd->freedSpaceBitmap.extPosition); | ||
| 1167 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; | ||
| 1168 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", | ||
| 1169 | i, bitmap->s_extPosition); | ||
| 1170 | } | ||
| 1171 | } | ||
| 1172 | } | ||
| 1173 | break; | 1275 | break; |
| 1174 | } | ||
| 1175 | } | 1276 | } |
| 1176 | if (i == sbi->s_partitions) | 1277 | |
| 1278 | if (i >= sbi->s_partitions) { | ||
| 1177 | udf_debug("Partition (%d) not found in partition map\n", | 1279 | udf_debug("Partition (%d) not found in partition map\n", |
| 1178 | le16_to_cpu(p->partitionNumber)); | 1280 | partitionNumber); |
| 1179 | else | 1281 | goto out_bh; |
| 1180 | udf_debug("Partition (%d:%d type %x) starts at physical %d, " | 1282 | } |
| 1181 | "block length %d\n", | 1283 | |
| 1182 | le16_to_cpu(p->partitionNumber), i, | 1284 | ret = udf_fill_partdesc_info(sb, p, i); |
| 1183 | map->s_partition_type, | 1285 | |
| 1184 | map->s_partition_root, | 1286 | /* |
| 1185 | map->s_partition_len); | 1287 | * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and |
| 1186 | return 0; | 1288 | * PHYSICAL partitions are already set up |
| 1289 | */ | ||
| 1290 | type1_idx = i; | ||
| 1291 | for (i = 0; i < sbi->s_partitions; i++) { | ||
| 1292 | map = &sbi->s_partmaps[i]; | ||
| 1293 | |||
| 1294 | if (map->s_partition_num == partitionNumber && | ||
| 1295 | (map->s_partition_type == UDF_VIRTUAL_MAP15 || | ||
| 1296 | map->s_partition_type == UDF_VIRTUAL_MAP20 || | ||
| 1297 | map->s_partition_type == UDF_METADATA_MAP25)) | ||
| 1298 | break; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | if (i >= sbi->s_partitions) | ||
| 1302 | goto out_bh; | ||
| 1303 | |||
| 1304 | ret = udf_fill_partdesc_info(sb, p, i); | ||
| 1305 | if (ret) | ||
| 1306 | goto out_bh; | ||
| 1307 | |||
| 1308 | if (map->s_partition_type == UDF_METADATA_MAP25) { | ||
| 1309 | ret = udf_load_metadata_files(sb, i); | ||
| 1310 | if (ret) { | ||
| 1311 | printk(KERN_ERR "UDF-fs: error loading MetaData " | ||
| 1312 | "partition map %d\n", i); | ||
| 1313 | goto out_bh; | ||
| 1314 | } | ||
| 1315 | } else { | ||
| 1316 | ret = udf_load_vat(sb, i, type1_idx); | ||
| 1317 | if (ret) | ||
| 1318 | goto out_bh; | ||
| 1319 | /* | ||
| 1320 | * Mark filesystem read-only if we have a partition with | ||
| 1321 | * virtual map since we don't handle writing to it (we | ||
| 1322 | * overwrite blocks instead of relocating them). | ||
| 1323 | */ | ||
| 1324 | sb->s_flags |= MS_RDONLY; | ||
| 1325 | printk(KERN_NOTICE "UDF-fs: Filesystem marked read-only " | ||
| 1326 | "because writing to pseudooverwrite partition is " | ||
| 1327 | "not implemented.\n"); | ||
| 1328 | } | ||
| 1329 | out_bh: | ||
| 1330 | /* In case loading failed, we handle cleanup in udf_fill_super */ | ||
| 1331 | brelse(bh); | ||
| 1332 | return ret; | ||
| 1187 | } | 1333 | } |
| 1188 | 1334 | ||
| 1189 | static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | 1335 | static int udf_load_logicalvol(struct super_block *sb, sector_t block, |
| 1190 | kernel_lb_addr *fileset) | 1336 | kernel_lb_addr *fileset) |
| 1191 | { | 1337 | { |
| 1192 | struct logicalVolDesc *lvd; | 1338 | struct logicalVolDesc *lvd; |
| @@ -1194,12 +1340,21 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
| 1194 | uint8_t type; | 1340 | uint8_t type; |
| 1195 | struct udf_sb_info *sbi = UDF_SB(sb); | 1341 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 1196 | struct genericPartitionMap *gpm; | 1342 | struct genericPartitionMap *gpm; |
| 1343 | uint16_t ident; | ||
| 1344 | struct buffer_head *bh; | ||
| 1345 | int ret = 0; | ||
| 1197 | 1346 | ||
| 1347 | bh = udf_read_tagged(sb, block, block, &ident); | ||
| 1348 | if (!bh) | ||
| 1349 | return 1; | ||
| 1350 | BUG_ON(ident != TAG_IDENT_LVD); | ||
| 1198 | lvd = (struct logicalVolDesc *)bh->b_data; | 1351 | lvd = (struct logicalVolDesc *)bh->b_data; |
| 1199 | 1352 | ||
| 1200 | i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); | 1353 | i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); |
| 1201 | if (i != 0) | 1354 | if (i != 0) { |
| 1202 | return i; | 1355 | ret = i; |
| 1356 | goto out_bh; | ||
| 1357 | } | ||
| 1203 | 1358 | ||
| 1204 | for (i = 0, offset = 0; | 1359 | for (i = 0, offset = 0; |
| 1205 | i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); | 1360 | i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); |
| @@ -1223,12 +1378,12 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
| 1223 | u16 suf = | 1378 | u16 suf = |
| 1224 | le16_to_cpu(((__le16 *)upm2->partIdent. | 1379 | le16_to_cpu(((__le16 *)upm2->partIdent. |
| 1225 | identSuffix)[0]); | 1380 | identSuffix)[0]); |
| 1226 | if (suf == 0x0150) { | 1381 | if (suf < 0x0200) { |
| 1227 | map->s_partition_type = | 1382 | map->s_partition_type = |
| 1228 | UDF_VIRTUAL_MAP15; | 1383 | UDF_VIRTUAL_MAP15; |
| 1229 | map->s_partition_func = | 1384 | map->s_partition_func = |
| 1230 | udf_get_pblock_virt15; | 1385 | udf_get_pblock_virt15; |
| 1231 | } else if (suf == 0x0200) { | 1386 | } else { |
| 1232 | map->s_partition_type = | 1387 | map->s_partition_type = |
| 1233 | UDF_VIRTUAL_MAP20; | 1388 | UDF_VIRTUAL_MAP20; |
| 1234 | map->s_partition_func = | 1389 | map->s_partition_func = |
| @@ -1238,7 +1393,6 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
| 1238 | UDF_ID_SPARABLE, | 1393 | UDF_ID_SPARABLE, |
| 1239 | strlen(UDF_ID_SPARABLE))) { | 1394 | strlen(UDF_ID_SPARABLE))) { |
| 1240 | uint32_t loc; | 1395 | uint32_t loc; |
| 1241 | uint16_t ident; | ||
| 1242 | struct sparingTable *st; | 1396 | struct sparingTable *st; |
| 1243 | struct sparablePartitionMap *spm = | 1397 | struct sparablePartitionMap *spm = |
| 1244 | (struct sparablePartitionMap *)gpm; | 1398 | (struct sparablePartitionMap *)gpm; |
| @@ -1256,22 +1410,64 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
| 1256 | map->s_type_specific.s_sparing. | 1410 | map->s_type_specific.s_sparing. |
| 1257 | s_spar_map[j] = bh2; | 1411 | s_spar_map[j] = bh2; |
| 1258 | 1412 | ||
| 1259 | if (bh2 != NULL) { | 1413 | if (bh2 == NULL) |
| 1260 | st = (struct sparingTable *) | 1414 | continue; |
| 1261 | bh2->b_data; | 1415 | |
| 1262 | if (ident != 0 || strncmp( | 1416 | st = (struct sparingTable *)bh2->b_data; |
| 1263 | st->sparingIdent.ident, | 1417 | if (ident != 0 || strncmp( |
| 1264 | UDF_ID_SPARING, | 1418 | st->sparingIdent.ident, |
| 1265 | strlen(UDF_ID_SPARING))) { | 1419 | UDF_ID_SPARING, |
| 1266 | brelse(bh2); | 1420 | strlen(UDF_ID_SPARING))) { |
| 1267 | map->s_type_specific. | 1421 | brelse(bh2); |
| 1268 | s_sparing. | 1422 | map->s_type_specific.s_sparing. |
| 1269 | s_spar_map[j] = | 1423 | s_spar_map[j] = NULL; |
| 1270 | NULL; | ||
| 1271 | } | ||
| 1272 | } | 1424 | } |
| 1273 | } | 1425 | } |
| 1274 | map->s_partition_func = udf_get_pblock_spar15; | 1426 | map->s_partition_func = udf_get_pblock_spar15; |
| 1427 | } else if (!strncmp(upm2->partIdent.ident, | ||
| 1428 | UDF_ID_METADATA, | ||
| 1429 | strlen(UDF_ID_METADATA))) { | ||
| 1430 | struct udf_meta_data *mdata = | ||
| 1431 | &map->s_type_specific.s_metadata; | ||
| 1432 | struct metadataPartitionMap *mdm = | ||
| 1433 | (struct metadataPartitionMap *) | ||
| 1434 | &(lvd->partitionMaps[offset]); | ||
| 1435 | udf_debug("Parsing Logical vol part %d " | ||
| 1436 | "type %d id=%s\n", i, type, | ||
| 1437 | UDF_ID_METADATA); | ||
| 1438 | |||
| 1439 | map->s_partition_type = UDF_METADATA_MAP25; | ||
| 1440 | map->s_partition_func = udf_get_pblock_meta25; | ||
| 1441 | |||
| 1442 | mdata->s_meta_file_loc = | ||
| 1443 | le32_to_cpu(mdm->metadataFileLoc); | ||
| 1444 | mdata->s_mirror_file_loc = | ||
| 1445 | le32_to_cpu(mdm->metadataMirrorFileLoc); | ||
| 1446 | mdata->s_bitmap_file_loc = | ||
| 1447 | le32_to_cpu(mdm->metadataBitmapFileLoc); | ||
| 1448 | mdata->s_alloc_unit_size = | ||
| 1449 | le32_to_cpu(mdm->allocUnitSize); | ||
| 1450 | mdata->s_align_unit_size = | ||
| 1451 | le16_to_cpu(mdm->alignUnitSize); | ||
| 1452 | mdata->s_dup_md_flag = | ||
| 1453 | mdm->flags & 0x01; | ||
| 1454 | |||
| 1455 | udf_debug("Metadata Ident suffix=0x%x\n", | ||
| 1456 | (le16_to_cpu( | ||
| 1457 | ((__le16 *) | ||
| 1458 | mdm->partIdent.identSuffix)[0]))); | ||
| 1459 | udf_debug("Metadata part num=%d\n", | ||
| 1460 | le16_to_cpu(mdm->partitionNum)); | ||
| 1461 | udf_debug("Metadata part alloc unit size=%d\n", | ||
| 1462 | le32_to_cpu(mdm->allocUnitSize)); | ||
| 1463 | udf_debug("Metadata file loc=%d\n", | ||
| 1464 | le32_to_cpu(mdm->metadataFileLoc)); | ||
| 1465 | udf_debug("Mirror file loc=%d\n", | ||
| 1466 | le32_to_cpu(mdm->metadataMirrorFileLoc)); | ||
| 1467 | udf_debug("Bitmap file loc=%d\n", | ||
| 1468 | le32_to_cpu(mdm->metadataBitmapFileLoc)); | ||
| 1469 | udf_debug("Duplicate Flag: %d %d\n", | ||
| 1470 | mdata->s_dup_md_flag, mdm->flags); | ||
| 1275 | } else { | 1471 | } else { |
| 1276 | udf_debug("Unknown ident: %s\n", | 1472 | udf_debug("Unknown ident: %s\n", |
| 1277 | upm2->partIdent.ident); | 1473 | upm2->partIdent.ident); |
| @@ -1296,7 +1492,9 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
| 1296 | if (lvd->integritySeqExt.extLength) | 1492 | if (lvd->integritySeqExt.extLength) |
| 1297 | udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); | 1493 | udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); |
| 1298 | 1494 | ||
| 1299 | return 0; | 1495 | out_bh: |
| 1496 | brelse(bh); | ||
| 1497 | return ret; | ||
| 1300 | } | 1498 | } |
| 1301 | 1499 | ||
| 1302 | /* | 1500 | /* |
| @@ -1345,7 +1543,7 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) | |||
| 1345 | * July 1, 1997 - Andrew E. Mileski | 1543 | * July 1, 1997 - Andrew E. Mileski |
| 1346 | * Written, tested, and released. | 1544 | * Written, tested, and released. |
| 1347 | */ | 1545 | */ |
| 1348 | static int udf_process_sequence(struct super_block *sb, long block, | 1546 | static noinline int udf_process_sequence(struct super_block *sb, long block, |
| 1349 | long lastblock, kernel_lb_addr *fileset) | 1547 | long lastblock, kernel_lb_addr *fileset) |
| 1350 | { | 1548 | { |
| 1351 | struct buffer_head *bh = NULL; | 1549 | struct buffer_head *bh = NULL; |
| @@ -1354,19 +1552,25 @@ static int udf_process_sequence(struct super_block *sb, long block, | |||
| 1354 | struct generic_desc *gd; | 1552 | struct generic_desc *gd; |
| 1355 | struct volDescPtr *vdp; | 1553 | struct volDescPtr *vdp; |
| 1356 | int done = 0; | 1554 | int done = 0; |
| 1357 | int i, j; | ||
| 1358 | uint32_t vdsn; | 1555 | uint32_t vdsn; |
| 1359 | uint16_t ident; | 1556 | uint16_t ident; |
| 1360 | long next_s = 0, next_e = 0; | 1557 | long next_s = 0, next_e = 0; |
| 1361 | 1558 | ||
| 1362 | memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); | 1559 | memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); |
| 1363 | 1560 | ||
| 1364 | /* Read the main descriptor sequence */ | 1561 | /* |
| 1562 | * Read the main descriptor sequence and find which descriptors | ||
| 1563 | * are in it. | ||
| 1564 | */ | ||
| 1365 | for (; (!done && block <= lastblock); block++) { | 1565 | for (; (!done && block <= lastblock); block++) { |
| 1366 | 1566 | ||
| 1367 | bh = udf_read_tagged(sb, block, block, &ident); | 1567 | bh = udf_read_tagged(sb, block, block, &ident); |
| 1368 | if (!bh) | 1568 | if (!bh) { |
| 1369 | break; | 1569 | printk(KERN_ERR "udf: Block %Lu of volume descriptor " |
| 1570 | "sequence is corrupted or we could not read " | ||
| 1571 | "it.\n", (unsigned long long)block); | ||
| 1572 | return 1; | ||
| 1573 | } | ||
| 1370 | 1574 | ||
| 1371 | /* Process each descriptor (ISO 13346 3/8.3-8.4) */ | 1575 | /* Process each descriptor (ISO 13346 3/8.3-8.4) */ |
| 1372 | gd = (struct generic_desc *)bh->b_data; | 1576 | gd = (struct generic_desc *)bh->b_data; |
| @@ -1432,41 +1636,31 @@ static int udf_process_sequence(struct super_block *sb, long block, | |||
| 1432 | } | 1636 | } |
| 1433 | brelse(bh); | 1637 | brelse(bh); |
| 1434 | } | 1638 | } |
| 1435 | for (i = 0; i < VDS_POS_LENGTH; i++) { | 1639 | /* |
| 1436 | if (vds[i].block) { | 1640 | * Now read interesting descriptors again and process them |
| 1437 | bh = udf_read_tagged(sb, vds[i].block, vds[i].block, | 1641 | * in a suitable order |
| 1438 | &ident); | 1642 | */ |
| 1439 | 1643 | if (!vds[VDS_POS_PRIMARY_VOL_DESC].block) { | |
| 1440 | if (i == VDS_POS_PRIMARY_VOL_DESC) { | 1644 | printk(KERN_ERR "udf: Primary Volume Descriptor not found!\n"); |
| 1441 | udf_load_pvoldesc(sb, bh); | 1645 | return 1; |
| 1442 | } else if (i == VDS_POS_LOGICAL_VOL_DESC) { | 1646 | } |
| 1443 | if (udf_load_logicalvol(sb, bh, fileset)) { | 1647 | if (udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block)) |
| 1444 | brelse(bh); | 1648 | return 1; |
| 1445 | return 1; | 1649 | |
| 1446 | } | 1650 | if (vds[VDS_POS_LOGICAL_VOL_DESC].block && udf_load_logicalvol(sb, |
| 1447 | } else if (i == VDS_POS_PARTITION_DESC) { | 1651 | vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset)) |
| 1448 | struct buffer_head *bh2 = NULL; | 1652 | return 1; |
| 1449 | if (udf_load_partdesc(sb, bh)) { | 1653 | |
| 1450 | brelse(bh); | 1654 | if (vds[VDS_POS_PARTITION_DESC].block) { |
| 1451 | return 1; | 1655 | /* |
| 1452 | } | 1656 | * We rescan the whole descriptor sequence to find |
| 1453 | for (j = vds[i].block + 1; | 1657 | * partition descriptor blocks and process them. |
| 1454 | j < vds[VDS_POS_TERMINATING_DESC].block; | 1658 | */ |
| 1455 | j++) { | 1659 | for (block = vds[VDS_POS_PARTITION_DESC].block; |
| 1456 | bh2 = udf_read_tagged(sb, j, j, &ident); | 1660 | block < vds[VDS_POS_TERMINATING_DESC].block; |
| 1457 | gd = (struct generic_desc *)bh2->b_data; | 1661 | block++) |
| 1458 | if (ident == TAG_IDENT_PD) | 1662 | if (udf_load_partdesc(sb, block)) |
| 1459 | if (udf_load_partdesc(sb, | 1663 | return 1; |
| 1460 | bh2)) { | ||
| 1461 | brelse(bh); | ||
| 1462 | brelse(bh2); | ||
| 1463 | return 1; | ||
| 1464 | } | ||
| 1465 | brelse(bh2); | ||
| 1466 | } | ||
| 1467 | } | ||
| 1468 | brelse(bh); | ||
| 1469 | } | ||
| 1470 | } | 1664 | } |
| 1471 | 1665 | ||
| 1472 | return 0; | 1666 | return 0; |
| @@ -1478,6 +1672,7 @@ static int udf_process_sequence(struct super_block *sb, long block, | |||
| 1478 | static int udf_check_valid(struct super_block *sb, int novrs, int silent) | 1672 | static int udf_check_valid(struct super_block *sb, int novrs, int silent) |
| 1479 | { | 1673 | { |
| 1480 | long block; | 1674 | long block; |
| 1675 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
| 1481 | 1676 | ||
| 1482 | if (novrs) { | 1677 | if (novrs) { |
| 1483 | udf_debug("Validity check skipped because of novrs option\n"); | 1678 | udf_debug("Validity check skipped because of novrs option\n"); |
| @@ -1485,27 +1680,22 @@ static int udf_check_valid(struct super_block *sb, int novrs, int silent) | |||
| 1485 | } | 1680 | } |
| 1486 | /* Check that it is NSR02 compliant */ | 1681 | /* Check that it is NSR02 compliant */ |
| 1487 | /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ | 1682 | /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ |
| 1488 | else { | 1683 | block = udf_vrs(sb, silent); |
| 1489 | block = udf_vrs(sb, silent); | 1684 | if (block == -1) |
| 1490 | if (block == -1) { | 1685 | udf_debug("Failed to read byte 32768. Assuming open " |
| 1491 | struct udf_sb_info *sbi = UDF_SB(sb); | 1686 | "disc. Skipping validity check\n"); |
| 1492 | udf_debug("Failed to read byte 32768. Assuming open " | 1687 | if (block && !sbi->s_last_block) |
| 1493 | "disc. Skipping validity check\n"); | 1688 | sbi->s_last_block = udf_get_last_block(sb); |
| 1494 | if (!sbi->s_last_block) | 1689 | return !block; |
| 1495 | sbi->s_last_block = udf_get_last_block(sb); | ||
| 1496 | return 0; | ||
| 1497 | } else | ||
| 1498 | return !block; | ||
| 1499 | } | ||
| 1500 | } | 1690 | } |
| 1501 | 1691 | ||
| 1502 | static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | 1692 | static int udf_load_sequence(struct super_block *sb, kernel_lb_addr *fileset) |
| 1503 | { | 1693 | { |
| 1504 | struct anchorVolDescPtr *anchor; | 1694 | struct anchorVolDescPtr *anchor; |
| 1505 | uint16_t ident; | 1695 | uint16_t ident; |
| 1506 | struct buffer_head *bh; | 1696 | struct buffer_head *bh; |
| 1507 | long main_s, main_e, reserve_s, reserve_e; | 1697 | long main_s, main_e, reserve_s, reserve_e; |
| 1508 | int i, j; | 1698 | int i; |
| 1509 | struct udf_sb_info *sbi; | 1699 | struct udf_sb_info *sbi; |
| 1510 | 1700 | ||
| 1511 | if (!sb) | 1701 | if (!sb) |
| @@ -1515,6 +1705,7 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
| 1515 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { | 1705 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { |
| 1516 | if (!sbi->s_anchor[i]) | 1706 | if (!sbi->s_anchor[i]) |
| 1517 | continue; | 1707 | continue; |
| 1708 | |||
| 1518 | bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i], | 1709 | bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i], |
| 1519 | &ident); | 1710 | &ident); |
| 1520 | if (!bh) | 1711 | if (!bh) |
| @@ -1553,76 +1744,6 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
| 1553 | } | 1744 | } |
| 1554 | udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]); | 1745 | udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]); |
| 1555 | 1746 | ||
| 1556 | for (i = 0; i < sbi->s_partitions; i++) { | ||
| 1557 | kernel_lb_addr uninitialized_var(ino); | ||
| 1558 | struct udf_part_map *map = &sbi->s_partmaps[i]; | ||
| 1559 | switch (map->s_partition_type) { | ||
| 1560 | case UDF_VIRTUAL_MAP15: | ||
| 1561 | case UDF_VIRTUAL_MAP20: | ||
| 1562 | if (!sbi->s_last_block) { | ||
| 1563 | sbi->s_last_block = udf_get_last_block(sb); | ||
| 1564 | udf_find_anchor(sb); | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | if (!sbi->s_last_block) { | ||
| 1568 | udf_debug("Unable to determine Lastblock (For " | ||
| 1569 | "Virtual Partition)\n"); | ||
| 1570 | return 1; | ||
| 1571 | } | ||
| 1572 | |||
| 1573 | for (j = 0; j < sbi->s_partitions; j++) { | ||
| 1574 | struct udf_part_map *map2 = &sbi->s_partmaps[j]; | ||
| 1575 | if (j != i && | ||
| 1576 | map->s_volumeseqnum == | ||
| 1577 | map2->s_volumeseqnum && | ||
| 1578 | map->s_partition_num == | ||
| 1579 | map2->s_partition_num) { | ||
| 1580 | ino.partitionReferenceNum = j; | ||
| 1581 | ino.logicalBlockNum = | ||
| 1582 | sbi->s_last_block - | ||
| 1583 | map2->s_partition_root; | ||
| 1584 | break; | ||
| 1585 | } | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | if (j == sbi->s_partitions) | ||
| 1589 | return 1; | ||
| 1590 | |||
| 1591 | sbi->s_vat_inode = udf_iget(sb, ino); | ||
| 1592 | if (!sbi->s_vat_inode) | ||
| 1593 | return 1; | ||
| 1594 | |||
| 1595 | if (map->s_partition_type == UDF_VIRTUAL_MAP15) { | ||
| 1596 | map->s_type_specific.s_virtual.s_start_offset = | ||
| 1597 | udf_ext0_offset(sbi->s_vat_inode); | ||
| 1598 | map->s_type_specific.s_virtual.s_num_entries = | ||
| 1599 | (sbi->s_vat_inode->i_size - 36) >> 2; | ||
| 1600 | } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) { | ||
| 1601 | uint32_t pos; | ||
| 1602 | struct virtualAllocationTable20 *vat20; | ||
| 1603 | |||
| 1604 | pos = udf_block_map(sbi->s_vat_inode, 0); | ||
| 1605 | bh = sb_bread(sb, pos); | ||
| 1606 | if (!bh) | ||
| 1607 | return 1; | ||
| 1608 | vat20 = (struct virtualAllocationTable20 *) | ||
| 1609 | bh->b_data + | ||
| 1610 | udf_ext0_offset(sbi->s_vat_inode); | ||
| 1611 | map->s_type_specific.s_virtual.s_start_offset = | ||
| 1612 | le16_to_cpu(vat20->lengthHeader) + | ||
| 1613 | udf_ext0_offset(sbi->s_vat_inode); | ||
| 1614 | map->s_type_specific.s_virtual.s_num_entries = | ||
| 1615 | (sbi->s_vat_inode->i_size - | ||
| 1616 | map->s_type_specific.s_virtual. | ||
| 1617 | s_start_offset) >> 2; | ||
| 1618 | brelse(bh); | ||
| 1619 | } | ||
| 1620 | map->s_partition_root = udf_get_pblock(sb, 0, i, 0); | ||
| 1621 | map->s_partition_len = | ||
| 1622 | sbi->s_partmaps[ino.partitionReferenceNum]. | ||
| 1623 | s_partition_len; | ||
| 1624 | } | ||
| 1625 | } | ||
| 1626 | return 0; | 1747 | return 0; |
| 1627 | } | 1748 | } |
| 1628 | 1749 | ||
| @@ -1630,65 +1751,61 @@ static void udf_open_lvid(struct super_block *sb) | |||
| 1630 | { | 1751 | { |
| 1631 | struct udf_sb_info *sbi = UDF_SB(sb); | 1752 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 1632 | struct buffer_head *bh = sbi->s_lvid_bh; | 1753 | struct buffer_head *bh = sbi->s_lvid_bh; |
| 1633 | if (bh) { | 1754 | struct logicalVolIntegrityDesc *lvid; |
| 1634 | kernel_timestamp cpu_time; | 1755 | struct logicalVolIntegrityDescImpUse *lvidiu; |
| 1635 | struct logicalVolIntegrityDesc *lvid = | 1756 | if (!bh) |
| 1636 | (struct logicalVolIntegrityDesc *)bh->b_data; | 1757 | return; |
| 1637 | struct logicalVolIntegrityDescImpUse *lvidiu = | ||
| 1638 | udf_sb_lvidiu(sbi); | ||
| 1639 | 1758 | ||
| 1640 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1759 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
| 1641 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1760 | lvidiu = udf_sb_lvidiu(sbi); |
| 1642 | if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) | ||
| 1643 | lvid->recordingDateAndTime = cpu_to_lets(cpu_time); | ||
| 1644 | lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; | ||
| 1645 | 1761 | ||
| 1646 | lvid->descTag.descCRC = cpu_to_le16( | 1762 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
| 1647 | udf_crc((char *)lvid + sizeof(tag), | 1763 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
| 1648 | le16_to_cpu(lvid->descTag.descCRCLength), | 1764 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, |
| 1649 | 0)); | 1765 | CURRENT_TIME); |
| 1766 | lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; | ||
| 1650 | 1767 | ||
| 1651 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1768 | lvid->descTag.descCRC = cpu_to_le16( |
| 1652 | mark_buffer_dirty(bh); | 1769 | crc_itu_t(0, (char *)lvid + sizeof(tag), |
| 1653 | } | 1770 | le16_to_cpu(lvid->descTag.descCRCLength))); |
| 1771 | |||
| 1772 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | ||
| 1773 | mark_buffer_dirty(bh); | ||
| 1654 | } | 1774 | } |
| 1655 | 1775 | ||
| 1656 | static void udf_close_lvid(struct super_block *sb) | 1776 | static void udf_close_lvid(struct super_block *sb) |
| 1657 | { | 1777 | { |
| 1658 | kernel_timestamp cpu_time; | ||
| 1659 | struct udf_sb_info *sbi = UDF_SB(sb); | 1778 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 1660 | struct buffer_head *bh = sbi->s_lvid_bh; | 1779 | struct buffer_head *bh = sbi->s_lvid_bh; |
| 1661 | struct logicalVolIntegrityDesc *lvid; | 1780 | struct logicalVolIntegrityDesc *lvid; |
| 1781 | struct logicalVolIntegrityDescImpUse *lvidiu; | ||
| 1662 | 1782 | ||
| 1663 | if (!bh) | 1783 | if (!bh) |
| 1664 | return; | 1784 | return; |
| 1665 | 1785 | ||
| 1666 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1786 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
| 1667 | 1787 | ||
| 1668 | if (lvid->integrityType == LVID_INTEGRITY_TYPE_OPEN) { | 1788 | if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN) |
| 1669 | struct logicalVolIntegrityDescImpUse *lvidiu = | 1789 | return; |
| 1670 | udf_sb_lvidiu(sbi); | 1790 | |
| 1671 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1791 | lvidiu = udf_sb_lvidiu(sbi); |
| 1672 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1792 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
| 1673 | if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) | 1793 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
| 1674 | lvid->recordingDateAndTime = cpu_to_lets(cpu_time); | 1794 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); |
| 1675 | if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) | 1795 | if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) |
| 1676 | lvidiu->maxUDFWriteRev = | 1796 | lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION); |
| 1677 | cpu_to_le16(UDF_MAX_WRITE_VERSION); | 1797 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) |
| 1678 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) | 1798 | lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev); |
| 1679 | lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev); | 1799 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev)) |
| 1680 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev)) | 1800 | lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev); |
| 1681 | lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev); | 1801 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); |
| 1682 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); | 1802 | |
| 1683 | 1803 | lvid->descTag.descCRC = cpu_to_le16( | |
| 1684 | lvid->descTag.descCRC = cpu_to_le16( | 1804 | crc_itu_t(0, (char *)lvid + sizeof(tag), |
| 1685 | udf_crc((char *)lvid + sizeof(tag), | 1805 | le16_to_cpu(lvid->descTag.descCRCLength))); |
| 1686 | le16_to_cpu(lvid->descTag.descCRCLength), | 1806 | |
| 1687 | 0)); | 1807 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
| 1688 | 1808 | mark_buffer_dirty(bh); | |
| 1689 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | ||
| 1690 | mark_buffer_dirty(bh); | ||
| 1691 | } | ||
| 1692 | } | 1809 | } |
| 1693 | 1810 | ||
| 1694 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | 1811 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) |
| @@ -1708,22 +1825,35 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | |||
| 1708 | vfree(bitmap); | 1825 | vfree(bitmap); |
| 1709 | } | 1826 | } |
| 1710 | 1827 | ||
| 1711 | /* | 1828 | static void udf_free_partition(struct udf_part_map *map) |
| 1712 | * udf_read_super | 1829 | { |
| 1713 | * | 1830 | int i; |
| 1714 | * PURPOSE | 1831 | struct udf_meta_data *mdata; |
| 1715 | * Complete the specified super block. | 1832 | |
| 1716 | * | 1833 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) |
| 1717 | * PRE-CONDITIONS | 1834 | iput(map->s_uspace.s_table); |
| 1718 | * sb Pointer to superblock to complete - never NULL. | 1835 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
| 1719 | * sb->s_dev Device to read suberblock from. | 1836 | iput(map->s_fspace.s_table); |
| 1720 | * options Pointer to mount options. | 1837 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
| 1721 | * silent Silent flag. | 1838 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); |
| 1722 | * | 1839 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
| 1723 | * HISTORY | 1840 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); |
| 1724 | * July 1, 1997 - Andrew E. Mileski | 1841 | if (map->s_partition_type == UDF_SPARABLE_MAP15) |
| 1725 | * Written, tested, and released. | 1842 | for (i = 0; i < 4; i++) |
| 1726 | */ | 1843 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); |
| 1844 | else if (map->s_partition_type == UDF_METADATA_MAP25) { | ||
| 1845 | mdata = &map->s_type_specific.s_metadata; | ||
| 1846 | iput(mdata->s_metadata_fe); | ||
| 1847 | mdata->s_metadata_fe = NULL; | ||
| 1848 | |||
| 1849 | iput(mdata->s_mirror_fe); | ||
| 1850 | mdata->s_mirror_fe = NULL; | ||
| 1851 | |||
| 1852 | iput(mdata->s_bitmap_fe); | ||
| 1853 | mdata->s_bitmap_fe = NULL; | ||
| 1854 | } | ||
| 1855 | } | ||
| 1856 | |||
| 1727 | static int udf_fill_super(struct super_block *sb, void *options, int silent) | 1857 | static int udf_fill_super(struct super_block *sb, void *options, int silent) |
| 1728 | { | 1858 | { |
| 1729 | int i; | 1859 | int i; |
| @@ -1776,8 +1906,11 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
| 1776 | sbi->s_nls_map = uopt.nls_map; | 1906 | sbi->s_nls_map = uopt.nls_map; |
| 1777 | 1907 | ||
| 1778 | /* Set the block size for all transfers */ | 1908 | /* Set the block size for all transfers */ |
| 1779 | if (!udf_set_blocksize(sb, uopt.blocksize)) | 1909 | if (!sb_min_blocksize(sb, uopt.blocksize)) { |
| 1910 | udf_debug("Bad block size (%d)\n", uopt.blocksize); | ||
| 1911 | printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize); | ||
| 1780 | goto error_out; | 1912 | goto error_out; |
| 1913 | } | ||
| 1781 | 1914 | ||
| 1782 | if (uopt.session == 0xFFFFFFFF) | 1915 | if (uopt.session == 0xFFFFFFFF) |
| 1783 | sbi->s_session = udf_get_last_session(sb); | 1916 | sbi->s_session = udf_get_last_session(sb); |
| @@ -1789,7 +1922,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
| 1789 | sbi->s_last_block = uopt.lastblock; | 1922 | sbi->s_last_block = uopt.lastblock; |
| 1790 | sbi->s_anchor[0] = sbi->s_anchor[1] = 0; | 1923 | sbi->s_anchor[0] = sbi->s_anchor[1] = 0; |
| 1791 | sbi->s_anchor[2] = uopt.anchor; | 1924 | sbi->s_anchor[2] = uopt.anchor; |
| 1792 | sbi->s_anchor[3] = 256; | ||
| 1793 | 1925 | ||
| 1794 | if (udf_check_valid(sb, uopt.novrs, silent)) { | 1926 | if (udf_check_valid(sb, uopt.novrs, silent)) { |
| 1795 | /* read volume recognition sequences */ | 1927 | /* read volume recognition sequences */ |
| @@ -1806,7 +1938,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
| 1806 | sb->s_magic = UDF_SUPER_MAGIC; | 1938 | sb->s_magic = UDF_SUPER_MAGIC; |
| 1807 | sb->s_time_gran = 1000; | 1939 | sb->s_time_gran = 1000; |
| 1808 | 1940 | ||
| 1809 | if (udf_load_partition(sb, &fileset)) { | 1941 | if (udf_load_sequence(sb, &fileset)) { |
| 1810 | printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); | 1942 | printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); |
| 1811 | goto error_out; | 1943 | goto error_out; |
| 1812 | } | 1944 | } |
| @@ -1856,12 +1988,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
| 1856 | } | 1988 | } |
| 1857 | 1989 | ||
| 1858 | if (!silent) { | 1990 | if (!silent) { |
| 1859 | kernel_timestamp ts; | 1991 | timestamp ts; |
| 1860 | udf_time_to_stamp(&ts, sbi->s_record_time); | 1992 | udf_time_to_disk_stamp(&ts, sbi->s_record_time); |
| 1861 | udf_info("UDF: Mounting volume '%s', " | 1993 | udf_info("UDF: Mounting volume '%s', " |
| 1862 | "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", | 1994 | "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", |
| 1863 | sbi->s_volume_ident, ts.year, ts.month, ts.day, | 1995 | sbi->s_volume_ident, le16_to_cpu(ts.year), ts.month, ts.day, |
| 1864 | ts.hour, ts.minute, ts.typeAndTimezone); | 1996 | ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone)); |
| 1865 | } | 1997 | } |
| 1866 | if (!(sb->s_flags & MS_RDONLY)) | 1998 | if (!(sb->s_flags & MS_RDONLY)) |
| 1867 | udf_open_lvid(sb); | 1999 | udf_open_lvid(sb); |
| @@ -1890,21 +2022,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
| 1890 | error_out: | 2022 | error_out: |
| 1891 | if (sbi->s_vat_inode) | 2023 | if (sbi->s_vat_inode) |
| 1892 | iput(sbi->s_vat_inode); | 2024 | iput(sbi->s_vat_inode); |
| 1893 | if (sbi->s_partitions) { | 2025 | if (sbi->s_partitions) |
| 1894 | struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; | 2026 | for (i = 0; i < sbi->s_partitions; i++) |
| 1895 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 2027 | udf_free_partition(&sbi->s_partmaps[i]); |
| 1896 | iput(map->s_uspace.s_table); | ||
| 1897 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | ||
| 1898 | iput(map->s_fspace.s_table); | ||
| 1899 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | ||
| 1900 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); | ||
| 1901 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
| 1902 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); | ||
| 1903 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | ||
| 1904 | for (i = 0; i < 4; i++) | ||
| 1905 | brelse(map->s_type_specific.s_sparing. | ||
| 1906 | s_spar_map[i]); | ||
| 1907 | } | ||
| 1908 | #ifdef CONFIG_UDF_NLS | 2028 | #ifdef CONFIG_UDF_NLS |
| 1909 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) | 2029 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
| 1910 | unload_nls(sbi->s_nls_map); | 2030 | unload_nls(sbi->s_nls_map); |
| @@ -1920,8 +2040,8 @@ error_out: | |||
| 1920 | return -EINVAL; | 2040 | return -EINVAL; |
| 1921 | } | 2041 | } |
| 1922 | 2042 | ||
| 1923 | void udf_error(struct super_block *sb, const char *function, | 2043 | static void udf_error(struct super_block *sb, const char *function, |
| 1924 | const char *fmt, ...) | 2044 | const char *fmt, ...) |
| 1925 | { | 2045 | { |
| 1926 | va_list args; | 2046 | va_list args; |
| 1927 | 2047 | ||
| @@ -1948,19 +2068,6 @@ void udf_warning(struct super_block *sb, const char *function, | |||
| 1948 | sb->s_id, function, error_buf); | 2068 | sb->s_id, function, error_buf); |
| 1949 | } | 2069 | } |
| 1950 | 2070 | ||
| 1951 | /* | ||
| 1952 | * udf_put_super | ||
| 1953 | * | ||
| 1954 | * PURPOSE | ||
| 1955 | * Prepare for destruction of the superblock. | ||
| 1956 | * | ||
| 1957 | * DESCRIPTION | ||
| 1958 | * Called before the filesystem is unmounted. | ||
| 1959 | * | ||
| 1960 | * HISTORY | ||
| 1961 | * July 1, 1997 - Andrew E. Mileski | ||
| 1962 | * Written, tested, and released. | ||
| 1963 | */ | ||
| 1964 | static void udf_put_super(struct super_block *sb) | 2071 | static void udf_put_super(struct super_block *sb) |
| 1965 | { | 2072 | { |
| 1966 | int i; | 2073 | int i; |
| @@ -1969,21 +2076,9 @@ static void udf_put_super(struct super_block *sb) | |||
| 1969 | sbi = UDF_SB(sb); | 2076 | sbi = UDF_SB(sb); |
| 1970 | if (sbi->s_vat_inode) | 2077 | if (sbi->s_vat_inode) |
| 1971 | iput(sbi->s_vat_inode); | 2078 | iput(sbi->s_vat_inode); |
| 1972 | if (sbi->s_partitions) { | 2079 | if (sbi->s_partitions) |
| 1973 | struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; | 2080 | for (i = 0; i < sbi->s_partitions; i++) |
| 1974 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 2081 | udf_free_partition(&sbi->s_partmaps[i]); |
| 1975 | iput(map->s_uspace.s_table); | ||
| 1976 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | ||
| 1977 | iput(map->s_fspace.s_table); | ||
| 1978 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | ||
| 1979 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); | ||
| 1980 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
| 1981 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); | ||
| 1982 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | ||
| 1983 | for (i = 0; i < 4; i++) | ||
| 1984 | brelse(map->s_type_specific.s_sparing. | ||
| 1985 | s_spar_map[i]); | ||
| 1986 | } | ||
| 1987 | #ifdef CONFIG_UDF_NLS | 2082 | #ifdef CONFIG_UDF_NLS |
| 1988 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) | 2083 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
| 1989 | unload_nls(sbi->s_nls_map); | 2084 | unload_nls(sbi->s_nls_map); |
| @@ -1996,19 +2091,6 @@ static void udf_put_super(struct super_block *sb) | |||
| 1996 | sb->s_fs_info = NULL; | 2091 | sb->s_fs_info = NULL; |
| 1997 | } | 2092 | } |
| 1998 | 2093 | ||
| 1999 | /* | ||
| 2000 | * udf_stat_fs | ||
| 2001 | * | ||
| 2002 | * PURPOSE | ||
| 2003 | * Return info about the filesystem. | ||
| 2004 | * | ||
| 2005 | * DESCRIPTION | ||
| 2006 | * Called by sys_statfs() | ||
| 2007 | * | ||
| 2008 | * HISTORY | ||
| 2009 | * July 1, 1997 - Andrew E. Mileski | ||
| 2010 | * Written, tested, and released. | ||
| 2011 | */ | ||
| 2012 | static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | 2094 | static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) |
| 2013 | { | 2095 | { |
| 2014 | struct super_block *sb = dentry->d_sb; | 2096 | struct super_block *sb = dentry->d_sb; |
| @@ -2035,10 +2117,6 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 2035 | return 0; | 2117 | return 0; |
| 2036 | } | 2118 | } |
| 2037 | 2119 | ||
| 2038 | static unsigned char udf_bitmap_lookup[16] = { | ||
| 2039 | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 | ||
| 2040 | }; | ||
| 2041 | |||
| 2042 | static unsigned int udf_count_free_bitmap(struct super_block *sb, | 2120 | static unsigned int udf_count_free_bitmap(struct super_block *sb, |
| 2043 | struct udf_bitmap *bitmap) | 2121 | struct udf_bitmap *bitmap) |
| 2044 | { | 2122 | { |
| @@ -2048,7 +2126,6 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
| 2048 | int block = 0, newblock; | 2126 | int block = 0, newblock; |
| 2049 | kernel_lb_addr loc; | 2127 | kernel_lb_addr loc; |
| 2050 | uint32_t bytes; | 2128 | uint32_t bytes; |
| 2051 | uint8_t value; | ||
| 2052 | uint8_t *ptr; | 2129 | uint8_t *ptr; |
| 2053 | uint16_t ident; | 2130 | uint16_t ident; |
| 2054 | struct spaceBitmapDesc *bm; | 2131 | struct spaceBitmapDesc *bm; |
| @@ -2074,13 +2151,10 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
| 2074 | ptr = (uint8_t *)bh->b_data; | 2151 | ptr = (uint8_t *)bh->b_data; |
| 2075 | 2152 | ||
| 2076 | while (bytes > 0) { | 2153 | while (bytes > 0) { |
| 2077 | while ((bytes > 0) && (index < sb->s_blocksize)) { | 2154 | u32 cur_bytes = min_t(u32, bytes, sb->s_blocksize - index); |
| 2078 | value = ptr[index]; | 2155 | accum += bitmap_weight((const unsigned long *)(ptr + index), |
| 2079 | accum += udf_bitmap_lookup[value & 0x0f]; | 2156 | cur_bytes * 8); |
| 2080 | accum += udf_bitmap_lookup[value >> 4]; | 2157 | bytes -= cur_bytes; |
| 2081 | index++; | ||
| 2082 | bytes--; | ||
| 2083 | } | ||
| 2084 | if (bytes) { | 2158 | if (bytes) { |
| 2085 | brelse(bh); | 2159 | brelse(bh); |
| 2086 | newblock = udf_get_lb_pblock(sb, loc, ++block); | 2160 | newblock = udf_get_lb_pblock(sb, loc, ++block); |
