diff options
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r-- | fs/udf/super.c | 605 |
1 files changed, 312 insertions, 293 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index e25e7010627b..72348cc855a4 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -81,16 +81,13 @@ static char error_buf[1024]; | |||
81 | /* These are the "meat" - everything else is stuffing */ | 81 | /* These are the "meat" - everything else is stuffing */ |
82 | static int udf_fill_super(struct super_block *, void *, int); | 82 | static int udf_fill_super(struct super_block *, void *, int); |
83 | static void udf_put_super(struct super_block *); | 83 | static void udf_put_super(struct super_block *); |
84 | static void udf_write_super(struct super_block *); | 84 | static int udf_sync_fs(struct super_block *, int); |
85 | static int udf_remount_fs(struct super_block *, int *, char *); | 85 | static int udf_remount_fs(struct super_block *, int *, char *); |
86 | static int udf_check_valid(struct super_block *, int, int); | 86 | static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); |
87 | static int udf_vrs(struct super_block *sb, int silent); | 87 | static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, |
88 | static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); | 88 | struct kernel_lb_addr *); |
89 | static void udf_find_anchor(struct super_block *); | ||
90 | static int udf_find_fileset(struct super_block *, kernel_lb_addr *, | ||
91 | kernel_lb_addr *); | ||
92 | static void udf_load_fileset(struct super_block *, struct buffer_head *, | 89 | static void udf_load_fileset(struct super_block *, struct buffer_head *, |
93 | kernel_lb_addr *); | 90 | struct kernel_lb_addr *); |
94 | static void udf_open_lvid(struct super_block *); | 91 | static void udf_open_lvid(struct super_block *); |
95 | static void udf_close_lvid(struct super_block *); | 92 | static void udf_close_lvid(struct super_block *); |
96 | static unsigned int udf_count_free(struct super_block *); | 93 | static unsigned int udf_count_free(struct super_block *); |
@@ -181,7 +178,7 @@ static const struct super_operations udf_sb_ops = { | |||
181 | .delete_inode = udf_delete_inode, | 178 | .delete_inode = udf_delete_inode, |
182 | .clear_inode = udf_clear_inode, | 179 | .clear_inode = udf_clear_inode, |
183 | .put_super = udf_put_super, | 180 | .put_super = udf_put_super, |
184 | .write_super = udf_write_super, | 181 | .sync_fs = udf_sync_fs, |
185 | .statfs = udf_statfs, | 182 | .statfs = udf_statfs, |
186 | .remount_fs = udf_remount_fs, | 183 | .remount_fs = udf_remount_fs, |
187 | .show_options = udf_show_options, | 184 | .show_options = udf_show_options, |
@@ -201,6 +198,8 @@ struct udf_options { | |||
201 | mode_t umask; | 198 | mode_t umask; |
202 | gid_t gid; | 199 | gid_t gid; |
203 | uid_t uid; | 200 | uid_t uid; |
201 | mode_t fmode; | ||
202 | mode_t dmode; | ||
204 | struct nls_table *nls_map; | 203 | struct nls_table *nls_map; |
205 | }; | 204 | }; |
206 | 205 | ||
@@ -258,7 +257,7 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt) | |||
258 | 257 | ||
259 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) | 258 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) |
260 | seq_puts(seq, ",nostrict"); | 259 | seq_puts(seq, ",nostrict"); |
261 | if (sb->s_blocksize != UDF_DEFAULT_BLOCKSIZE) | 260 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET)) |
262 | seq_printf(seq, ",bs=%lu", sb->s_blocksize); | 261 | seq_printf(seq, ",bs=%lu", sb->s_blocksize); |
263 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) | 262 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) |
264 | seq_puts(seq, ",unhide"); | 263 | seq_puts(seq, ",unhide"); |
@@ -282,18 +281,16 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt) | |||
282 | seq_printf(seq, ",gid=%u", sbi->s_gid); | 281 | seq_printf(seq, ",gid=%u", sbi->s_gid); |
283 | if (sbi->s_umask != 0) | 282 | if (sbi->s_umask != 0) |
284 | seq_printf(seq, ",umask=%o", sbi->s_umask); | 283 | seq_printf(seq, ",umask=%o", sbi->s_umask); |
284 | if (sbi->s_fmode != UDF_INVALID_MODE) | ||
285 | seq_printf(seq, ",mode=%o", sbi->s_fmode); | ||
286 | if (sbi->s_dmode != UDF_INVALID_MODE) | ||
287 | seq_printf(seq, ",dmode=%o", sbi->s_dmode); | ||
285 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET)) | 288 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET)) |
286 | seq_printf(seq, ",session=%u", sbi->s_session); | 289 | seq_printf(seq, ",session=%u", sbi->s_session); |
287 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET)) | 290 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET)) |
288 | seq_printf(seq, ",lastblock=%u", sbi->s_last_block); | 291 | seq_printf(seq, ",lastblock=%u", sbi->s_last_block); |
289 | /* | 292 | if (sbi->s_anchor != 0) |
290 | * s_anchor[2] could be zeroed out in case there is no anchor | 293 | seq_printf(seq, ",anchor=%u", sbi->s_anchor); |
291 | * in the specified block, but then the "anchor=N" option | ||
292 | * originally given by the user wasn't effective, so it's OK | ||
293 | * if we don't show it. | ||
294 | */ | ||
295 | if (sbi->s_anchor[2] != 0) | ||
296 | seq_printf(seq, ",anchor=%u", sbi->s_anchor[2]); | ||
297 | /* | 294 | /* |
298 | * volume, partition, fileset and rootdir seem to be ignored | 295 | * volume, partition, fileset and rootdir seem to be ignored |
299 | * currently | 296 | * currently |
@@ -317,6 +314,8 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt) | |||
317 | * | 314 | * |
318 | * gid= Set the default group. | 315 | * gid= Set the default group. |
319 | * umask= Set the default umask. | 316 | * umask= Set the default umask. |
317 | * mode= Set the default file permissions. | ||
318 | * dmode= Set the default directory permissions. | ||
320 | * uid= Set the default user. | 319 | * uid= Set the default user. |
321 | * bs= Set the block size. | 320 | * bs= Set the block size. |
322 | * unhide Show otherwise hidden files. | 321 | * unhide Show otherwise hidden files. |
@@ -366,7 +365,8 @@ enum { | |||
366 | Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, | 365 | Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, |
367 | Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, | 366 | Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, |
368 | Opt_rootdir, Opt_utf8, Opt_iocharset, | 367 | Opt_rootdir, Opt_utf8, Opt_iocharset, |
369 | Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore | 368 | Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore, |
369 | Opt_fmode, Opt_dmode | ||
370 | }; | 370 | }; |
371 | 371 | ||
372 | static const match_table_t tokens = { | 372 | static const match_table_t tokens = { |
@@ -395,6 +395,8 @@ static const match_table_t tokens = { | |||
395 | {Opt_rootdir, "rootdir=%u"}, | 395 | {Opt_rootdir, "rootdir=%u"}, |
396 | {Opt_utf8, "utf8"}, | 396 | {Opt_utf8, "utf8"}, |
397 | {Opt_iocharset, "iocharset=%s"}, | 397 | {Opt_iocharset, "iocharset=%s"}, |
398 | {Opt_fmode, "mode=%o"}, | ||
399 | {Opt_dmode, "dmode=%o"}, | ||
398 | {Opt_err, NULL} | 400 | {Opt_err, NULL} |
399 | }; | 401 | }; |
400 | 402 | ||
@@ -405,7 +407,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt, | |||
405 | int option; | 407 | int option; |
406 | 408 | ||
407 | uopt->novrs = 0; | 409 | uopt->novrs = 0; |
408 | uopt->blocksize = UDF_DEFAULT_BLOCKSIZE; | ||
409 | uopt->partition = 0xFFFF; | 410 | uopt->partition = 0xFFFF; |
410 | uopt->session = 0xFFFFFFFF; | 411 | uopt->session = 0xFFFFFFFF; |
411 | uopt->lastblock = 0; | 412 | uopt->lastblock = 0; |
@@ -428,10 +429,12 @@ static int udf_parse_options(char *options, struct udf_options *uopt, | |||
428 | switch (token) { | 429 | switch (token) { |
429 | case Opt_novrs: | 430 | case Opt_novrs: |
430 | uopt->novrs = 1; | 431 | uopt->novrs = 1; |
432 | break; | ||
431 | case Opt_bs: | 433 | case Opt_bs: |
432 | if (match_int(&args[0], &option)) | 434 | if (match_int(&args[0], &option)) |
433 | return 0; | 435 | return 0; |
434 | uopt->blocksize = option; | 436 | uopt->blocksize = option; |
437 | uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET); | ||
435 | break; | 438 | break; |
436 | case Opt_unhide: | 439 | case Opt_unhide: |
437 | uopt->flags |= (1 << UDF_FLAG_UNHIDE); | 440 | uopt->flags |= (1 << UDF_FLAG_UNHIDE); |
@@ -531,6 +534,16 @@ static int udf_parse_options(char *options, struct udf_options *uopt, | |||
531 | case Opt_gforget: | 534 | case Opt_gforget: |
532 | uopt->flags |= (1 << UDF_FLAG_GID_FORGET); | 535 | uopt->flags |= (1 << UDF_FLAG_GID_FORGET); |
533 | break; | 536 | break; |
537 | case Opt_fmode: | ||
538 | if (match_octal(args, &option)) | ||
539 | return 0; | ||
540 | uopt->fmode = option & 0777; | ||
541 | break; | ||
542 | case Opt_dmode: | ||
543 | if (match_octal(args, &option)) | ||
544 | return 0; | ||
545 | uopt->dmode = option & 0777; | ||
546 | break; | ||
534 | default: | 547 | default: |
535 | printk(KERN_ERR "udf: bad mount option \"%s\" " | 548 | printk(KERN_ERR "udf: bad mount option \"%s\" " |
536 | "or missing value\n", p); | 549 | "or missing value\n", p); |
@@ -540,17 +553,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt, | |||
540 | return 1; | 553 | return 1; |
541 | } | 554 | } |
542 | 555 | ||
543 | static void udf_write_super(struct super_block *sb) | ||
544 | { | ||
545 | lock_kernel(); | ||
546 | |||
547 | if (!(sb->s_flags & MS_RDONLY)) | ||
548 | udf_open_lvid(sb); | ||
549 | sb->s_dirt = 0; | ||
550 | |||
551 | unlock_kernel(); | ||
552 | } | ||
553 | |||
554 | static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | 556 | static int udf_remount_fs(struct super_block *sb, int *flags, char *options) |
555 | { | 557 | { |
556 | struct udf_options uopt; | 558 | struct udf_options uopt; |
@@ -560,6 +562,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
560 | uopt.uid = sbi->s_uid; | 562 | uopt.uid = sbi->s_uid; |
561 | uopt.gid = sbi->s_gid; | 563 | uopt.gid = sbi->s_gid; |
562 | uopt.umask = sbi->s_umask; | 564 | uopt.umask = sbi->s_umask; |
565 | uopt.fmode = sbi->s_fmode; | ||
566 | uopt.dmode = sbi->s_dmode; | ||
563 | 567 | ||
564 | if (!udf_parse_options(options, &uopt, true)) | 568 | if (!udf_parse_options(options, &uopt, true)) |
565 | return -EINVAL; | 569 | return -EINVAL; |
@@ -568,6 +572,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
568 | sbi->s_uid = uopt.uid; | 572 | sbi->s_uid = uopt.uid; |
569 | sbi->s_gid = uopt.gid; | 573 | sbi->s_gid = uopt.gid; |
570 | sbi->s_umask = uopt.umask; | 574 | sbi->s_umask = uopt.umask; |
575 | sbi->s_fmode = uopt.fmode; | ||
576 | sbi->s_dmode = uopt.dmode; | ||
571 | 577 | ||
572 | if (sbi->s_lvid_bh) { | 578 | if (sbi->s_lvid_bh) { |
573 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); | 579 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); |
@@ -585,22 +591,19 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
585 | return 0; | 591 | return 0; |
586 | } | 592 | } |
587 | 593 | ||
588 | static int udf_vrs(struct super_block *sb, int silent) | 594 | /* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ |
595 | /* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ | ||
596 | static loff_t udf_check_vsd(struct super_block *sb) | ||
589 | { | 597 | { |
590 | struct volStructDesc *vsd = NULL; | 598 | struct volStructDesc *vsd = NULL; |
591 | loff_t sector = 32768; | 599 | loff_t sector = 32768; |
592 | int sectorsize; | 600 | int sectorsize; |
593 | struct buffer_head *bh = NULL; | 601 | struct buffer_head *bh = NULL; |
594 | int iso9660 = 0; | ||
595 | int nsr02 = 0; | 602 | int nsr02 = 0; |
596 | int nsr03 = 0; | 603 | int nsr03 = 0; |
597 | struct udf_sb_info *sbi; | 604 | struct udf_sb_info *sbi; |
598 | 605 | ||
599 | /* Block size must be a multiple of 512 */ | ||
600 | if (sb->s_blocksize & 511) | ||
601 | return 0; | ||
602 | sbi = UDF_SB(sb); | 606 | sbi = UDF_SB(sb); |
603 | |||
604 | if (sb->s_blocksize < sizeof(struct volStructDesc)) | 607 | if (sb->s_blocksize < sizeof(struct volStructDesc)) |
605 | sectorsize = sizeof(struct volStructDesc); | 608 | sectorsize = sizeof(struct volStructDesc); |
606 | else | 609 | else |
@@ -627,7 +630,6 @@ static int udf_vrs(struct super_block *sb, int silent) | |||
627 | break; | 630 | break; |
628 | } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, | 631 | } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, |
629 | VSD_STD_ID_LEN)) { | 632 | VSD_STD_ID_LEN)) { |
630 | iso9660 = sector; | ||
631 | switch (vsd->structType) { | 633 | switch (vsd->structType) { |
632 | case 0: | 634 | case 0: |
633 | udf_debug("ISO9660 Boot Record found\n"); | 635 | udf_debug("ISO9660 Boot Record found\n"); |
@@ -679,139 +681,9 @@ static int udf_vrs(struct super_block *sb, int silent) | |||
679 | return 0; | 681 | return 0; |
680 | } | 682 | } |
681 | 683 | ||
682 | /* | ||
683 | * Check whether there is an anchor block in the given block | ||
684 | */ | ||
685 | static int udf_check_anchor_block(struct super_block *sb, sector_t block) | ||
686 | { | ||
687 | struct buffer_head *bh; | ||
688 | uint16_t ident; | ||
689 | |||
690 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && | ||
691 | udf_fixed_to_variable(block) >= | ||
692 | sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) | ||
693 | return 0; | ||
694 | |||
695 | bh = udf_read_tagged(sb, block, block, &ident); | ||
696 | if (!bh) | ||
697 | return 0; | ||
698 | brelse(bh); | ||
699 | |||
700 | return ident == TAG_IDENT_AVDP; | ||
701 | } | ||
702 | |||
703 | /* Search for an anchor volume descriptor pointer */ | ||
704 | static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) | ||
705 | { | ||
706 | sector_t last[6]; | ||
707 | int i; | ||
708 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
709 | |||
710 | last[0] = lastblock; | ||
711 | last[1] = last[0] - 1; | ||
712 | last[2] = last[0] + 1; | ||
713 | last[3] = last[0] - 2; | ||
714 | last[4] = last[0] - 150; | ||
715 | last[5] = last[0] - 152; | ||
716 | |||
717 | /* according to spec, anchor is in either: | ||
718 | * block 256 | ||
719 | * lastblock-256 | ||
720 | * lastblock | ||
721 | * however, if the disc isn't closed, it could be 512 */ | ||
722 | |||
723 | for (i = 0; i < ARRAY_SIZE(last); i++) { | ||
724 | if (last[i] < 0) | ||
725 | continue; | ||
726 | if (last[i] >= sb->s_bdev->bd_inode->i_size >> | ||
727 | sb->s_blocksize_bits) | ||
728 | continue; | ||
729 | |||
730 | if (udf_check_anchor_block(sb, last[i])) { | ||
731 | sbi->s_anchor[0] = last[i]; | ||
732 | sbi->s_anchor[1] = last[i] - 256; | ||
733 | return last[i]; | ||
734 | } | ||
735 | |||
736 | if (last[i] < 256) | ||
737 | continue; | ||
738 | |||
739 | if (udf_check_anchor_block(sb, last[i] - 256)) { | ||
740 | sbi->s_anchor[1] = last[i] - 256; | ||
741 | return last[i]; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | if (udf_check_anchor_block(sb, sbi->s_session + 256)) { | ||
746 | sbi->s_anchor[0] = sbi->s_session + 256; | ||
747 | return last[0]; | ||
748 | } | ||
749 | if (udf_check_anchor_block(sb, sbi->s_session + 512)) { | ||
750 | sbi->s_anchor[0] = sbi->s_session + 512; | ||
751 | return last[0]; | ||
752 | } | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | /* | ||
757 | * Find an anchor volume descriptor. The function expects sbi->s_lastblock to | ||
758 | * be the last block on the media. | ||
759 | * | ||
760 | * Return 1 if not found, 0 if ok | ||
761 | * | ||
762 | */ | ||
763 | static void udf_find_anchor(struct super_block *sb) | ||
764 | { | ||
765 | sector_t lastblock; | ||
766 | struct buffer_head *bh = NULL; | ||
767 | uint16_t ident; | ||
768 | int i; | ||
769 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
770 | |||
771 | lastblock = udf_scan_anchors(sb, sbi->s_last_block); | ||
772 | if (lastblock) | ||
773 | goto check_anchor; | ||
774 | |||
775 | /* No anchor found? Try VARCONV conversion of block numbers */ | ||
776 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
777 | /* Firstly, we try to not convert number of the last block */ | ||
778 | lastblock = udf_scan_anchors(sb, | ||
779 | udf_variable_to_fixed(sbi->s_last_block)); | ||
780 | if (lastblock) | ||
781 | goto check_anchor; | ||
782 | |||
783 | /* Secondly, we try with converted number of the last block */ | ||
784 | lastblock = udf_scan_anchors(sb, sbi->s_last_block); | ||
785 | if (!lastblock) { | ||
786 | /* VARCONV didn't help. Clear it. */ | ||
787 | UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); | ||
788 | } | ||
789 | |||
790 | check_anchor: | ||
791 | /* | ||
792 | * Check located anchors and the anchor block supplied via | ||
793 | * mount options | ||
794 | */ | ||
795 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { | ||
796 | if (!sbi->s_anchor[i]) | ||
797 | continue; | ||
798 | bh = udf_read_tagged(sb, sbi->s_anchor[i], | ||
799 | sbi->s_anchor[i], &ident); | ||
800 | if (!bh) | ||
801 | sbi->s_anchor[i] = 0; | ||
802 | else { | ||
803 | brelse(bh); | ||
804 | if (ident != TAG_IDENT_AVDP) | ||
805 | sbi->s_anchor[i] = 0; | ||
806 | } | ||
807 | } | ||
808 | |||
809 | sbi->s_last_block = lastblock; | ||
810 | } | ||
811 | |||
812 | static int udf_find_fileset(struct super_block *sb, | 684 | static int udf_find_fileset(struct super_block *sb, |
813 | kernel_lb_addr *fileset, | 685 | struct kernel_lb_addr *fileset, |
814 | kernel_lb_addr *root) | 686 | struct kernel_lb_addr *root) |
815 | { | 687 | { |
816 | struct buffer_head *bh = NULL; | 688 | struct buffer_head *bh = NULL; |
817 | long lastblock; | 689 | long lastblock; |
@@ -820,7 +692,7 @@ static int udf_find_fileset(struct super_block *sb, | |||
820 | 692 | ||
821 | if (fileset->logicalBlockNum != 0xFFFFFFFF || | 693 | if (fileset->logicalBlockNum != 0xFFFFFFFF || |
822 | fileset->partitionReferenceNum != 0xFFFF) { | 694 | fileset->partitionReferenceNum != 0xFFFF) { |
823 | bh = udf_read_ptagged(sb, *fileset, 0, &ident); | 695 | bh = udf_read_ptagged(sb, fileset, 0, &ident); |
824 | 696 | ||
825 | if (!bh) { | 697 | if (!bh) { |
826 | return 1; | 698 | return 1; |
@@ -834,7 +706,7 @@ static int udf_find_fileset(struct super_block *sb, | |||
834 | sbi = UDF_SB(sb); | 706 | sbi = UDF_SB(sb); |
835 | if (!bh) { | 707 | if (!bh) { |
836 | /* Search backwards through the partitions */ | 708 | /* Search backwards through the partitions */ |
837 | kernel_lb_addr newfileset; | 709 | struct kernel_lb_addr newfileset; |
838 | 710 | ||
839 | /* --> cvg: FIXME - is it reasonable? */ | 711 | /* --> cvg: FIXME - is it reasonable? */ |
840 | return 1; | 712 | return 1; |
@@ -850,7 +722,7 @@ static int udf_find_fileset(struct super_block *sb, | |||
850 | newfileset.logicalBlockNum = 0; | 722 | newfileset.logicalBlockNum = 0; |
851 | 723 | ||
852 | do { | 724 | do { |
853 | bh = udf_read_ptagged(sb, newfileset, 0, | 725 | bh = udf_read_ptagged(sb, &newfileset, 0, |
854 | &ident); | 726 | &ident); |
855 | if (!bh) { | 727 | if (!bh) { |
856 | newfileset.logicalBlockNum++; | 728 | newfileset.logicalBlockNum++; |
@@ -902,14 +774,23 @@ static int udf_find_fileset(struct super_block *sb, | |||
902 | static int udf_load_pvoldesc(struct super_block *sb, sector_t block) | 774 | static int udf_load_pvoldesc(struct super_block *sb, sector_t block) |
903 | { | 775 | { |
904 | struct primaryVolDesc *pvoldesc; | 776 | struct primaryVolDesc *pvoldesc; |
905 | struct ustr instr; | 777 | struct ustr *instr, *outstr; |
906 | struct ustr outstr; | ||
907 | struct buffer_head *bh; | 778 | struct buffer_head *bh; |
908 | uint16_t ident; | 779 | uint16_t ident; |
780 | int ret = 1; | ||
781 | |||
782 | instr = kmalloc(sizeof(struct ustr), GFP_NOFS); | ||
783 | if (!instr) | ||
784 | return 1; | ||
785 | |||
786 | outstr = kmalloc(sizeof(struct ustr), GFP_NOFS); | ||
787 | if (!outstr) | ||
788 | goto out1; | ||
909 | 789 | ||
910 | bh = udf_read_tagged(sb, block, block, &ident); | 790 | bh = udf_read_tagged(sb, block, block, &ident); |
911 | if (!bh) | 791 | if (!bh) |
912 | return 1; | 792 | goto out2; |
793 | |||
913 | BUG_ON(ident != TAG_IDENT_PVD); | 794 | BUG_ON(ident != TAG_IDENT_PVD); |
914 | 795 | ||
915 | pvoldesc = (struct primaryVolDesc *)bh->b_data; | 796 | pvoldesc = (struct primaryVolDesc *)bh->b_data; |
@@ -917,7 +798,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) | |||
917 | if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, | 798 | if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, |
918 | pvoldesc->recordingDateAndTime)) { | 799 | pvoldesc->recordingDateAndTime)) { |
919 | #ifdef UDFFS_DEBUG | 800 | #ifdef UDFFS_DEBUG |
920 | timestamp *ts = &pvoldesc->recordingDateAndTime; | 801 | struct timestamp *ts = &pvoldesc->recordingDateAndTime; |
921 | udf_debug("recording time %04u/%02u/%02u" | 802 | udf_debug("recording time %04u/%02u/%02u" |
922 | " %02u:%02u (%x)\n", | 803 | " %02u:%02u (%x)\n", |
923 | le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, | 804 | le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, |
@@ -925,20 +806,25 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) | |||
925 | #endif | 806 | #endif |
926 | } | 807 | } |
927 | 808 | ||
928 | if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) | 809 | if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) |
929 | if (udf_CS0toUTF8(&outstr, &instr)) { | 810 | if (udf_CS0toUTF8(outstr, instr)) { |
930 | strncpy(UDF_SB(sb)->s_volume_ident, outstr.u_name, | 811 | strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name, |
931 | outstr.u_len > 31 ? 31 : outstr.u_len); | 812 | outstr->u_len > 31 ? 31 : outstr->u_len); |
932 | udf_debug("volIdent[] = '%s'\n", | 813 | udf_debug("volIdent[] = '%s'\n", |
933 | UDF_SB(sb)->s_volume_ident); | 814 | UDF_SB(sb)->s_volume_ident); |
934 | } | 815 | } |
935 | 816 | ||
936 | if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) | 817 | if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128)) |
937 | if (udf_CS0toUTF8(&outstr, &instr)) | 818 | if (udf_CS0toUTF8(outstr, instr)) |
938 | udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); | 819 | udf_debug("volSetIdent[] = '%s'\n", outstr->u_name); |
939 | 820 | ||
940 | brelse(bh); | 821 | brelse(bh); |
941 | return 0; | 822 | ret = 0; |
823 | out2: | ||
824 | kfree(outstr); | ||
825 | out1: | ||
826 | kfree(instr); | ||
827 | return ret; | ||
942 | } | 828 | } |
943 | 829 | ||
944 | static int udf_load_metadata_files(struct super_block *sb, int partition) | 830 | static int udf_load_metadata_files(struct super_block *sb, int partition) |
@@ -946,7 +832,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) | |||
946 | struct udf_sb_info *sbi = UDF_SB(sb); | 832 | struct udf_sb_info *sbi = UDF_SB(sb); |
947 | struct udf_part_map *map; | 833 | struct udf_part_map *map; |
948 | struct udf_meta_data *mdata; | 834 | struct udf_meta_data *mdata; |
949 | kernel_lb_addr addr; | 835 | struct kernel_lb_addr addr; |
950 | int fe_error = 0; | 836 | int fe_error = 0; |
951 | 837 | ||
952 | map = &sbi->s_partmaps[partition]; | 838 | map = &sbi->s_partmaps[partition]; |
@@ -959,7 +845,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) | |||
959 | udf_debug("Metadata file location: block = %d part = %d\n", | 845 | udf_debug("Metadata file location: block = %d part = %d\n", |
960 | addr.logicalBlockNum, addr.partitionReferenceNum); | 846 | addr.logicalBlockNum, addr.partitionReferenceNum); |
961 | 847 | ||
962 | mdata->s_metadata_fe = udf_iget(sb, addr); | 848 | mdata->s_metadata_fe = udf_iget(sb, &addr); |
963 | 849 | ||
964 | if (mdata->s_metadata_fe == NULL) { | 850 | if (mdata->s_metadata_fe == NULL) { |
965 | udf_warning(sb, __func__, "metadata inode efe not found, " | 851 | udf_warning(sb, __func__, "metadata inode efe not found, " |
@@ -981,7 +867,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) | |||
981 | udf_debug("Mirror metadata file location: block = %d part = %d\n", | 867 | udf_debug("Mirror metadata file location: block = %d part = %d\n", |
982 | addr.logicalBlockNum, addr.partitionReferenceNum); | 868 | addr.logicalBlockNum, addr.partitionReferenceNum); |
983 | 869 | ||
984 | mdata->s_mirror_fe = udf_iget(sb, addr); | 870 | mdata->s_mirror_fe = udf_iget(sb, &addr); |
985 | 871 | ||
986 | if (mdata->s_mirror_fe == NULL) { | 872 | if (mdata->s_mirror_fe == NULL) { |
987 | if (fe_error) { | 873 | if (fe_error) { |
@@ -1013,7 +899,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) | |||
1013 | udf_debug("Bitmap file location: block = %d part = %d\n", | 899 | udf_debug("Bitmap file location: block = %d part = %d\n", |
1014 | addr.logicalBlockNum, addr.partitionReferenceNum); | 900 | addr.logicalBlockNum, addr.partitionReferenceNum); |
1015 | 901 | ||
1016 | mdata->s_bitmap_fe = udf_iget(sb, addr); | 902 | mdata->s_bitmap_fe = udf_iget(sb, &addr); |
1017 | 903 | ||
1018 | if (mdata->s_bitmap_fe == NULL) { | 904 | if (mdata->s_bitmap_fe == NULL) { |
1019 | if (sb->s_flags & MS_RDONLY) | 905 | if (sb->s_flags & MS_RDONLY) |
@@ -1037,7 +923,7 @@ error_exit: | |||
1037 | } | 923 | } |
1038 | 924 | ||
1039 | static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, | 925 | static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, |
1040 | kernel_lb_addr *root) | 926 | struct kernel_lb_addr *root) |
1041 | { | 927 | { |
1042 | struct fileSetDesc *fset; | 928 | struct fileSetDesc *fset; |
1043 | 929 | ||
@@ -1119,13 +1005,13 @@ static int udf_fill_partdesc_info(struct super_block *sb, | |||
1119 | 1005 | ||
1120 | phd = (struct partitionHeaderDesc *)p->partitionContentsUse; | 1006 | phd = (struct partitionHeaderDesc *)p->partitionContentsUse; |
1121 | if (phd->unallocSpaceTable.extLength) { | 1007 | if (phd->unallocSpaceTable.extLength) { |
1122 | kernel_lb_addr loc = { | 1008 | struct kernel_lb_addr loc = { |
1123 | .logicalBlockNum = le32_to_cpu( | 1009 | .logicalBlockNum = le32_to_cpu( |
1124 | phd->unallocSpaceTable.extPosition), | 1010 | phd->unallocSpaceTable.extPosition), |
1125 | .partitionReferenceNum = p_index, | 1011 | .partitionReferenceNum = p_index, |
1126 | }; | 1012 | }; |
1127 | 1013 | ||
1128 | map->s_uspace.s_table = udf_iget(sb, loc); | 1014 | map->s_uspace.s_table = udf_iget(sb, &loc); |
1129 | if (!map->s_uspace.s_table) { | 1015 | if (!map->s_uspace.s_table) { |
1130 | udf_debug("cannot load unallocSpaceTable (part %d)\n", | 1016 | udf_debug("cannot load unallocSpaceTable (part %d)\n", |
1131 | p_index); | 1017 | p_index); |
@@ -1154,13 +1040,13 @@ static int udf_fill_partdesc_info(struct super_block *sb, | |||
1154 | udf_debug("partitionIntegrityTable (part %d)\n", p_index); | 1040 | udf_debug("partitionIntegrityTable (part %d)\n", p_index); |
1155 | 1041 | ||
1156 | if (phd->freedSpaceTable.extLength) { | 1042 | if (phd->freedSpaceTable.extLength) { |
1157 | kernel_lb_addr loc = { | 1043 | struct kernel_lb_addr loc = { |
1158 | .logicalBlockNum = le32_to_cpu( | 1044 | .logicalBlockNum = le32_to_cpu( |
1159 | phd->freedSpaceTable.extPosition), | 1045 | phd->freedSpaceTable.extPosition), |
1160 | .partitionReferenceNum = p_index, | 1046 | .partitionReferenceNum = p_index, |
1161 | }; | 1047 | }; |
1162 | 1048 | ||
1163 | map->s_fspace.s_table = udf_iget(sb, loc); | 1049 | map->s_fspace.s_table = udf_iget(sb, &loc); |
1164 | if (!map->s_fspace.s_table) { | 1050 | if (!map->s_fspace.s_table) { |
1165 | udf_debug("cannot load freedSpaceTable (part %d)\n", | 1051 | udf_debug("cannot load freedSpaceTable (part %d)\n", |
1166 | p_index); | 1052 | p_index); |
@@ -1192,7 +1078,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) | |||
1192 | { | 1078 | { |
1193 | struct udf_sb_info *sbi = UDF_SB(sb); | 1079 | struct udf_sb_info *sbi = UDF_SB(sb); |
1194 | struct udf_part_map *map = &sbi->s_partmaps[p_index]; | 1080 | struct udf_part_map *map = &sbi->s_partmaps[p_index]; |
1195 | kernel_lb_addr ino; | 1081 | struct kernel_lb_addr ino; |
1196 | struct buffer_head *bh = NULL; | 1082 | struct buffer_head *bh = NULL; |
1197 | struct udf_inode_info *vati; | 1083 | struct udf_inode_info *vati; |
1198 | uint32_t pos; | 1084 | uint32_t pos; |
@@ -1201,7 +1087,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) | |||
1201 | /* VAT file entry is in the last recorded block */ | 1087 | /* VAT file entry is in the last recorded block */ |
1202 | ino.partitionReferenceNum = type1_index; | 1088 | ino.partitionReferenceNum = type1_index; |
1203 | ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root; | 1089 | ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root; |
1204 | sbi->s_vat_inode = udf_iget(sb, ino); | 1090 | sbi->s_vat_inode = udf_iget(sb, &ino); |
1205 | if (!sbi->s_vat_inode) | 1091 | if (!sbi->s_vat_inode) |
1206 | return 1; | 1092 | return 1; |
1207 | 1093 | ||
@@ -1322,7 +1208,7 @@ out_bh: | |||
1322 | } | 1208 | } |
1323 | 1209 | ||
1324 | static int udf_load_logicalvol(struct super_block *sb, sector_t block, | 1210 | static int udf_load_logicalvol(struct super_block *sb, sector_t block, |
1325 | kernel_lb_addr *fileset) | 1211 | struct kernel_lb_addr *fileset) |
1326 | { | 1212 | { |
1327 | struct logicalVolDesc *lvd; | 1213 | struct logicalVolDesc *lvd; |
1328 | int i, j, offset; | 1214 | int i, j, offset; |
@@ -1471,7 +1357,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1471 | } | 1357 | } |
1472 | 1358 | ||
1473 | if (fileset) { | 1359 | if (fileset) { |
1474 | long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]); | 1360 | struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]); |
1475 | 1361 | ||
1476 | *fileset = lelb_to_cpu(la->extLocation); | 1362 | *fileset = lelb_to_cpu(la->extLocation); |
1477 | udf_debug("FileSet found in LogicalVolDesc at block=%d, " | 1363 | udf_debug("FileSet found in LogicalVolDesc at block=%d, " |
@@ -1490,7 +1376,7 @@ out_bh: | |||
1490 | * udf_load_logicalvolint | 1376 | * udf_load_logicalvolint |
1491 | * | 1377 | * |
1492 | */ | 1378 | */ |
1493 | static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) | 1379 | static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc) |
1494 | { | 1380 | { |
1495 | struct buffer_head *bh = NULL; | 1381 | struct buffer_head *bh = NULL; |
1496 | uint16_t ident; | 1382 | uint16_t ident; |
@@ -1533,7 +1419,7 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) | |||
1533 | * Written, tested, and released. | 1419 | * Written, tested, and released. |
1534 | */ | 1420 | */ |
1535 | static noinline int udf_process_sequence(struct super_block *sb, long block, | 1421 | static noinline int udf_process_sequence(struct super_block *sb, long block, |
1536 | long lastblock, kernel_lb_addr *fileset) | 1422 | long lastblock, struct kernel_lb_addr *fileset) |
1537 | { | 1423 | { |
1538 | struct buffer_head *bh = NULL; | 1424 | struct buffer_head *bh = NULL; |
1539 | struct udf_vds_record vds[VDS_POS_LENGTH]; | 1425 | struct udf_vds_record vds[VDS_POS_LENGTH]; |
@@ -1655,85 +1541,199 @@ static noinline int udf_process_sequence(struct super_block *sb, long block, | |||
1655 | return 0; | 1541 | return 0; |
1656 | } | 1542 | } |
1657 | 1543 | ||
1544 | static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh, | ||
1545 | struct kernel_lb_addr *fileset) | ||
1546 | { | ||
1547 | struct anchorVolDescPtr *anchor; | ||
1548 | long main_s, main_e, reserve_s, reserve_e; | ||
1549 | struct udf_sb_info *sbi; | ||
1550 | |||
1551 | sbi = UDF_SB(sb); | ||
1552 | anchor = (struct anchorVolDescPtr *)bh->b_data; | ||
1553 | |||
1554 | /* Locate the main sequence */ | ||
1555 | main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation); | ||
1556 | main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength); | ||
1557 | main_e = main_e >> sb->s_blocksize_bits; | ||
1558 | main_e += main_s; | ||
1559 | |||
1560 | /* Locate the reserve sequence */ | ||
1561 | reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation); | ||
1562 | reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength); | ||
1563 | reserve_e = reserve_e >> sb->s_blocksize_bits; | ||
1564 | reserve_e += reserve_s; | ||
1565 | |||
1566 | /* Process the main & reserve sequences */ | ||
1567 | /* responsible for finding the PartitionDesc(s) */ | ||
1568 | if (!udf_process_sequence(sb, main_s, main_e, fileset)) | ||
1569 | return 1; | ||
1570 | return !udf_process_sequence(sb, reserve_s, reserve_e, fileset); | ||
1571 | } | ||
1572 | |||
1658 | /* | 1573 | /* |
1659 | * udf_check_valid() | 1574 | * Check whether there is an anchor block in the given block and |
1575 | * load Volume Descriptor Sequence if so. | ||
1660 | */ | 1576 | */ |
1661 | static int udf_check_valid(struct super_block *sb, int novrs, int silent) | 1577 | static int udf_check_anchor_block(struct super_block *sb, sector_t block, |
1578 | struct kernel_lb_addr *fileset) | ||
1662 | { | 1579 | { |
1663 | long block; | 1580 | struct buffer_head *bh; |
1664 | struct udf_sb_info *sbi = UDF_SB(sb); | 1581 | uint16_t ident; |
1582 | int ret; | ||
1665 | 1583 | ||
1666 | if (novrs) { | 1584 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && |
1667 | udf_debug("Validity check skipped because of novrs option\n"); | 1585 | udf_fixed_to_variable(block) >= |
1586 | sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) | ||
1587 | return 0; | ||
1588 | |||
1589 | bh = udf_read_tagged(sb, block, block, &ident); | ||
1590 | if (!bh) | ||
1591 | return 0; | ||
1592 | if (ident != TAG_IDENT_AVDP) { | ||
1593 | brelse(bh); | ||
1668 | return 0; | 1594 | return 0; |
1669 | } | 1595 | } |
1670 | /* Check that it is NSR02 compliant */ | 1596 | ret = udf_load_sequence(sb, bh, fileset); |
1671 | /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ | 1597 | brelse(bh); |
1672 | block = udf_vrs(sb, silent); | 1598 | return ret; |
1673 | if (block == -1) | ||
1674 | udf_debug("Failed to read byte 32768. Assuming open " | ||
1675 | "disc. Skipping validity check\n"); | ||
1676 | if (block && !sbi->s_last_block) | ||
1677 | sbi->s_last_block = udf_get_last_block(sb); | ||
1678 | return !block; | ||
1679 | } | 1599 | } |
1680 | 1600 | ||
1681 | static int udf_load_sequence(struct super_block *sb, kernel_lb_addr *fileset) | 1601 | /* Search for an anchor volume descriptor pointer */ |
1602 | static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock, | ||
1603 | struct kernel_lb_addr *fileset) | ||
1682 | { | 1604 | { |
1683 | struct anchorVolDescPtr *anchor; | 1605 | sector_t last[6]; |
1684 | uint16_t ident; | ||
1685 | struct buffer_head *bh; | ||
1686 | long main_s, main_e, reserve_s, reserve_e; | ||
1687 | int i; | 1606 | int i; |
1688 | struct udf_sb_info *sbi; | 1607 | struct udf_sb_info *sbi = UDF_SB(sb); |
1689 | 1608 | int last_count = 0; | |
1690 | if (!sb) | ||
1691 | return 1; | ||
1692 | sbi = UDF_SB(sb); | ||
1693 | 1609 | ||
1694 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { | 1610 | /* First try user provided anchor */ |
1695 | if (!sbi->s_anchor[i]) | 1611 | if (sbi->s_anchor) { |
1612 | if (udf_check_anchor_block(sb, sbi->s_anchor, fileset)) | ||
1613 | return lastblock; | ||
1614 | } | ||
1615 | /* | ||
1616 | * according to spec, anchor is in either: | ||
1617 | * block 256 | ||
1618 | * lastblock-256 | ||
1619 | * lastblock | ||
1620 | * however, if the disc isn't closed, it could be 512. | ||
1621 | */ | ||
1622 | if (udf_check_anchor_block(sb, sbi->s_session + 256, fileset)) | ||
1623 | return lastblock; | ||
1624 | /* | ||
1625 | * The trouble is which block is the last one. Drives often misreport | ||
1626 | * this so we try various possibilities. | ||
1627 | */ | ||
1628 | last[last_count++] = lastblock; | ||
1629 | if (lastblock >= 1) | ||
1630 | last[last_count++] = lastblock - 1; | ||
1631 | last[last_count++] = lastblock + 1; | ||
1632 | if (lastblock >= 2) | ||
1633 | last[last_count++] = lastblock - 2; | ||
1634 | if (lastblock >= 150) | ||
1635 | last[last_count++] = lastblock - 150; | ||
1636 | if (lastblock >= 152) | ||
1637 | last[last_count++] = lastblock - 152; | ||
1638 | |||
1639 | for (i = 0; i < last_count; i++) { | ||
1640 | if (last[i] >= sb->s_bdev->bd_inode->i_size >> | ||
1641 | sb->s_blocksize_bits) | ||
1696 | continue; | 1642 | continue; |
1697 | 1643 | if (udf_check_anchor_block(sb, last[i], fileset)) | |
1698 | bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i], | 1644 | return last[i]; |
1699 | &ident); | 1645 | if (last[i] < 256) |
1700 | if (!bh) | ||
1701 | continue; | 1646 | continue; |
1647 | if (udf_check_anchor_block(sb, last[i] - 256, fileset)) | ||
1648 | return last[i]; | ||
1649 | } | ||
1702 | 1650 | ||
1703 | anchor = (struct anchorVolDescPtr *)bh->b_data; | 1651 | /* Finally try block 512 in case media is open */ |
1652 | if (udf_check_anchor_block(sb, sbi->s_session + 512, fileset)) | ||
1653 | return last[0]; | ||
1654 | return 0; | ||
1655 | } | ||
1704 | 1656 | ||
1705 | /* Locate the main sequence */ | 1657 | /* |
1706 | main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation); | 1658 | * Find an anchor volume descriptor and load Volume Descriptor Sequence from |
1707 | main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength); | 1659 | * area specified by it. The function expects sbi->s_lastblock to be the last |
1708 | main_e = main_e >> sb->s_blocksize_bits; | 1660 | * block on the media. |
1709 | main_e += main_s; | 1661 | * |
1662 | * Return 1 if ok, 0 if not found. | ||
1663 | * | ||
1664 | */ | ||
1665 | static int udf_find_anchor(struct super_block *sb, | ||
1666 | struct kernel_lb_addr *fileset) | ||
1667 | { | ||
1668 | sector_t lastblock; | ||
1669 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1710 | 1670 | ||
1711 | /* Locate the reserve sequence */ | 1671 | lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset); |
1712 | reserve_s = le32_to_cpu( | 1672 | if (lastblock) |
1713 | anchor->reserveVolDescSeqExt.extLocation); | 1673 | goto out; |
1714 | reserve_e = le32_to_cpu( | ||
1715 | anchor->reserveVolDescSeqExt.extLength); | ||
1716 | reserve_e = reserve_e >> sb->s_blocksize_bits; | ||
1717 | reserve_e += reserve_s; | ||
1718 | 1674 | ||
1719 | brelse(bh); | 1675 | /* No anchor found? Try VARCONV conversion of block numbers */ |
1676 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
1677 | /* Firstly, we try to not convert number of the last block */ | ||
1678 | lastblock = udf_scan_anchors(sb, | ||
1679 | udf_variable_to_fixed(sbi->s_last_block), | ||
1680 | fileset); | ||
1681 | if (lastblock) | ||
1682 | goto out; | ||
1720 | 1683 | ||
1721 | /* Process the main & reserve sequences */ | 1684 | /* Secondly, we try with converted number of the last block */ |
1722 | /* responsible for finding the PartitionDesc(s) */ | 1685 | lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset); |
1723 | if (!(udf_process_sequence(sb, main_s, main_e, | 1686 | if (!lastblock) { |
1724 | fileset) && | 1687 | /* VARCONV didn't help. Clear it. */ |
1725 | udf_process_sequence(sb, reserve_s, reserve_e, | 1688 | UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); |
1726 | fileset))) | 1689 | return 0; |
1727 | break; | ||
1728 | } | 1690 | } |
1691 | out: | ||
1692 | sbi->s_last_block = lastblock; | ||
1693 | return 1; | ||
1694 | } | ||
1729 | 1695 | ||
1730 | if (i == ARRAY_SIZE(sbi->s_anchor)) { | 1696 | /* |
1731 | udf_debug("No Anchor block found\n"); | 1697 | * Check Volume Structure Descriptor, find Anchor block and load Volume |
1732 | return 1; | 1698 | * Descriptor Sequence |
1699 | */ | ||
1700 | static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, | ||
1701 | int silent, struct kernel_lb_addr *fileset) | ||
1702 | { | ||
1703 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1704 | loff_t nsr_off; | ||
1705 | |||
1706 | if (!sb_set_blocksize(sb, uopt->blocksize)) { | ||
1707 | if (!silent) | ||
1708 | printk(KERN_WARNING "UDF-fs: Bad block size\n"); | ||
1709 | return 0; | ||
1710 | } | ||
1711 | sbi->s_last_block = uopt->lastblock; | ||
1712 | if (!uopt->novrs) { | ||
1713 | /* Check that it is NSR02 compliant */ | ||
1714 | nsr_off = udf_check_vsd(sb); | ||
1715 | if (!nsr_off) { | ||
1716 | if (!silent) | ||
1717 | printk(KERN_WARNING "UDF-fs: No VRS found\n"); | ||
1718 | return 0; | ||
1719 | } | ||
1720 | if (nsr_off == -1) | ||
1721 | udf_debug("Failed to read byte 32768. Assuming open " | ||
1722 | "disc. Skipping validity check\n"); | ||
1723 | if (!sbi->s_last_block) | ||
1724 | sbi->s_last_block = udf_get_last_block(sb); | ||
1725 | } else { | ||
1726 | udf_debug("Validity check skipped because of novrs option\n"); | ||
1733 | } | 1727 | } |
1734 | udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]); | ||
1735 | 1728 | ||
1736 | return 0; | 1729 | /* Look for anchor block and load Volume Descriptor Sequence */ |
1730 | sbi->s_anchor = uopt->anchor; | ||
1731 | if (!udf_find_anchor(sb, fileset)) { | ||
1732 | if (!silent) | ||
1733 | printk(KERN_WARNING "UDF-fs: No anchor found\n"); | ||
1734 | return 0; | ||
1735 | } | ||
1736 | return 1; | ||
1737 | } | 1737 | } |
1738 | 1738 | ||
1739 | static void udf_open_lvid(struct super_block *sb) | 1739 | static void udf_open_lvid(struct super_block *sb) |
@@ -1742,9 +1742,9 @@ static void udf_open_lvid(struct super_block *sb) | |||
1742 | struct buffer_head *bh = sbi->s_lvid_bh; | 1742 | struct buffer_head *bh = sbi->s_lvid_bh; |
1743 | struct logicalVolIntegrityDesc *lvid; | 1743 | struct logicalVolIntegrityDesc *lvid; |
1744 | struct logicalVolIntegrityDescImpUse *lvidiu; | 1744 | struct logicalVolIntegrityDescImpUse *lvidiu; |
1745 | |||
1745 | if (!bh) | 1746 | if (!bh) |
1746 | return; | 1747 | return; |
1747 | |||
1748 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1748 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1749 | lvidiu = udf_sb_lvidiu(sbi); | 1749 | lvidiu = udf_sb_lvidiu(sbi); |
1750 | 1750 | ||
@@ -1752,14 +1752,15 @@ static void udf_open_lvid(struct super_block *sb) | |||
1752 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1752 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1753 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, | 1753 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, |
1754 | CURRENT_TIME); | 1754 | CURRENT_TIME); |
1755 | lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; | 1755 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN); |
1756 | 1756 | ||
1757 | lvid->descTag.descCRC = cpu_to_le16( | 1757 | lvid->descTag.descCRC = cpu_to_le16( |
1758 | crc_itu_t(0, (char *)lvid + sizeof(tag), | 1758 | crc_itu_t(0, (char *)lvid + sizeof(struct tag), |
1759 | le16_to_cpu(lvid->descTag.descCRCLength))); | 1759 | le16_to_cpu(lvid->descTag.descCRCLength))); |
1760 | 1760 | ||
1761 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1761 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1762 | mark_buffer_dirty(bh); | 1762 | mark_buffer_dirty(bh); |
1763 | sbi->s_lvid_dirty = 0; | ||
1763 | } | 1764 | } |
1764 | 1765 | ||
1765 | static void udf_close_lvid(struct super_block *sb) | 1766 | static void udf_close_lvid(struct super_block *sb) |
@@ -1773,10 +1774,6 @@ static void udf_close_lvid(struct super_block *sb) | |||
1773 | return; | 1774 | return; |
1774 | 1775 | ||
1775 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1776 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1776 | |||
1777 | if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN) | ||
1778 | return; | ||
1779 | |||
1780 | lvidiu = udf_sb_lvidiu(sbi); | 1777 | lvidiu = udf_sb_lvidiu(sbi); |
1781 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1778 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1782 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1779 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
@@ -1790,11 +1787,12 @@ static void udf_close_lvid(struct super_block *sb) | |||
1790 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); | 1787 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); |
1791 | 1788 | ||
1792 | lvid->descTag.descCRC = cpu_to_le16( | 1789 | lvid->descTag.descCRC = cpu_to_le16( |
1793 | crc_itu_t(0, (char *)lvid + sizeof(tag), | 1790 | crc_itu_t(0, (char *)lvid + sizeof(struct tag), |
1794 | le16_to_cpu(lvid->descTag.descCRCLength))); | 1791 | le16_to_cpu(lvid->descTag.descCRCLength))); |
1795 | 1792 | ||
1796 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1793 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1797 | mark_buffer_dirty(bh); | 1794 | mark_buffer_dirty(bh); |
1795 | sbi->s_lvid_dirty = 0; | ||
1798 | } | 1796 | } |
1799 | 1797 | ||
1800 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | 1798 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) |
@@ -1846,15 +1844,18 @@ static void udf_free_partition(struct udf_part_map *map) | |||
1846 | static int udf_fill_super(struct super_block *sb, void *options, int silent) | 1844 | static int udf_fill_super(struct super_block *sb, void *options, int silent) |
1847 | { | 1845 | { |
1848 | int i; | 1846 | int i; |
1847 | int ret; | ||
1849 | struct inode *inode = NULL; | 1848 | struct inode *inode = NULL; |
1850 | struct udf_options uopt; | 1849 | struct udf_options uopt; |
1851 | kernel_lb_addr rootdir, fileset; | 1850 | struct kernel_lb_addr rootdir, fileset; |
1852 | struct udf_sb_info *sbi; | 1851 | struct udf_sb_info *sbi; |
1853 | 1852 | ||
1854 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); | 1853 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); |
1855 | uopt.uid = -1; | 1854 | uopt.uid = -1; |
1856 | uopt.gid = -1; | 1855 | uopt.gid = -1; |
1857 | uopt.umask = 0; | 1856 | uopt.umask = 0; |
1857 | uopt.fmode = UDF_INVALID_MODE; | ||
1858 | uopt.dmode = UDF_INVALID_MODE; | ||
1858 | 1859 | ||
1859 | sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); | 1860 | sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); |
1860 | if (!sbi) | 1861 | if (!sbi) |
@@ -1892,15 +1893,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1892 | sbi->s_uid = uopt.uid; | 1893 | sbi->s_uid = uopt.uid; |
1893 | sbi->s_gid = uopt.gid; | 1894 | sbi->s_gid = uopt.gid; |
1894 | sbi->s_umask = uopt.umask; | 1895 | sbi->s_umask = uopt.umask; |
1896 | sbi->s_fmode = uopt.fmode; | ||
1897 | sbi->s_dmode = uopt.dmode; | ||
1895 | sbi->s_nls_map = uopt.nls_map; | 1898 | sbi->s_nls_map = uopt.nls_map; |
1896 | 1899 | ||
1897 | /* Set the block size for all transfers */ | ||
1898 | if (!sb_min_blocksize(sb, uopt.blocksize)) { | ||
1899 | udf_debug("Bad block size (%d)\n", uopt.blocksize); | ||
1900 | printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize); | ||
1901 | goto error_out; | ||
1902 | } | ||
1903 | |||
1904 | if (uopt.session == 0xFFFFFFFF) | 1900 | if (uopt.session == 0xFFFFFFFF) |
1905 | sbi->s_session = udf_get_last_session(sb); | 1901 | sbi->s_session = udf_get_last_session(sb); |
1906 | else | 1902 | else |
@@ -1908,18 +1904,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1908 | 1904 | ||
1909 | udf_debug("Multi-session=%d\n", sbi->s_session); | 1905 | udf_debug("Multi-session=%d\n", sbi->s_session); |
1910 | 1906 | ||
1911 | sbi->s_last_block = uopt.lastblock; | ||
1912 | sbi->s_anchor[0] = sbi->s_anchor[1] = 0; | ||
1913 | sbi->s_anchor[2] = uopt.anchor; | ||
1914 | |||
1915 | if (udf_check_valid(sb, uopt.novrs, silent)) { | ||
1916 | /* read volume recognition sequences */ | ||
1917 | printk(KERN_WARNING "UDF-fs: No VRS found\n"); | ||
1918 | goto error_out; | ||
1919 | } | ||
1920 | |||
1921 | udf_find_anchor(sb); | ||
1922 | |||
1923 | /* Fill in the rest of the superblock */ | 1907 | /* Fill in the rest of the superblock */ |
1924 | sb->s_op = &udf_sb_ops; | 1908 | sb->s_op = &udf_sb_ops; |
1925 | sb->s_export_op = &udf_export_ops; | 1909 | sb->s_export_op = &udf_export_ops; |
@@ -1928,7 +1912,21 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1928 | sb->s_magic = UDF_SUPER_MAGIC; | 1912 | sb->s_magic = UDF_SUPER_MAGIC; |
1929 | sb->s_time_gran = 1000; | 1913 | sb->s_time_gran = 1000; |
1930 | 1914 | ||
1931 | if (udf_load_sequence(sb, &fileset)) { | 1915 | if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { |
1916 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | ||
1917 | } else { | ||
1918 | uopt.blocksize = bdev_hardsect_size(sb->s_bdev); | ||
1919 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | ||
1920 | if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { | ||
1921 | if (!silent) | ||
1922 | printk(KERN_NOTICE | ||
1923 | "UDF-fs: Rescanning with blocksize " | ||
1924 | "%d\n", UDF_DEFAULT_BLOCKSIZE); | ||
1925 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; | ||
1926 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | ||
1927 | } | ||
1928 | } | ||
1929 | if (!ret) { | ||
1932 | printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); | 1930 | printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); |
1933 | goto error_out; | 1931 | goto error_out; |
1934 | } | 1932 | } |
@@ -1978,7 +1976,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1978 | } | 1976 | } |
1979 | 1977 | ||
1980 | if (!silent) { | 1978 | if (!silent) { |
1981 | timestamp ts; | 1979 | struct timestamp ts; |
1982 | udf_time_to_disk_stamp(&ts, sbi->s_record_time); | 1980 | udf_time_to_disk_stamp(&ts, sbi->s_record_time); |
1983 | udf_info("UDF: Mounting volume '%s', " | 1981 | udf_info("UDF: Mounting volume '%s', " |
1984 | "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", | 1982 | "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", |
@@ -1991,7 +1989,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1991 | /* Assign the root inode */ | 1989 | /* Assign the root inode */ |
1992 | /* assign inodes by physical block number */ | 1990 | /* assign inodes by physical block number */ |
1993 | /* perhaps it's not extensible enough, but for now ... */ | 1991 | /* perhaps it's not extensible enough, but for now ... */ |
1994 | inode = udf_iget(sb, rootdir); | 1992 | inode = udf_iget(sb, &rootdir); |
1995 | if (!inode) { | 1993 | if (!inode) { |
1996 | printk(KERN_ERR "UDF-fs: Error in udf_iget, block=%d, " | 1994 | printk(KERN_ERR "UDF-fs: Error in udf_iget, block=%d, " |
1997 | "partition=%d\n", | 1995 | "partition=%d\n", |
@@ -2081,11 +2079,31 @@ static void udf_put_super(struct super_block *sb) | |||
2081 | sb->s_fs_info = NULL; | 2079 | sb->s_fs_info = NULL; |
2082 | } | 2080 | } |
2083 | 2081 | ||
2082 | static int udf_sync_fs(struct super_block *sb, int wait) | ||
2083 | { | ||
2084 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
2085 | |||
2086 | mutex_lock(&sbi->s_alloc_mutex); | ||
2087 | if (sbi->s_lvid_dirty) { | ||
2088 | /* | ||
2089 | * Blockdevice will be synced later so we don't have to submit | ||
2090 | * the buffer for IO | ||
2091 | */ | ||
2092 | mark_buffer_dirty(sbi->s_lvid_bh); | ||
2093 | sb->s_dirt = 0; | ||
2094 | sbi->s_lvid_dirty = 0; | ||
2095 | } | ||
2096 | mutex_unlock(&sbi->s_alloc_mutex); | ||
2097 | |||
2098 | return 0; | ||
2099 | } | ||
2100 | |||
2084 | static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | 2101 | static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) |
2085 | { | 2102 | { |
2086 | struct super_block *sb = dentry->d_sb; | 2103 | struct super_block *sb = dentry->d_sb; |
2087 | struct udf_sb_info *sbi = UDF_SB(sb); | 2104 | struct udf_sb_info *sbi = UDF_SB(sb); |
2088 | struct logicalVolIntegrityDescImpUse *lvidiu; | 2105 | struct logicalVolIntegrityDescImpUse *lvidiu; |
2106 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); | ||
2089 | 2107 | ||
2090 | if (sbi->s_lvid_bh != NULL) | 2108 | if (sbi->s_lvid_bh != NULL) |
2091 | lvidiu = udf_sb_lvidiu(sbi); | 2109 | lvidiu = udf_sb_lvidiu(sbi); |
@@ -2101,8 +2119,9 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
2101 | le32_to_cpu(lvidiu->numDirs)) : 0) | 2119 | le32_to_cpu(lvidiu->numDirs)) : 0) |
2102 | + buf->f_bfree; | 2120 | + buf->f_bfree; |
2103 | buf->f_ffree = buf->f_bfree; | 2121 | buf->f_ffree = buf->f_bfree; |
2104 | /* __kernel_fsid_t f_fsid */ | ||
2105 | buf->f_namelen = UDF_NAME_LEN - 2; | 2122 | buf->f_namelen = UDF_NAME_LEN - 2; |
2123 | buf->f_fsid.val[0] = (u32)id; | ||
2124 | buf->f_fsid.val[1] = (u32)(id >> 32); | ||
2106 | 2125 | ||
2107 | return 0; | 2126 | return 0; |
2108 | } | 2127 | } |
@@ -2114,7 +2133,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2114 | unsigned int accum = 0; | 2133 | unsigned int accum = 0; |
2115 | int index; | 2134 | int index; |
2116 | int block = 0, newblock; | 2135 | int block = 0, newblock; |
2117 | kernel_lb_addr loc; | 2136 | struct kernel_lb_addr loc; |
2118 | uint32_t bytes; | 2137 | uint32_t bytes; |
2119 | uint8_t *ptr; | 2138 | uint8_t *ptr; |
2120 | uint16_t ident; | 2139 | uint16_t ident; |
@@ -2124,7 +2143,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2124 | 2143 | ||
2125 | loc.logicalBlockNum = bitmap->s_extPosition; | 2144 | loc.logicalBlockNum = bitmap->s_extPosition; |
2126 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; | 2145 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; |
2127 | bh = udf_read_ptagged(sb, loc, 0, &ident); | 2146 | bh = udf_read_ptagged(sb, &loc, 0, &ident); |
2128 | 2147 | ||
2129 | if (!bh) { | 2148 | if (!bh) { |
2130 | printk(KERN_ERR "udf: udf_count_free failed\n"); | 2149 | printk(KERN_ERR "udf: udf_count_free failed\n"); |
@@ -2147,7 +2166,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2147 | bytes -= cur_bytes; | 2166 | bytes -= cur_bytes; |
2148 | if (bytes) { | 2167 | if (bytes) { |
2149 | brelse(bh); | 2168 | brelse(bh); |
2150 | newblock = udf_get_lb_pblock(sb, loc, ++block); | 2169 | newblock = udf_get_lb_pblock(sb, &loc, ++block); |
2151 | bh = udf_tread(sb, newblock); | 2170 | bh = udf_tread(sb, newblock); |
2152 | if (!bh) { | 2171 | if (!bh) { |
2153 | udf_debug("read failed\n"); | 2172 | udf_debug("read failed\n"); |
@@ -2170,7 +2189,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, | |||
2170 | { | 2189 | { |
2171 | unsigned int accum = 0; | 2190 | unsigned int accum = 0; |
2172 | uint32_t elen; | 2191 | uint32_t elen; |
2173 | kernel_lb_addr eloc; | 2192 | struct kernel_lb_addr eloc; |
2174 | int8_t etype; | 2193 | int8_t etype; |
2175 | struct extent_position epos; | 2194 | struct extent_position epos; |
2176 | 2195 | ||