summary refs log tree commit diff
path: root/fs/udf
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2018-02-09 13:28:41 +0100
committerJan Kara <jack@suse.cz>2018-02-16 11:15:04 +0100
commit7b568cba4f0af32522f84c1378e71a47a9c61bb0 (patch)
treee75aed72b2e9aab3f685090a2dc28ced4e6124ec /fs/udf
parent91c9c9ec54c1e88d9ef59a7b12cf31d6ef5d1e58 (diff)
downloadlinux-7b568cba4f0af32522f84c1378e71a47a9c61bb0.tar.gz
udf: Simplify handling of Volume Descriptor Pointers
According to ECMA-167 3/8.4.2 Volume Descriptor Pointer is terminating
current extent of Volume Descriptor Sequence. Also according to ECMA-167
3/8.4.3 Volume Descriptor Sequence Number is not significant for Volume
Descriptor Pointers. Simplify the handling of Volume Descriptor Pointers
to take this into account.

Acked-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/super.c41
1 files changed, 16 insertions, 25 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 5c5d5fd513cc..f80b97173acd 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1615,7 +1615,6 @@ static noinline int udf_process_sequence(
 	bool done = false;
 	uint32_t vdsn;
 	uint16_t ident;
-	long next_s = 0, next_e = 0;
 	int ret;
 	unsigned int indirections = 0;
 
@@ -1647,19 +1646,22 @@ static noinline int udf_process_sequence(
 			}
 			break;
 		case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
-			curr = &vds[VDS_POS_VOL_DESC_PTR];
-			if (vdsn >= curr->volDescSeqNum) {
-				curr->volDescSeqNum = vdsn;
-				curr->block = block;
-
-				vdp = (struct volDescPtr *)bh->b_data;
-				next_s = le32_to_cpu(
-					vdp->nextVolDescSeqExt.extLocation);
-				next_e = le32_to_cpu(
-					vdp->nextVolDescSeqExt.extLength);
-				next_e = next_e >> sb->s_blocksize_bits;
-				next_e += next_s - 1;
+			if (++indirections > UDF_MAX_TD_NESTING) {
+				udf_err(sb, "too many Volume Descriptor "
+					"Pointers (max %u supported)\n",
+					UDF_MAX_TD_NESTING);
+				brelse(bh);
+				return -EIO;
 			}
+
+			vdp = (struct volDescPtr *)bh->b_data;
+			block = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
+			lastblock = le32_to_cpu(
+				vdp->nextVolDescSeqExt.extLength) >>
+				sb->s_blocksize_bits;
+			lastblock += block - 1;
+			/* For loop is going to increment 'block' again */
+			block--;
 			break;
 		case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
 			curr = &vds[VDS_POS_IMP_USE_VOL_DESC];
@@ -1688,19 +1690,8 @@ static noinline int udf_process_sequence(
 			}
 			break;
 		case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
-			if (++indirections > UDF_MAX_TD_NESTING) {
-				udf_err(sb, "too many TDs (max %u supported)\n", UDF_MAX_TD_NESTING);
-				brelse(bh);
-				return -EIO;
-			}
-
 			vds[VDS_POS_TERMINATING_DESC].block = block;
-			if (next_e) {
-				block = next_s;
-				lastblock = next_e;
-				next_s = next_e = 0;
-			} else
-				done = true;
+			done = true;
 			break;
 		}
 		brelse(bh);