.. | .. |
---|
11 | 11 | * This code is based on version 2.00 of the UDF specification, |
---|
12 | 12 | * and revision 3 of the ECMA 167 standard [equivalent to ISO 13346]. |
---|
13 | 13 | * http://www.osta.org/ |
---|
14 | | - * http://www.ecma.ch/ |
---|
15 | | - * http://www.iso.org/ |
---|
| 14 | + * https://www.ecma.ch/ |
---|
| 15 | + * https://www.iso.org/ |
---|
16 | 16 | * |
---|
17 | 17 | * COPYRIGHT |
---|
18 | 18 | * This file is distributed under the terms of the GNU General Public |
---|
.. | .. |
---|
93 | 93 | static int udf_sync_fs(struct super_block *, int); |
---|
94 | 94 | static int udf_remount_fs(struct super_block *, int *, char *); |
---|
95 | 95 | static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); |
---|
96 | | -static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, |
---|
97 | | - struct kernel_lb_addr *); |
---|
98 | | -static void udf_load_fileset(struct super_block *, struct buffer_head *, |
---|
99 | | - struct kernel_lb_addr *); |
---|
100 | 96 | static void udf_open_lvid(struct super_block *); |
---|
101 | 97 | static void udf_close_lvid(struct super_block *); |
---|
102 | 98 | static unsigned int udf_count_free(struct super_block *); |
---|
.. | .. |
---|
146 | 142 | |
---|
147 | 143 | ei->i_unique = 0; |
---|
148 | 144 | ei->i_lenExtents = 0; |
---|
| 145 | + ei->i_lenStreams = 0; |
---|
149 | 146 | ei->i_next_alloc_block = 0; |
---|
150 | 147 | ei->i_next_alloc_goal = 0; |
---|
151 | 148 | ei->i_strat4096 = 0; |
---|
| 149 | + ei->i_streamdir = 0; |
---|
| 150 | + ei->i_hidden = 0; |
---|
152 | 151 | init_rwsem(&ei->i_data_sem); |
---|
153 | 152 | ei->cached_extent.lstart = -1; |
---|
154 | 153 | spin_lock_init(&ei->i_extent_cache_lock); |
---|
.. | .. |
---|
157 | 156 | return &ei->vfs_inode; |
---|
158 | 157 | } |
---|
159 | 158 | |
---|
160 | | -static void udf_i_callback(struct rcu_head *head) |
---|
| 159 | +static void udf_free_in_core_inode(struct inode *inode) |
---|
161 | 160 | { |
---|
162 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
---|
163 | 161 | kmem_cache_free(udf_inode_cachep, UDF_I(inode)); |
---|
164 | | -} |
---|
165 | | - |
---|
166 | | -static void udf_destroy_inode(struct inode *inode) |
---|
167 | | -{ |
---|
168 | | - call_rcu(&inode->i_rcu, udf_i_callback); |
---|
169 | 162 | } |
---|
170 | 163 | |
---|
171 | 164 | static void init_once(void *foo) |
---|
172 | 165 | { |
---|
173 | 166 | struct udf_inode_info *ei = (struct udf_inode_info *)foo; |
---|
174 | 167 | |
---|
175 | | - ei->i_ext.i_data = NULL; |
---|
| 168 | + ei->i_data = NULL; |
---|
176 | 169 | inode_init_once(&ei->vfs_inode); |
---|
177 | 170 | } |
---|
178 | 171 | |
---|
.. | .. |
---|
202 | 195 | /* Superblock operations */ |
---|
203 | 196 | static const struct super_operations udf_sb_ops = { |
---|
204 | 197 | .alloc_inode = udf_alloc_inode, |
---|
205 | | - .destroy_inode = udf_destroy_inode, |
---|
| 198 | + .free_inode = udf_free_in_core_inode, |
---|
206 | 199 | .write_inode = udf_write_inode, |
---|
207 | 200 | .evict_inode = udf_evict_inode, |
---|
208 | 201 | .put_super = udf_put_super, |
---|
.. | .. |
---|
273 | 266 | int nr_groups = bitmap->s_nr_groups; |
---|
274 | 267 | |
---|
275 | 268 | for (i = 0; i < nr_groups; i++) |
---|
276 | | - if (bitmap->s_block_bitmap[i]) |
---|
277 | | - brelse(bitmap->s_block_bitmap[i]); |
---|
| 269 | + brelse(bitmap->s_block_bitmap[i]); |
---|
278 | 270 | |
---|
279 | 271 | kvfree(bitmap); |
---|
280 | 272 | } |
---|
.. | .. |
---|
286 | 278 | |
---|
287 | 279 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) |
---|
288 | 280 | iput(map->s_uspace.s_table); |
---|
289 | | - if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
---|
290 | | - iput(map->s_fspace.s_table); |
---|
291 | 281 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
---|
292 | 282 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); |
---|
293 | | - if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
---|
294 | | - udf_sb_free_bitmap(map->s_fspace.s_bitmap); |
---|
295 | 283 | if (map->s_partition_type == UDF_SPARABLE_MAP15) |
---|
296 | 284 | for (i = 0; i < 4; i++) |
---|
297 | 285 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); |
---|
.. | .. |
---|
358 | 346 | seq_printf(seq, ",lastblock=%u", sbi->s_last_block); |
---|
359 | 347 | if (sbi->s_anchor != 0) |
---|
360 | 348 | seq_printf(seq, ",anchor=%u", sbi->s_anchor); |
---|
361 | | - if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) |
---|
362 | | - seq_puts(seq, ",utf8"); |
---|
363 | | - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP) && sbi->s_nls_map) |
---|
| 349 | + if (sbi->s_nls_map) |
---|
364 | 350 | seq_printf(seq, ",iocharset=%s", sbi->s_nls_map->charset); |
---|
| 351 | + else |
---|
| 352 | + seq_puts(seq, ",iocharset=utf8"); |
---|
365 | 353 | |
---|
366 | 354 | return 0; |
---|
367 | 355 | } |
---|
.. | .. |
---|
566 | 554 | /* Ignored (never implemented properly) */ |
---|
567 | 555 | break; |
---|
568 | 556 | case Opt_utf8: |
---|
569 | | - uopt->flags |= (1 << UDF_FLAG_UTF8); |
---|
| 557 | + if (!remount) { |
---|
| 558 | + unload_nls(uopt->nls_map); |
---|
| 559 | + uopt->nls_map = NULL; |
---|
| 560 | + } |
---|
570 | 561 | break; |
---|
571 | 562 | case Opt_iocharset: |
---|
572 | 563 | if (!remount) { |
---|
573 | | - if (uopt->nls_map) |
---|
574 | | - unload_nls(uopt->nls_map); |
---|
| 564 | + unload_nls(uopt->nls_map); |
---|
| 565 | + uopt->nls_map = NULL; |
---|
| 566 | + } |
---|
| 567 | + /* When nls_map is not loaded then UTF-8 is used */ |
---|
| 568 | + if (!remount && strcmp(args[0].from, "utf8") != 0) { |
---|
575 | 569 | uopt->nls_map = load_nls(args[0].from); |
---|
576 | | - uopt->flags |= (1 << UDF_FLAG_NLS_MAP); |
---|
| 570 | + if (!uopt->nls_map) { |
---|
| 571 | + pr_err("iocharset %s not found\n", |
---|
| 572 | + args[0].from); |
---|
| 573 | + return 0; |
---|
| 574 | + } |
---|
577 | 575 | } |
---|
578 | 576 | break; |
---|
579 | 577 | case Opt_uforget: |
---|
.. | .. |
---|
647 | 645 | return error; |
---|
648 | 646 | } |
---|
649 | 647 | |
---|
650 | | -/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ |
---|
651 | | -/* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ |
---|
652 | | -static loff_t udf_check_vsd(struct super_block *sb) |
---|
| 648 | +/* |
---|
| 649 | + * Check VSD descriptor. Returns -1 in case we are at the end of volume |
---|
| 650 | + * recognition area, 0 if the descriptor is valid but non-interesting, 1 if |
---|
| 651 | + * we found one of NSR descriptors we are looking for. |
---|
| 652 | + */ |
---|
| 653 | +static int identify_vsd(const struct volStructDesc *vsd) |
---|
| 654 | +{ |
---|
| 655 | + int ret = 0; |
---|
| 656 | + |
---|
| 657 | + if (!memcmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) { |
---|
| 658 | + switch (vsd->structType) { |
---|
| 659 | + case 0: |
---|
| 660 | + udf_debug("ISO9660 Boot Record found\n"); |
---|
| 661 | + break; |
---|
| 662 | + case 1: |
---|
| 663 | + udf_debug("ISO9660 Primary Volume Descriptor found\n"); |
---|
| 664 | + break; |
---|
| 665 | + case 2: |
---|
| 666 | + udf_debug("ISO9660 Supplementary Volume Descriptor found\n"); |
---|
| 667 | + break; |
---|
| 668 | + case 3: |
---|
| 669 | + udf_debug("ISO9660 Volume Partition Descriptor found\n"); |
---|
| 670 | + break; |
---|
| 671 | + case 255: |
---|
| 672 | + udf_debug("ISO9660 Volume Descriptor Set Terminator found\n"); |
---|
| 673 | + break; |
---|
| 674 | + default: |
---|
| 675 | + udf_debug("ISO9660 VRS (%u) found\n", vsd->structType); |
---|
| 676 | + break; |
---|
| 677 | + } |
---|
| 678 | + } else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) |
---|
| 679 | + ; /* ret = 0 */ |
---|
| 680 | + else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) |
---|
| 681 | + ret = 1; |
---|
| 682 | + else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) |
---|
| 683 | + ret = 1; |
---|
| 684 | + else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BOOT2, VSD_STD_ID_LEN)) |
---|
| 685 | + ; /* ret = 0 */ |
---|
| 686 | + else if (!memcmp(vsd->stdIdent, VSD_STD_ID_CDW02, VSD_STD_ID_LEN)) |
---|
| 687 | + ; /* ret = 0 */ |
---|
| 688 | + else { |
---|
| 689 | + /* TEA01 or invalid id : end of volume recognition area */ |
---|
| 690 | + ret = -1; |
---|
| 691 | + } |
---|
| 692 | + |
---|
| 693 | + return ret; |
---|
| 694 | +} |
---|
| 695 | + |
---|
| 696 | +/* |
---|
| 697 | + * Check Volume Structure Descriptors (ECMA 167 2/9.1) |
---|
| 698 | + * We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) |
---|
| 699 | + * @return 1 if NSR02 or NSR03 found, |
---|
| 700 | + * -1 if first sector read error, 0 otherwise |
---|
| 701 | + */ |
---|
| 702 | +static int udf_check_vsd(struct super_block *sb) |
---|
653 | 703 | { |
---|
654 | 704 | struct volStructDesc *vsd = NULL; |
---|
655 | 705 | loff_t sector = VSD_FIRST_SECTOR_OFFSET; |
---|
656 | 706 | int sectorsize; |
---|
657 | 707 | struct buffer_head *bh = NULL; |
---|
658 | | - int nsr02 = 0; |
---|
659 | | - int nsr03 = 0; |
---|
| 708 | + int nsr = 0; |
---|
660 | 709 | struct udf_sb_info *sbi; |
---|
| 710 | + loff_t session_offset; |
---|
661 | 711 | |
---|
662 | 712 | sbi = UDF_SB(sb); |
---|
663 | 713 | if (sb->s_blocksize < sizeof(struct volStructDesc)) |
---|
.. | .. |
---|
665 | 715 | else |
---|
666 | 716 | sectorsize = sb->s_blocksize; |
---|
667 | 717 | |
---|
668 | | - sector += (((loff_t)sbi->s_session) << sb->s_blocksize_bits); |
---|
| 718 | + session_offset = (loff_t)sbi->s_session << sb->s_blocksize_bits; |
---|
| 719 | + sector += session_offset; |
---|
669 | 720 | |
---|
670 | 721 | udf_debug("Starting at sector %u (%lu byte sectors)\n", |
---|
671 | 722 | (unsigned int)(sector >> sb->s_blocksize_bits), |
---|
.. | .. |
---|
680 | 731 | * activity. This actually happened with uninitialised SSD partitions |
---|
681 | 732 | * (all 0xFF) before the check for the limit and all valid IDs were |
---|
682 | 733 | * added */ |
---|
683 | | - for (; !nsr02 && !nsr03 && sector < VSD_MAX_SECTOR_OFFSET; |
---|
684 | | - sector += sectorsize) { |
---|
| 734 | + for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) { |
---|
685 | 735 | /* Read a block */ |
---|
686 | 736 | bh = udf_tread(sb, sector >> sb->s_blocksize_bits); |
---|
687 | 737 | if (!bh) |
---|
688 | 738 | break; |
---|
689 | 739 | |
---|
690 | | - /* Look for ISO descriptors */ |
---|
691 | 740 | vsd = (struct volStructDesc *)(bh->b_data + |
---|
692 | 741 | (sector & (sb->s_blocksize - 1))); |
---|
693 | | - |
---|
694 | | - if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, |
---|
695 | | - VSD_STD_ID_LEN)) { |
---|
696 | | - switch (vsd->structType) { |
---|
697 | | - case 0: |
---|
698 | | - udf_debug("ISO9660 Boot Record found\n"); |
---|
699 | | - break; |
---|
700 | | - case 1: |
---|
701 | | - udf_debug("ISO9660 Primary Volume Descriptor found\n"); |
---|
702 | | - break; |
---|
703 | | - case 2: |
---|
704 | | - udf_debug("ISO9660 Supplementary Volume Descriptor found\n"); |
---|
705 | | - break; |
---|
706 | | - case 3: |
---|
707 | | - udf_debug("ISO9660 Volume Partition Descriptor found\n"); |
---|
708 | | - break; |
---|
709 | | - case 255: |
---|
710 | | - udf_debug("ISO9660 Volume Descriptor Set Terminator found\n"); |
---|
711 | | - break; |
---|
712 | | - default: |
---|
713 | | - udf_debug("ISO9660 VRS (%u) found\n", |
---|
714 | | - vsd->structType); |
---|
715 | | - break; |
---|
716 | | - } |
---|
717 | | - } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, |
---|
718 | | - VSD_STD_ID_LEN)) |
---|
719 | | - ; /* nothing */ |
---|
720 | | - else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, |
---|
721 | | - VSD_STD_ID_LEN)) { |
---|
| 742 | + nsr = identify_vsd(vsd); |
---|
| 743 | + /* Found NSR or end? */ |
---|
| 744 | + if (nsr) { |
---|
722 | 745 | brelse(bh); |
---|
723 | 746 | break; |
---|
724 | | - } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, |
---|
725 | | - VSD_STD_ID_LEN)) |
---|
726 | | - nsr02 = sector; |
---|
727 | | - else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, |
---|
728 | | - VSD_STD_ID_LEN)) |
---|
729 | | - nsr03 = sector; |
---|
730 | | - else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BOOT2, |
---|
731 | | - VSD_STD_ID_LEN)) |
---|
732 | | - ; /* nothing */ |
---|
733 | | - else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CDW02, |
---|
734 | | - VSD_STD_ID_LEN)) |
---|
735 | | - ; /* nothing */ |
---|
736 | | - else { |
---|
737 | | - /* invalid id : end of volume recognition area */ |
---|
738 | | - brelse(bh); |
---|
739 | | - break; |
---|
| 747 | + } |
---|
| 748 | + /* |
---|
| 749 | + * Special handling for improperly formatted VRS (e.g., Win10) |
---|
| 750 | + * where components are separated by 2048 bytes even though |
---|
| 751 | + * sectors are 4K |
---|
| 752 | + */ |
---|
| 753 | + if (sb->s_blocksize == 4096) { |
---|
| 754 | + nsr = identify_vsd(vsd + 1); |
---|
| 755 | + /* Ignore unknown IDs... */ |
---|
| 756 | + if (nsr < 0) |
---|
| 757 | + nsr = 0; |
---|
740 | 758 | } |
---|
741 | 759 | brelse(bh); |
---|
742 | 760 | } |
---|
743 | 761 | |
---|
744 | | - if (nsr03) |
---|
745 | | - return nsr03; |
---|
746 | | - else if (nsr02) |
---|
747 | | - return nsr02; |
---|
748 | | - else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == |
---|
749 | | - VSD_FIRST_SECTOR_OFFSET) |
---|
| 762 | + if (nsr > 0) |
---|
| 763 | + return 1; |
---|
| 764 | + else if (!bh && sector - session_offset == VSD_FIRST_SECTOR_OFFSET) |
---|
750 | 765 | return -1; |
---|
751 | 766 | else |
---|
752 | 767 | return 0; |
---|
| 768 | +} |
---|
| 769 | + |
---|
| 770 | +static int udf_verify_domain_identifier(struct super_block *sb, |
---|
| 771 | + struct regid *ident, char *dname) |
---|
| 772 | +{ |
---|
| 773 | + struct domainIdentSuffix *suffix; |
---|
| 774 | + |
---|
| 775 | + if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) { |
---|
| 776 | + udf_warn(sb, "Not OSTA UDF compliant %s descriptor.\n", dname); |
---|
| 777 | + goto force_ro; |
---|
| 778 | + } |
---|
| 779 | + if (ident->flags & ENTITYID_FLAGS_DIRTY) { |
---|
| 780 | + udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor.\n", |
---|
| 781 | + dname); |
---|
| 782 | + goto force_ro; |
---|
| 783 | + } |
---|
| 784 | + suffix = (struct domainIdentSuffix *)ident->identSuffix; |
---|
| 785 | + if ((suffix->domainFlags & DOMAIN_FLAGS_HARD_WRITE_PROTECT) || |
---|
| 786 | + (suffix->domainFlags & DOMAIN_FLAGS_SOFT_WRITE_PROTECT)) { |
---|
| 787 | + if (!sb_rdonly(sb)) { |
---|
| 788 | + udf_warn(sb, "Descriptor for %s marked write protected." |
---|
| 789 | + " Forcing read only mount.\n", dname); |
---|
| 790 | + } |
---|
| 791 | + goto force_ro; |
---|
| 792 | + } |
---|
| 793 | + return 0; |
---|
| 794 | + |
---|
| 795 | +force_ro: |
---|
| 796 | + if (!sb_rdonly(sb)) |
---|
| 797 | + return -EACCES; |
---|
| 798 | + UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
---|
| 799 | + return 0; |
---|
| 800 | +} |
---|
| 801 | + |
---|
| 802 | +static int udf_load_fileset(struct super_block *sb, struct fileSetDesc *fset, |
---|
| 803 | + struct kernel_lb_addr *root) |
---|
| 804 | +{ |
---|
| 805 | + int ret; |
---|
| 806 | + |
---|
| 807 | + ret = udf_verify_domain_identifier(sb, &fset->domainIdent, "file set"); |
---|
| 808 | + if (ret < 0) |
---|
| 809 | + return ret; |
---|
| 810 | + |
---|
| 811 | + *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation); |
---|
| 812 | + UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum); |
---|
| 813 | + |
---|
| 814 | + udf_debug("Rootdir at block=%u, partition=%u\n", |
---|
| 815 | + root->logicalBlockNum, root->partitionReferenceNum); |
---|
| 816 | + return 0; |
---|
753 | 817 | } |
---|
754 | 818 | |
---|
755 | 819 | static int udf_find_fileset(struct super_block *sb, |
---|
.. | .. |
---|
758 | 822 | { |
---|
759 | 823 | struct buffer_head *bh = NULL; |
---|
760 | 824 | uint16_t ident; |
---|
| 825 | + int ret; |
---|
761 | 826 | |
---|
762 | | - if (fileset->logicalBlockNum != 0xFFFFFFFF || |
---|
763 | | - fileset->partitionReferenceNum != 0xFFFF) { |
---|
764 | | - bh = udf_read_ptagged(sb, fileset, 0, &ident); |
---|
| 827 | + if (fileset->logicalBlockNum == 0xFFFFFFFF && |
---|
| 828 | + fileset->partitionReferenceNum == 0xFFFF) |
---|
| 829 | + return -EINVAL; |
---|
765 | 830 | |
---|
766 | | - if (!bh) { |
---|
767 | | - return 1; |
---|
768 | | - } else if (ident != TAG_IDENT_FSD) { |
---|
769 | | - brelse(bh); |
---|
770 | | - return 1; |
---|
771 | | - } |
---|
772 | | - |
---|
773 | | - udf_debug("Fileset at block=%u, partition=%u\n", |
---|
774 | | - fileset->logicalBlockNum, |
---|
775 | | - fileset->partitionReferenceNum); |
---|
776 | | - |
---|
777 | | - UDF_SB(sb)->s_partition = fileset->partitionReferenceNum; |
---|
778 | | - udf_load_fileset(sb, bh, root); |
---|
| 831 | + bh = udf_read_ptagged(sb, fileset, 0, &ident); |
---|
| 832 | + if (!bh) |
---|
| 833 | + return -EIO; |
---|
| 834 | + if (ident != TAG_IDENT_FSD) { |
---|
779 | 835 | brelse(bh); |
---|
780 | | - return 0; |
---|
| 836 | + return -EINVAL; |
---|
781 | 837 | } |
---|
782 | | - return 1; |
---|
| 838 | + |
---|
| 839 | + udf_debug("Fileset at block=%u, partition=%u\n", |
---|
| 840 | + fileset->logicalBlockNum, fileset->partitionReferenceNum); |
---|
| 841 | + |
---|
| 842 | + UDF_SB(sb)->s_partition = fileset->partitionReferenceNum; |
---|
| 843 | + ret = udf_load_fileset(sb, (struct fileSetDesc *)bh->b_data, root); |
---|
| 844 | + brelse(bh); |
---|
| 845 | + return ret; |
---|
783 | 846 | } |
---|
784 | 847 | |
---|
785 | 848 | /* |
---|
.. | .. |
---|
794 | 857 | uint8_t *outstr; |
---|
795 | 858 | struct buffer_head *bh; |
---|
796 | 859 | uint16_t ident; |
---|
797 | | - int ret = -ENOMEM; |
---|
798 | | -#ifdef UDFFS_DEBUG |
---|
| 860 | + int ret; |
---|
799 | 861 | struct timestamp *ts; |
---|
800 | | -#endif |
---|
801 | 862 | |
---|
802 | 863 | outstr = kmalloc(128, GFP_NOFS); |
---|
803 | 864 | if (!outstr) |
---|
.. | .. |
---|
818 | 879 | |
---|
819 | 880 | udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, |
---|
820 | 881 | pvoldesc->recordingDateAndTime); |
---|
821 | | -#ifdef UDFFS_DEBUG |
---|
822 | 882 | ts = &pvoldesc->recordingDateAndTime; |
---|
823 | 883 | udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n", |
---|
824 | 884 | le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, |
---|
825 | 885 | ts->minute, le16_to_cpu(ts->typeAndTimezone)); |
---|
826 | | -#endif |
---|
827 | | - |
---|
828 | 886 | |
---|
829 | 887 | ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32); |
---|
830 | 888 | if (ret < 0) { |
---|
.. | .. |
---|
940 | 998 | return 0; |
---|
941 | 999 | } |
---|
942 | 1000 | |
---|
943 | | -static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, |
---|
944 | | - struct kernel_lb_addr *root) |
---|
945 | | -{ |
---|
946 | | - struct fileSetDesc *fset; |
---|
947 | | - |
---|
948 | | - fset = (struct fileSetDesc *)bh->b_data; |
---|
949 | | - |
---|
950 | | - *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation); |
---|
951 | | - |
---|
952 | | - UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum); |
---|
953 | | - |
---|
954 | | - udf_debug("Rootdir at block=%u, partition=%u\n", |
---|
955 | | - root->logicalBlockNum, root->partitionReferenceNum); |
---|
956 | | -} |
---|
957 | | - |
---|
958 | 1001 | int udf_compute_nr_groups(struct super_block *sb, u32 partition) |
---|
959 | 1002 | { |
---|
960 | 1003 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
---|
.. | .. |
---|
966 | 1009 | static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) |
---|
967 | 1010 | { |
---|
968 | 1011 | struct udf_bitmap *bitmap; |
---|
969 | | - int nr_groups; |
---|
970 | | - int size; |
---|
| 1012 | + int nr_groups = udf_compute_nr_groups(sb, index); |
---|
971 | 1013 | |
---|
972 | | - nr_groups = udf_compute_nr_groups(sb, index); |
---|
973 | | - size = sizeof(struct udf_bitmap) + |
---|
974 | | - (sizeof(struct buffer_head *) * nr_groups); |
---|
975 | | - |
---|
976 | | - if (size <= PAGE_SIZE) |
---|
977 | | - bitmap = kzalloc(size, GFP_KERNEL); |
---|
978 | | - else |
---|
979 | | - bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ |
---|
980 | | - |
---|
| 1014 | + bitmap = kvzalloc(struct_size(bitmap, s_block_bitmap, nr_groups), |
---|
| 1015 | + GFP_KERNEL); |
---|
981 | 1016 | if (!bitmap) |
---|
982 | 1017 | return NULL; |
---|
983 | 1018 | |
---|
.. | .. |
---|
1022 | 1057 | goto force_ro; |
---|
1023 | 1058 | |
---|
1024 | 1059 | if (map->s_partition_type == UDF_VIRTUAL_MAP15 || |
---|
1025 | | - map->s_partition_type == UDF_VIRTUAL_MAP20) |
---|
| 1060 | + map->s_partition_type == UDF_VIRTUAL_MAP20 || |
---|
| 1061 | + map->s_partition_type == UDF_METADATA_MAP25) |
---|
1026 | 1062 | goto force_ro; |
---|
1027 | 1063 | |
---|
1028 | 1064 | return 0; |
---|
.. | .. |
---|
1104 | 1140 | p_index, bitmap->s_extPosition); |
---|
1105 | 1141 | } |
---|
1106 | 1142 | |
---|
1107 | | - if (phd->freedSpaceTable.extLength) { |
---|
1108 | | - struct kernel_lb_addr loc = { |
---|
1109 | | - .logicalBlockNum = le32_to_cpu( |
---|
1110 | | - phd->freedSpaceTable.extPosition), |
---|
1111 | | - .partitionReferenceNum = p_index, |
---|
1112 | | - }; |
---|
1113 | | - struct inode *inode; |
---|
1114 | | - |
---|
1115 | | - inode = udf_iget_special(sb, &loc); |
---|
1116 | | - if (IS_ERR(inode)) { |
---|
1117 | | - udf_debug("cannot load freedSpaceTable (part %d)\n", |
---|
1118 | | - p_index); |
---|
1119 | | - return PTR_ERR(inode); |
---|
1120 | | - } |
---|
1121 | | - map->s_fspace.s_table = inode; |
---|
1122 | | - map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE; |
---|
1123 | | - udf_debug("freedSpaceTable (part %d) @ %lu\n", |
---|
1124 | | - p_index, map->s_fspace.s_table->i_ino); |
---|
1125 | | - } |
---|
1126 | | - |
---|
1127 | | - if (phd->freedSpaceBitmap.extLength) { |
---|
1128 | | - struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); |
---|
1129 | | - if (!bitmap) |
---|
1130 | | - return -ENOMEM; |
---|
1131 | | - map->s_fspace.s_bitmap = bitmap; |
---|
1132 | | - bitmap->s_extPosition = le32_to_cpu( |
---|
1133 | | - phd->freedSpaceBitmap.extPosition); |
---|
1134 | | - map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; |
---|
1135 | | - udf_debug("freedSpaceBitmap (part %d) @ %u\n", |
---|
1136 | | - p_index, bitmap->s_extPosition); |
---|
1137 | | - } |
---|
1138 | 1143 | return 0; |
---|
1139 | 1144 | } |
---|
1140 | 1145 | |
---|
.. | .. |
---|
1200 | 1205 | vat20 = (struct virtualAllocationTable20 *)bh->b_data; |
---|
1201 | 1206 | } else { |
---|
1202 | 1207 | vat20 = (struct virtualAllocationTable20 *) |
---|
1203 | | - vati->i_ext.i_data; |
---|
| 1208 | + vati->i_data; |
---|
1204 | 1209 | } |
---|
1205 | 1210 | |
---|
1206 | 1211 | map->s_type_specific.s_virtual.s_start_offset = |
---|
.. | .. |
---|
1269 | 1274 | * PHYSICAL partitions are already set up |
---|
1270 | 1275 | */ |
---|
1271 | 1276 | type1_idx = i; |
---|
1272 | | -#ifdef UDFFS_DEBUG |
---|
1273 | 1277 | map = NULL; /* supress 'maybe used uninitialized' warning */ |
---|
1274 | | -#endif |
---|
1275 | 1278 | for (i = 0; i < sbi->s_partitions; i++) { |
---|
1276 | 1279 | map = &sbi->s_partmaps[i]; |
---|
1277 | 1280 | |
---|
.. | .. |
---|
1401 | 1404 | goto out_bh; |
---|
1402 | 1405 | } |
---|
1403 | 1406 | |
---|
| 1407 | + ret = udf_verify_domain_identifier(sb, &lvd->domainIdent, |
---|
| 1408 | + "logical volume"); |
---|
| 1409 | + if (ret) |
---|
| 1410 | + goto out_bh; |
---|
1404 | 1411 | ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); |
---|
1405 | 1412 | if (ret) |
---|
1406 | 1413 | goto out_bh; |
---|
.. | .. |
---|
1510 | 1517 | if (lvd->integritySeqExt.extLength) |
---|
1511 | 1518 | udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); |
---|
1512 | 1519 | ret = 0; |
---|
| 1520 | + |
---|
| 1521 | + if (!sbi->s_lvid_bh) { |
---|
| 1522 | + /* We can't generate unique IDs without a valid LVID */ |
---|
| 1523 | + if (sb_rdonly(sb)) { |
---|
| 1524 | + UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
---|
| 1525 | + } else { |
---|
| 1526 | + udf_warn(sb, "Damaged or missing LVID, forcing " |
---|
| 1527 | + "readonly mount\n"); |
---|
| 1528 | + ret = -EACCES; |
---|
| 1529 | + } |
---|
| 1530 | + } |
---|
1513 | 1531 | out_bh: |
---|
1514 | 1532 | brelse(bh); |
---|
1515 | 1533 | return ret; |
---|
.. | .. |
---|
1959 | 1977 | int silent, struct kernel_lb_addr *fileset) |
---|
1960 | 1978 | { |
---|
1961 | 1979 | struct udf_sb_info *sbi = UDF_SB(sb); |
---|
1962 | | - loff_t nsr_off; |
---|
| 1980 | + int nsr = 0; |
---|
1963 | 1981 | int ret; |
---|
1964 | 1982 | |
---|
1965 | 1983 | if (!sb_set_blocksize(sb, uopt->blocksize)) { |
---|
.. | .. |
---|
1970 | 1988 | sbi->s_last_block = uopt->lastblock; |
---|
1971 | 1989 | if (!uopt->novrs) { |
---|
1972 | 1990 | /* Check that it is NSR02 compliant */ |
---|
1973 | | - nsr_off = udf_check_vsd(sb); |
---|
1974 | | - if (!nsr_off) { |
---|
| 1991 | + nsr = udf_check_vsd(sb); |
---|
| 1992 | + if (!nsr) { |
---|
1975 | 1993 | if (!silent) |
---|
1976 | 1994 | udf_warn(sb, "No VRS found\n"); |
---|
1977 | 1995 | return -EINVAL; |
---|
1978 | 1996 | } |
---|
1979 | | - if (nsr_off == -1) |
---|
| 1997 | + if (nsr == -1) |
---|
1980 | 1998 | udf_debug("Failed to read sector at offset %d. " |
---|
1981 | 1999 | "Assuming open disc. Skipping validity " |
---|
1982 | 2000 | "check\n", VSD_FIRST_SECTOR_OFFSET); |
---|
.. | .. |
---|
1997 | 2015 | return 0; |
---|
1998 | 2016 | } |
---|
1999 | 2017 | |
---|
| 2018 | +static void udf_finalize_lvid(struct logicalVolIntegrityDesc *lvid) |
---|
| 2019 | +{ |
---|
| 2020 | + struct timespec64 ts; |
---|
| 2021 | + |
---|
| 2022 | + ktime_get_real_ts64(&ts); |
---|
| 2023 | + udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts); |
---|
| 2024 | + lvid->descTag.descCRC = cpu_to_le16( |
---|
| 2025 | + crc_itu_t(0, (char *)lvid + sizeof(struct tag), |
---|
| 2026 | + le16_to_cpu(lvid->descTag.descCRCLength))); |
---|
| 2027 | + lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
---|
| 2028 | +} |
---|
| 2029 | + |
---|
2000 | 2030 | static void udf_open_lvid(struct super_block *sb) |
---|
2001 | 2031 | { |
---|
2002 | 2032 | struct udf_sb_info *sbi = UDF_SB(sb); |
---|
2003 | 2033 | struct buffer_head *bh = sbi->s_lvid_bh; |
---|
2004 | 2034 | struct logicalVolIntegrityDesc *lvid; |
---|
2005 | 2035 | struct logicalVolIntegrityDescImpUse *lvidiu; |
---|
2006 | | - struct timespec64 ts; |
---|
2007 | 2036 | |
---|
2008 | 2037 | if (!bh) |
---|
2009 | 2038 | return; |
---|
.. | .. |
---|
2015 | 2044 | mutex_lock(&sbi->s_alloc_mutex); |
---|
2016 | 2045 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
---|
2017 | 2046 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
---|
2018 | | - ktime_get_real_ts64(&ts); |
---|
2019 | | - udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts); |
---|
2020 | 2047 | if (le32_to_cpu(lvid->integrityType) == LVID_INTEGRITY_TYPE_CLOSE) |
---|
2021 | 2048 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN); |
---|
2022 | 2049 | else |
---|
2023 | 2050 | UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT); |
---|
2024 | 2051 | |
---|
2025 | | - lvid->descTag.descCRC = cpu_to_le16( |
---|
2026 | | - crc_itu_t(0, (char *)lvid + sizeof(struct tag), |
---|
2027 | | - le16_to_cpu(lvid->descTag.descCRCLength))); |
---|
2028 | | - |
---|
2029 | | - lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
---|
| 2052 | + udf_finalize_lvid(lvid); |
---|
2030 | 2053 | mark_buffer_dirty(bh); |
---|
2031 | 2054 | sbi->s_lvid_dirty = 0; |
---|
2032 | 2055 | mutex_unlock(&sbi->s_alloc_mutex); |
---|
.. | .. |
---|
2040 | 2063 | struct buffer_head *bh = sbi->s_lvid_bh; |
---|
2041 | 2064 | struct logicalVolIntegrityDesc *lvid; |
---|
2042 | 2065 | struct logicalVolIntegrityDescImpUse *lvidiu; |
---|
2043 | | - struct timespec64 ts; |
---|
2044 | 2066 | |
---|
2045 | 2067 | if (!bh) |
---|
2046 | 2068 | return; |
---|
.. | .. |
---|
2052 | 2074 | mutex_lock(&sbi->s_alloc_mutex); |
---|
2053 | 2075 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
---|
2054 | 2076 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
---|
2055 | | - ktime_get_real_ts64(&ts); |
---|
2056 | | - udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts); |
---|
2057 | 2077 | if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) |
---|
2058 | 2078 | lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION); |
---|
2059 | 2079 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) |
---|
.. | .. |
---|
2063 | 2083 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT)) |
---|
2064 | 2084 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); |
---|
2065 | 2085 | |
---|
2066 | | - lvid->descTag.descCRC = cpu_to_le16( |
---|
2067 | | - crc_itu_t(0, (char *)lvid + sizeof(struct tag), |
---|
2068 | | - le16_to_cpu(lvid->descTag.descCRCLength))); |
---|
2069 | | - |
---|
2070 | | - lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
---|
2071 | 2086 | /* |
---|
2072 | 2087 | * We set buffer uptodate unconditionally here to avoid spurious |
---|
2073 | 2088 | * warnings from mark_buffer_dirty() when previous EIO has marked |
---|
2074 | 2089 | * the buffer as !uptodate |
---|
2075 | 2090 | */ |
---|
2076 | 2091 | set_buffer_uptodate(bh); |
---|
| 2092 | + udf_finalize_lvid(lvid); |
---|
2077 | 2093 | mark_buffer_dirty(bh); |
---|
2078 | 2094 | sbi->s_lvid_dirty = 0; |
---|
2079 | 2095 | mutex_unlock(&sbi->s_alloc_mutex); |
---|
.. | .. |
---|
2102 | 2118 | if (!(++uniqueID & 0xFFFFFFFF)) |
---|
2103 | 2119 | uniqueID += 16; |
---|
2104 | 2120 | lvhd->uniqueID = cpu_to_le64(uniqueID); |
---|
| 2121 | + udf_updated_lvid(sb); |
---|
2105 | 2122 | mutex_unlock(&sbi->s_alloc_mutex); |
---|
2106 | | - mark_buffer_dirty(bh); |
---|
2107 | 2123 | |
---|
2108 | 2124 | return ret; |
---|
2109 | 2125 | } |
---|
.. | .. |
---|
2136 | 2152 | |
---|
2137 | 2153 | if (!udf_parse_options((char *)options, &uopt, false)) |
---|
2138 | 2154 | goto parse_options_failure; |
---|
2139 | | - |
---|
2140 | | - if (uopt.flags & (1 << UDF_FLAG_UTF8) && |
---|
2141 | | - uopt.flags & (1 << UDF_FLAG_NLS_MAP)) { |
---|
2142 | | - udf_err(sb, "utf8 cannot be combined with iocharset\n"); |
---|
2143 | | - goto parse_options_failure; |
---|
2144 | | - } |
---|
2145 | | - if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) { |
---|
2146 | | - uopt.nls_map = load_nls_default(); |
---|
2147 | | - if (!uopt.nls_map) |
---|
2148 | | - uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP); |
---|
2149 | | - else |
---|
2150 | | - udf_debug("Using default NLS map\n"); |
---|
2151 | | - } |
---|
2152 | | - if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP))) |
---|
2153 | | - uopt.flags |= (1 << UDF_FLAG_UTF8); |
---|
2154 | 2155 | |
---|
2155 | 2156 | fileset.logicalBlockNum = 0xFFFFFFFF; |
---|
2156 | 2157 | fileset.partitionReferenceNum = 0xFFFF; |
---|
.. | .. |
---|
2262 | 2263 | UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
---|
2263 | 2264 | } |
---|
2264 | 2265 | |
---|
2265 | | - if (udf_find_fileset(sb, &fileset, &rootdir)) { |
---|
| 2266 | + ret = udf_find_fileset(sb, &fileset, &rootdir); |
---|
| 2267 | + if (ret < 0) { |
---|
2266 | 2268 | udf_warn(sb, "No fileset found\n"); |
---|
2267 | | - ret = -EINVAL; |
---|
2268 | 2269 | goto error_out; |
---|
2269 | 2270 | } |
---|
2270 | 2271 | |
---|
.. | .. |
---|
2306 | 2307 | error_out: |
---|
2307 | 2308 | iput(sbi->s_vat_inode); |
---|
2308 | 2309 | parse_options_failure: |
---|
2309 | | - if (uopt.nls_map) |
---|
2310 | | - unload_nls(uopt.nls_map); |
---|
| 2310 | + unload_nls(uopt.nls_map); |
---|
2311 | 2311 | if (lvid_open) |
---|
2312 | 2312 | udf_close_lvid(sb); |
---|
2313 | 2313 | brelse(sbi->s_lvid_bh); |
---|
.. | .. |
---|
2357 | 2357 | sbi = UDF_SB(sb); |
---|
2358 | 2358 | |
---|
2359 | 2359 | iput(sbi->s_vat_inode); |
---|
2360 | | - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
---|
2361 | | - unload_nls(sbi->s_nls_map); |
---|
| 2360 | + unload_nls(sbi->s_nls_map); |
---|
2362 | 2361 | if (!sb_rdonly(sb)) |
---|
2363 | 2362 | udf_close_lvid(sb); |
---|
2364 | 2363 | brelse(sbi->s_lvid_bh); |
---|
.. | .. |
---|
2374 | 2373 | |
---|
2375 | 2374 | mutex_lock(&sbi->s_alloc_mutex); |
---|
2376 | 2375 | if (sbi->s_lvid_dirty) { |
---|
| 2376 | + struct buffer_head *bh = sbi->s_lvid_bh; |
---|
| 2377 | + struct logicalVolIntegrityDesc *lvid; |
---|
| 2378 | + |
---|
| 2379 | + lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
---|
| 2380 | + udf_finalize_lvid(lvid); |
---|
| 2381 | + |
---|
2377 | 2382 | /* |
---|
2378 | 2383 | * Blockdevice will be synced later so we don't have to submit |
---|
2379 | 2384 | * the buffer for IO |
---|
2380 | 2385 | */ |
---|
2381 | | - mark_buffer_dirty(sbi->s_lvid_bh); |
---|
| 2386 | + mark_buffer_dirty(bh); |
---|
2382 | 2387 | sbi->s_lvid_dirty = 0; |
---|
2383 | 2388 | } |
---|
2384 | 2389 | mutex_unlock(&sbi->s_alloc_mutex); |
---|
.. | .. |
---|
2399 | 2404 | buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len; |
---|
2400 | 2405 | buf->f_bfree = udf_count_free(sb); |
---|
2401 | 2406 | buf->f_bavail = buf->f_bfree; |
---|
| 2407 | + /* |
---|
| 2408 | + * Let's pretend each free block is also a free 'inode' since UDF does |
---|
| 2409 | + * not have separate preallocated table of inodes. |
---|
| 2410 | + */ |
---|
2402 | 2411 | buf->f_files = (lvidiu != NULL ? (le32_to_cpu(lvidiu->numFiles) + |
---|
2403 | 2412 | le32_to_cpu(lvidiu->numDirs)) : 0) |
---|
2404 | 2413 | + buf->f_bfree; |
---|
2405 | 2414 | buf->f_ffree = buf->f_bfree; |
---|
2406 | 2415 | buf->f_namelen = UDF_NAME_LEN; |
---|
2407 | | - buf->f_fsid.val[0] = (u32)id; |
---|
2408 | | - buf->f_fsid.val[1] = (u32)(id >> 32); |
---|
| 2416 | + buf->f_fsid = u64_to_fsid(id); |
---|
2409 | 2417 | |
---|
2410 | 2418 | return 0; |
---|
2411 | 2419 | } |
---|
.. | .. |
---|
2525 | 2533 | accum += udf_count_free_bitmap(sb, |
---|
2526 | 2534 | map->s_uspace.s_bitmap); |
---|
2527 | 2535 | } |
---|
2528 | | - if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { |
---|
2529 | | - accum += udf_count_free_bitmap(sb, |
---|
2530 | | - map->s_fspace.s_bitmap); |
---|
2531 | | - } |
---|
2532 | 2536 | if (accum) |
---|
2533 | 2537 | return accum; |
---|
2534 | 2538 | |
---|
.. | .. |
---|
2536 | 2540 | accum += udf_count_free_table(sb, |
---|
2537 | 2541 | map->s_uspace.s_table); |
---|
2538 | 2542 | } |
---|
2539 | | - if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { |
---|
2540 | | - accum += udf_count_free_table(sb, |
---|
2541 | | - map->s_fspace.s_table); |
---|
2542 | | - } |
---|
2543 | | - |
---|
2544 | 2543 | return accum; |
---|
2545 | 2544 | } |
---|
2546 | 2545 | |
---|
2547 | 2546 | MODULE_AUTHOR("Ben Fennema"); |
---|
2548 | 2547 | MODULE_DESCRIPTION("Universal Disk Format Filesystem"); |
---|
2549 | 2548 | MODULE_LICENSE("GPL"); |
---|
| 2549 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
---|
2550 | 2550 | module_init(init_udf_fs) |
---|
2551 | 2551 | module_exit(exit_udf_fs) |
---|