summaryrefslogtreecommitdiffstats
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-stable-7b568cba4f0af32522f84c1378e71a47a9c61bb0.tar.gz
linux-stable-7b568cba4f0af32522f84c1378e71a47a9c61bb0.tar.bz2
linux-stable-7b568cba4f0af32522f84c1378e71a47a9c61bb0.zip
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);