diff options
author | Steven J. Magnani <steve.magnani@digidescorp.com> | 2019-07-11 09:38:52 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2019-07-31 06:04:42 -0400 |
commit | 6fbacb8539a6659d446a9efabb538cfc007c1427 (patch) | |
tree | 5f9649197f4f6df4c766a0a629e11dafc16f5843 | |
parent | ba54aef0313322d9eea0fca648170d5a3c906de4 (diff) |
udf: support 2048-byte spacing of VRS descriptors on 4K media
Some UDF creators (specifically Microsoft, but perhaps others) mishandle
the ECMA-167 corner case that requires descriptors within a Volume
Recognition Sequence to be placed at 4096-byte intervals on media where
the block size is 4K. Instead, the descriptors are placed at the 2048-
byte interval mandated for media with smaller blocks. This nonconformity
currently prevents Linux from recognizing the filesystem as UDF.
Modify the driver to tolerate a misformatted VRS on 4K media.
[JK: Simplified descriptor checking]
Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
Tested-by: Steven J. Magnani <steve@digidescorp.com>
Link: https://lore.kernel.org/r/20190711133852.16887-2-steve@digidescorp.com
Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | fs/udf/super.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 14a91955507b..f34e06b4d8fa 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -739,6 +739,22 @@ static int udf_check_vsd(struct super_block *sb) | |||
739 | vsd = (struct volStructDesc *)(bh->b_data + | 739 | vsd = (struct volStructDesc *)(bh->b_data + |
740 | (sector & (sb->s_blocksize - 1))); | 740 | (sector & (sb->s_blocksize - 1))); |
741 | nsr = identify_vsd(vsd); | 741 | nsr = identify_vsd(vsd); |
742 | /* Found NSR or end? */ | ||
743 | if (nsr) { | ||
744 | brelse(bh); | ||
745 | break; | ||
746 | } | ||
747 | /* | ||
748 | * Special handling for improperly formatted VRS (e.g., Win10) | ||
749 | * where components are separated by 2048 bytes even though | ||
750 | * sectors are 4K | ||
751 | */ | ||
752 | if (sb->s_blocksize == 4096) { | ||
753 | nsr = identify_vsd(vsd + 1); | ||
754 | /* Ignore unknown IDs... */ | ||
755 | if (nsr < 0) | ||
756 | nsr = 0; | ||
757 | } | ||
742 | brelse(bh); | 758 | brelse(bh); |
743 | } | 759 | } |
744 | 760 | ||