Btrfs: fix a crash of clone with inline extents's split

xfstests's btrfs/035 triggers a BUG_ON, which we use to detect the split
of inline extents in __btrfs_drop_extents().

For inline extents, we cannot duplicate another EXTENT_DATA item, because
it breaks the rule of inline extents, that is, 'start offset' needs to be 0.

We have set limitations for the source inode's compressed inline extents,
because it needs to decompress and recompress.  Now the destination inode's
inline extents also need similar limitations.

With this, xfstests btrfs/035 doesn't run into panic.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
Liu Bo
2014-03-10 18:56:07 +08:00
committed by Chris Mason
parent 73b802f447
commit 00fdf13a2e
2 changed files with 18 additions and 7 deletions

View File

@@ -804,7 +804,10 @@ next_slot:
*/
if (start > key.offset && end < extent_end) {
BUG_ON(del_nr > 0);
BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
ret = -EINVAL;
break;
}
memcpy(&new_key, &key, sizeof(new_key));
new_key.offset = start;
@@ -847,7 +850,10 @@ next_slot:
* | -------- extent -------- |
*/
if (start <= key.offset && end < extent_end) {
BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
ret = -EINVAL;
break;
}
memcpy(&new_key, &key, sizeof(new_key));
new_key.offset = end;
@@ -870,7 +876,10 @@ next_slot:
*/
if (start > key.offset && end >= extent_end) {
BUG_ON(del_nr > 0);
BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
ret = -EINVAL;
break;
}
btrfs_set_file_extent_num_bytes(leaf, fi,
start - key.offset);