btrfs return errors on panic, add memory deleter to ReadAt()

* Additional return BAD_DATA after error conditions encountered
   when attempting to decompress BTRFS extents.

 * MemoryDeleter for extent_data added to ReadAt() preventing
   double-free after error.

Change-Id: Ib9f8e9723d3fb6aaff8e69dbb66cd279e86f226b
Reviewed-on: https://review.haiku-os.org/c/1045
Reviewed-by: Stephan Aßmus <[email protected]>
This commit is contained in:
Rob Gill
2019-02-15 08:20:09 +00:00
committed by Stephan Aßmus
parent b6adef8501
commit efac84e790
@@ -240,27 +240,31 @@ Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
"\n", status);
return status;
}
MemoryDeleter deleter(extent_data);
uint8 compression = extent_data->Compression();
if (FileCache() != NULL
&& extent_data->Type() == BTRFS_EXTENT_DATA_REGULAR) {
TRACE("inode %" B_PRIdINO ": ReadAt cache (pos %" B_PRIdOFF ", length %lu)\n",
ID(), pos, length);
free(extent_data);
if (compression == BTRFS_EXTENT_COMPRESS_NONE)
return file_cache_read(FileCache(), NULL, pos, buffer, _length);
else if (compression == BTRFS_EXTENT_COMPRESS_ZLIB)
panic("zlib isn't unsupported for regular extent\n");
else
panic("unknown extent compression; %d\n", compression);
return B_BAD_DATA;
}
TRACE("Inode::ReadAt(%" B_PRIdINO ") key.Offset() %" B_PRId64 "\n", ID(),
search_key.Offset());
off_t diff = pos - search_key.Offset();
if (extent_data->Type() != BTRFS_EXTENT_DATA_INLINE)
if (extent_data->Type() != BTRFS_EXTENT_DATA_INLINE) {
panic("unknown extent type; %d\n", extent_data->Type());
return B_BAD_DATA;
}
*_length = min_c(extent_data->Size() - diff, *_length);
if (compression == BTRFS_EXTENT_COMPRESS_NONE)
@@ -313,7 +317,6 @@ Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
status = inflateInit2(&zStream, 15);
if (status != Z_OK) {
free(extent_data);
return B_ERROR;
}
}
@@ -335,14 +338,15 @@ Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
if (status != Z_STREAM_END) {
TRACE("Inode::ReadAt() inflating failed: %d!\n", status);
free(extent_data);
return B_BAD_DATA;
}
*_length = zStream.total_out;
} else
} else {
panic("unknown extent compression; %d\n", compression);
return B_BAD_DATA;
}
free(extent_data);
return B_OK;