On thu, 25 Jul 2013 17:32:29 +0800, Eryu Guan wrote:
> The second btrfs command segfaults on big endian host(ppc64)
>
> btrfs subvolume snapshot /mnt/btrfs /mnt/btrfs/snap
> btrfs subvolume list -s /mnt/btrfs
>
> And ltrace shows
>
> localtime(0x10029c482d0) = 0
> strftime( <no return ...>
> --- SIGSEGV (Segmentation fault) ---
>
> The corresponding code
>
> btrfs-list.c:
> case BTRFS_LIST_OTIME:
> if (subv->otime)
> strftime(tstr, 256, "%Y-%m-%d %X",
> localtime(&subv->otime));
> else
> strcpy(tstr, "-");
> printf("%s", tstr);
> break;
>
> localtime() returned NULL then strftime() got SIGSEGV.
>
> The reason is that ri->otime.sec is stored as little endian but
> assigned to 't' without conversion.
>
> Signed-off-by: Eryu Guan <guaneryu@xxxxxxxxx>
> ---
> btrfs-list.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/btrfs-list.c b/btrfs-list.c
> index 4fab858..ca1bae8 100644
> --- a/btrfs-list.c
> +++ b/btrfs-list.c
> @@ -1052,7 +1052,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
> flags = btrfs_root_flags(ri);
> if(sh.len >
> sizeof(struct btrfs_root_item_v0)) {
> - t = ri->otime.sec;
> + t = le64_to_cpu(ri->otime.sec);
It is better to use btrfs_stack_timespec_sec() instead of raw convert.
Thanks
Miao
> ogen = btrfs_root_otransid(ri);
> memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
> memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
>
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html