diff options
author | Jan Kara <jack@suse.cz> | 2018-02-09 13:28:41 +0100 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2018-02-16 11:15:04 +0100 |
commit | 7b568cba4f0af32522f84c1378e71a47a9c61bb0 (patch) | |
tree | e75aed72b2e9aab3f685090a2dc28ced4e6124ec /fs/udf | |
parent | 91c9c9ec54c1e88d9ef59a7b12cf31d6ef5d1e58 (diff) | |
download | linux-7b568cba4f0af32522f84c1378e71a47a9c61bb0.tar.gz linux-7b568cba4f0af32522f84c1378e71a47a9c61bb0.tar.bz2 linux-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.c | 41 |
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); |