Support version 33 including symlinks
This commit is contained in:
parent
11e50e923a
commit
34c5965451
3 changed files with 141 additions and 13 deletions
|
@ -1839,19 +1839,18 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
*path = ch;
|
*path = ch;
|
||||||
if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
|
if (dnode_path->dn.dn.dn_bonustype == DMU_OT_ZNODE
|
||||||
|
&& ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
|
||||||
{
|
{
|
||||||
char *sym_value;
|
char *sym_value;
|
||||||
grub_size_t avail_in_dnode;
|
|
||||||
grub_size_t sym_sz;
|
grub_size_t sym_sz;
|
||||||
int free_symval = 0;
|
int free_symval = 0;
|
||||||
char *oldpath = path, *oldpathbuf = path_buf;
|
char *oldpath = path, *oldpathbuf = path_buf;
|
||||||
sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys));
|
sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys));
|
||||||
avail_in_dnode = (char *) (&dnode_path->dn + 1) - sym_value;
|
|
||||||
|
|
||||||
sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian);
|
sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian);
|
||||||
|
|
||||||
if (sym_sz > avail_in_dnode - 8)
|
if (dnode_path->dn.dn.dn_flags & 1)
|
||||||
{
|
{
|
||||||
grub_size_t block;
|
grub_size_t block;
|
||||||
grub_size_t blksz;
|
grub_size_t blksz;
|
||||||
|
@ -1905,6 +1904,62 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn,
|
||||||
grub_free (dn_new);
|
grub_free (dn_new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dnode_path->dn.dn.dn_bonustype == DMU_OT_SA)
|
||||||
|
{
|
||||||
|
void *sahdrp;
|
||||||
|
int hdrsize;
|
||||||
|
|
||||||
|
if (dnode_path->dn.dn.dn_bonuslen != 0)
|
||||||
|
{
|
||||||
|
sahdrp = DN_BONUS (&dnode_path->dn.dn);
|
||||||
|
}
|
||||||
|
else if (dnode_path->dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
|
||||||
|
{
|
||||||
|
blkptr_t *bp = &dnode_path->dn.dn.dn_spill;
|
||||||
|
|
||||||
|
err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
|
||||||
|
}
|
||||||
|
|
||||||
|
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
|
||||||
|
|
||||||
|
if (((grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_TYPE_OFFSET), dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
|
||||||
|
{
|
||||||
|
char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET;
|
||||||
|
grub_size_t sym_sz =
|
||||||
|
grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), dnode_path->dn.endian);
|
||||||
|
char *oldpath = path, *oldpathbuf = path_buf;
|
||||||
|
path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
|
||||||
|
if (!path_buf)
|
||||||
|
{
|
||||||
|
grub_free (oldpathbuf);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
grub_memcpy (path, sym_value, sym_sz);
|
||||||
|
path [sym_sz] = 0;
|
||||||
|
grub_memcpy (path + grub_strlen (path), oldpath,
|
||||||
|
grub_strlen (oldpath) + 1);
|
||||||
|
|
||||||
|
grub_free (oldpathbuf);
|
||||||
|
if (path[0] != '/')
|
||||||
|
{
|
||||||
|
dn_new = dnode_path;
|
||||||
|
dnode_path = dn_new->next;
|
||||||
|
grub_free (dn_new);
|
||||||
|
}
|
||||||
|
else while (dnode_path != root)
|
||||||
|
{
|
||||||
|
dn_new = dnode_path;
|
||||||
|
dnode_path = dn_new->next;
|
||||||
|
grub_free (dn_new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
|
@ -2666,12 +2721,14 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
|
||||||
}
|
}
|
||||||
|
|
||||||
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
|
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
|
||||||
file->size = *(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET);
|
file->size = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian);
|
||||||
}
|
}
|
||||||
else
|
else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE)
|
||||||
{
|
{
|
||||||
file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian);
|
file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "bad bonus type");
|
||||||
|
|
||||||
file->data = data;
|
file->data = data;
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
|
@ -2830,8 +2887,39 @@ fill_fs_info (struct grub_dirhook_info *info,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->mtimeset = 1;
|
if (dn.dn.dn_bonustype == DMU_OT_SA)
|
||||||
info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian);
|
{
|
||||||
|
void *sahdrp;
|
||||||
|
int hdrsize;
|
||||||
|
|
||||||
|
if (dn.dn.dn_bonuslen != 0)
|
||||||
|
{
|
||||||
|
sahdrp = (sa_hdr_phys_t *) DN_BONUS (&dn.dn);
|
||||||
|
}
|
||||||
|
else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
|
||||||
|
{
|
||||||
|
blkptr_t *bp = &dn.dn.dn_spill;
|
||||||
|
|
||||||
|
err = zio_read (bp, dn.endian, &sahdrp, NULL, data);
|
||||||
|
if (err)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
|
||||||
|
info->mtimeset = 1;
|
||||||
|
info->mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
|
||||||
|
{
|
||||||
|
info->mtimeset = 1;
|
||||||
|
info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2855,10 +2943,47 @@ grub_zfs_dir (grub_device_t device, const char *path,
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
|
||||||
dnode_get (&(data->mdn), val, 0, &dn, data);
|
dnode_get (&(data->mdn), val, 0, &dn, data);
|
||||||
info.mtimeset = 1;
|
|
||||||
info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian);
|
if (dn.dn.dn_bonustype == DMU_OT_SA)
|
||||||
info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
|
{
|
||||||
grub_dprintf ("zfs", "type=%d, name=%s\n",
|
void *sahdrp;
|
||||||
|
int hdrsize;
|
||||||
|
|
||||||
|
if (dn.dn.dn_bonuslen != 0)
|
||||||
|
{
|
||||||
|
sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn);
|
||||||
|
}
|
||||||
|
else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
|
||||||
|
{
|
||||||
|
blkptr_t *bp = &dn.dn.dn_spill;
|
||||||
|
|
||||||
|
err = zio_read (bp, dn.endian, &sahdrp, NULL, data);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
|
||||||
|
grub_print_error ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
|
||||||
|
{
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0],
|
||||||
|
dn.endian);
|
||||||
|
}
|
||||||
|
info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
|
||||||
|
grub_dprintf ("zfs", "type=%d, name=%s\n",
|
||||||
(int)dn.dn.dn_type, (char *)name);
|
(int)dn.dn.dn_type, (char *)name);
|
||||||
return hook (name, &info);
|
return hook (name, &info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ typedef struct sa_hdr_phys {
|
||||||
} sa_hdr_phys_t;
|
} sa_hdr_phys_t;
|
||||||
|
|
||||||
#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0)
|
#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0)
|
||||||
|
#define SA_TYPE_OFFSET 0x0
|
||||||
#define SA_SIZE_OFFSET 0x8
|
#define SA_SIZE_OFFSET 0x8
|
||||||
|
#define SA_MTIME_OFFSET 0x38
|
||||||
|
#define SA_SYMLINK_OFFSET 0xa0
|
||||||
|
|
||||||
#endif /* _SYS_SA_IMPL_H */
|
#endif /* _SYS_SA_IMPL_H */
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
/*
|
/*
|
||||||
* On-disk version number.
|
* On-disk version number.
|
||||||
*/
|
*/
|
||||||
#define SPA_VERSION 31ULL
|
#define SPA_VERSION 33ULL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following are configuration names used in the nvlist describing a pool's
|
* The following are configuration names used in the nvlist describing a pool's
|
||||||
|
|
Loading…
Reference in a new issue