* grub-core/fs/btrfs.c (GRUB_BTRFS_ITEM_TYPE_INODE_REF): New enum value.

(find_path): Handle "." and "..".
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-05-27 00:47:37 +02:00
parent fd8ed4c5c5
commit f3250e5f1f
2 changed files with 58 additions and 6 deletions

View file

@ -1,3 +1,8 @@
2012-05-27 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/btrfs.c (GRUB_BTRFS_ITEM_TYPE_INODE_REF): New enum value.
(find_path): Handle "." and "..".
2012-05-27 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/affs.c (grub_affs_file): New field hardlink.

View file

@ -106,15 +106,20 @@ struct grub_btrfs_data
struct grub_btrfs_extent_data *extent;
};
enum
{
GRUB_BTRFS_ITEM_TYPE_INODE_ITEM = 0x01,
GRUB_BTRFS_ITEM_TYPE_INODE_REF = 0x0c,
GRUB_BTRFS_ITEM_TYPE_DIR_ITEM = 0x54,
GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM = 0x6c,
GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84,
GRUB_BTRFS_ITEM_TYPE_DEVICE = 0xd8,
GRUB_BTRFS_ITEM_TYPE_CHUNK = 0xe4
};
struct grub_btrfs_key
{
grub_uint64_t object_id;
#define GRUB_BTRFS_ITEM_TYPE_INODE_ITEM 0x01
#define GRUB_BTRFS_ITEM_TYPE_DIR_ITEM 0x54
#define GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM 0x6c
#define GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM 0x84
#define GRUB_BTRFS_ITEM_TYPE_DEVICE 0xd8
#define GRUB_BTRFS_ITEM_TYPE_CHUNK 0xe4
grub_uint8_t type;
grub_uint64_t offset;
} __attribute__ ((packed));
@ -1232,6 +1237,48 @@ find_path (struct grub_btrfs_data *data,
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
}
if (ctokenlen == 1 && ctoken[0] == '.')
{
if (!skip_default)
path = slash;
skip_default = 0;
continue;
}
if (ctokenlen == 2 && ctoken[0] == '.' && ctoken[1] == '.')
{
key->type = GRUB_BTRFS_ITEM_TYPE_INODE_REF;
key->offset = -1;
err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize,
NULL, 0);
if (err)
{
grub_free (direl);
grub_free (path_alloc);
grub_free (origpath);
return err;
}
if (key_out.type != key->type
|| key->object_id != key_out.object_id)
{
grub_free (direl);
grub_free (path_alloc);
err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
grub_free (origpath);
return err;
}
*type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY;
key->object_id = key_out.offset;
if (!skip_default)
path = slash;
skip_default = 0;
continue;
}
key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM;
key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen));