From 6fbacb8539a6659d446a9efabb538cfc007c1427 Mon Sep 17 00:00:00 2001 From: "Steven J. Magnani" Date: Thu, 11 Jul 2019 08:38:52 -0500 Subject: [PATCH] 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 Tested-by: Steven J. Magnani Link: https://lore.kernel.org/r/20190711133852.16887-2-steve@digidescorp.com Signed-off-by: Jan Kara --- fs/udf/super.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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) vsd = (struct volStructDesc *)(bh->b_data + (sector & (sb->s_blocksize - 1))); nsr = identify_vsd(vsd); + /* Found NSR or end? */ + if (nsr) { + brelse(bh); + break; + } + /* + * Special handling for improperly formatted VRS (e.g., Win10) + * where components are separated by 2048 bytes even though + * sectors are 4K + */ + if (sb->s_blocksize == 4096) { + nsr = identify_vsd(vsd + 1); + /* Ignore unknown IDs... */ + if (nsr < 0) + nsr = 0; + } brelse(bh); } -- 2.45.2