buffer extent for performance
This commit is contained in:
parent
8006f6779e
commit
a43c4bc55f
1 changed files with 53 additions and 53 deletions
|
@ -70,6 +70,8 @@ struct grub_btrfs_data
|
||||||
unsigned int sblock_number;
|
unsigned int sblock_number;
|
||||||
grub_uint64_t tree;
|
grub_uint64_t tree;
|
||||||
grub_uint64_t inode;
|
grub_uint64_t inode;
|
||||||
|
grub_uint64_t extstart;
|
||||||
|
struct grub_btrfs_extent_data *extent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_btrfs_key
|
struct grub_btrfs_key
|
||||||
|
@ -557,7 +559,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
static struct grub_btrfs_data *
|
static struct grub_btrfs_data *
|
||||||
grub_btrfs_mount (grub_disk_t disk)
|
grub_btrfs_mount (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
struct grub_btrfs_data *data = grub_malloc (sizeof (*data));
|
struct grub_btrfs_data *data = grub_zalloc (sizeof (*data));
|
||||||
unsigned i;
|
unsigned i;
|
||||||
grub_err_t err = GRUB_ERR_NONE;
|
grub_err_t err = GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
@ -899,7 +901,10 @@ grub_btrfs_open (struct grub_file *file, const char *name)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_btrfs_close (grub_file_t file)
|
grub_btrfs_close (grub_file_t file)
|
||||||
{
|
{
|
||||||
grub_free (file->data);
|
struct grub_btrfs_data *data = file->data;
|
||||||
|
|
||||||
|
grub_free (data->extent);
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -909,16 +914,19 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
struct grub_btrfs_data *data = file->data;
|
struct grub_btrfs_data *data = file->data;
|
||||||
grub_off_t pos = file->offset;
|
grub_off_t pos = file->offset;
|
||||||
grub_disk_addr_t elemaddr;
|
|
||||||
grub_size_t elemsize;
|
|
||||||
struct grub_btrfs_key key_in, key_out;
|
|
||||||
grub_off_t extoff;
|
|
||||||
|
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
grub_size_t csize;
|
grub_size_t csize;
|
||||||
struct grub_btrfs_extent_data *extent;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
grub_off_t extoff;
|
||||||
|
if (!data->extent || data->extstart > pos ||
|
||||||
|
grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos)
|
||||||
|
{
|
||||||
|
struct grub_btrfs_key key_in, key_out;
|
||||||
|
grub_disk_addr_t elemaddr;
|
||||||
|
grub_size_t elemsize;
|
||||||
|
grub_free (data->extent);
|
||||||
key_in.object_id = data->inode;
|
key_in.object_id = data->inode;
|
||||||
key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM;
|
key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM;
|
||||||
key_in.offset = grub_cpu_to_le64 (pos);
|
key_in.offset = grub_cpu_to_le64 (pos);
|
||||||
|
@ -933,41 +941,36 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
extent = grub_malloc (elemsize);
|
data->extstart = grub_le_to_cpu64 (key_out.offset);
|
||||||
if (!extent)
|
data->extent = grub_malloc (elemsize);
|
||||||
|
if (!data->extent)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
err = grub_btrfs_read_logical (data, file->device->disk, elemaddr,
|
err = grub_btrfs_read_logical (data, file->device->disk, elemaddr,
|
||||||
extent, elemsize);
|
data->extent, elemsize);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
|
||||||
grub_free (extent);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
if (grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos)
|
||||||
if (grub_le_to_cpu64 (extent->size) + grub_le_to_cpu64 (key_out.offset)
|
|
||||||
<= pos)
|
|
||||||
{
|
|
||||||
grub_free (extent);
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
return grub_error (GRUB_ERR_BAD_FS, "extent not found");
|
||||||
}
|
|
||||||
grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%"
|
grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%"
|
||||||
PRIxGRUB_UINT64_T "\n",
|
PRIxGRUB_UINT64_T "\n",
|
||||||
grub_le_to_cpu64 (key_out.offset),
|
grub_le_to_cpu64 (key_out.offset),
|
||||||
grub_le_to_cpu64 (extent->size));
|
grub_le_to_cpu64 (data->extent->size));
|
||||||
csize = grub_le_to_cpu64 (extent->size)
|
}
|
||||||
+ grub_le_to_cpu64 (key_out.offset) - pos;
|
csize = grub_le_to_cpu64 (data->extent->size)
|
||||||
extoff = pos - grub_le_to_cpu64 (key_out.offset);
|
+ grub_le_to_cpu64 (data->extstart) - pos;
|
||||||
|
extoff = pos - data->extstart;
|
||||||
if (csize > len)
|
if (csize > len)
|
||||||
csize = len;
|
csize = len;
|
||||||
|
|
||||||
if (extent->encryption)
|
if (data->extent->encryption)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"encryption not supported");
|
"encryption not supported");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extent->compression)
|
if (data->extent->compression)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"compression not supported");
|
"compression not supported");
|
||||||
|
@ -975,37 +978,34 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (extent->encoding)
|
if (data->extent->encoding)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"encoding not supported");
|
"encoding not supported");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (extent->type)
|
switch (data->extent->type)
|
||||||
{
|
{
|
||||||
case GRUB_BTRFS_EXTENT_INLINE:
|
case GRUB_BTRFS_EXTENT_INLINE:
|
||||||
grub_memcpy (buf, extent->inl + extoff, csize);
|
grub_memcpy (buf, data->extent->inl + extoff, csize);
|
||||||
grub_free (extent);
|
|
||||||
break;
|
break;
|
||||||
case GRUB_BTRFS_EXTENT_REGULAR:
|
case GRUB_BTRFS_EXTENT_REGULAR:
|
||||||
if (!extent->laddr)
|
if (!data->extent->laddr)
|
||||||
{
|
{
|
||||||
grub_memset (buf, 0, csize);
|
grub_memset (buf, 0, csize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
err = grub_btrfs_read_logical (data, file->device->disk,
|
err = grub_btrfs_read_logical (data, file->device->disk,
|
||||||
grub_le_to_cpu64 (extent->laddr)
|
grub_le_to_cpu64 (data->extent->laddr)
|
||||||
+ extoff,
|
+ extoff,
|
||||||
buf, csize);
|
buf, csize);
|
||||||
grub_free (extent);
|
|
||||||
if (err)
|
if (err)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
grub_free (extent);
|
|
||||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"unsupported extent type 0x%x", extent->type);
|
"unsupported extent type 0x%x", data->extent->type);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
buf += csize;
|
buf += csize;
|
||||||
|
|
Loading…
Reference in a new issue