@@ -179,6 +179,40 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
return NULL;
}
+bool udf_check_tagged_bh(struct super_block *sb, struct buffer_head *bh)
+{
+ u8 checksum;
+ struct tag *tag_p = (struct tag *)(bh->b_data);
+
+ /* Verify the tag checksum */
+ checksum = udf_tag_checksum(tag_p);
+ if (checksum != tag_p->tagChecksum) {
+ udf_err(sb, "tag checksum failed, block %llu: 0x%02x != 0x%02x\n",
+ bh->b_blocknr, checksum, tag_p->tagChecksum);
+ return false;
+ }
+
+ /* Verify the tag version */
+ if (tag_p->descVersion != cpu_to_le16(0x0002U) &&
+ tag_p->descVersion != cpu_to_le16(0x0003U)) {
+ udf_err(sb, "tag version 0x%04x != 0x0002 || 0x0003, block %llu\n",
+ le16_to_cpu(tag_p->descVersion), bh->b_blocknr);
+ return false;
+ }
+
+ /* Verify the descriptor CRC */
+ if (le16_to_cpu(tag_p->descCRCLength) + sizeof(struct tag) > sb->s_blocksize ||
+ le16_to_cpu(tag_p->descCRC) == crc_itu_t(0,
+ bh->b_data + sizeof(struct tag),
+ le16_to_cpu(tag_p->descCRCLength)))
+ return true;
+
+ udf_debug("Crc failure block %llu: crc = %u, crclen = %u\n", bh->b_blocknr,
+ le16_to_cpu(tag_p->descCRC),
+ le16_to_cpu(tag_p->descCRCLength));
+ return false;
+}
+
/*
* udf_read_tagged
*
@@ -194,7 +228,6 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
{
struct tag *tag_p;
struct buffer_head *bh = NULL;
- u8 checksum;
/* Read the block */
if (block == 0xFFFFFFFF)
@@ -217,32 +250,9 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
goto error_out;
}
- /* Verify the tag checksum */
- checksum = udf_tag_checksum(tag_p);
- if (checksum != tag_p->tagChecksum) {
- udf_err(sb, "tag checksum failed, block %u: 0x%02x != 0x%02x\n",
- block, checksum, tag_p->tagChecksum);
- goto error_out;
- }
-
- /* Verify the tag version */
- if (tag_p->descVersion != cpu_to_le16(0x0002U) &&
- tag_p->descVersion != cpu_to_le16(0x0003U)) {
- udf_err(sb, "tag version 0x%04x != 0x0002 || 0x0003, block %u\n",
- le16_to_cpu(tag_p->descVersion), block);
- goto error_out;
- }
-
- /* Verify the descriptor CRC */
- if (le16_to_cpu(tag_p->descCRCLength) + sizeof(struct tag) > sb->s_blocksize ||
- le16_to_cpu(tag_p->descCRC) == crc_itu_t(0,
- bh->b_data + sizeof(struct tag),
- le16_to_cpu(tag_p->descCRCLength)))
+ if (udf_check_tagged_bh(sb, bh))
return bh;
- udf_debug("Crc failure block %u: crc = %u, crclen = %u\n", block,
- le16_to_cpu(tag_p->descCRC),
- le16_to_cpu(tag_p->descCRCLength));
error_out:
brelse(bh);
return NULL;
@@ -180,6 +180,7 @@ extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t,
uint32_t, uint8_t);
extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t,
uint8_t);
+extern bool udf_check_tagged_bh(struct super_block *sb, struct buffer_head *bh);
extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t,
uint32_t, uint16_t *);
extern struct buffer_head *udf_read_ptagged(struct super_block *,