X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=file_ioctl.c;h=fc45aa693b9676f8a0aef23854c03d77b73a36a4;hb=f3b38739d507e5ba3c9d8b728fe581f30d4463f8;hp=b065db917557149dd0b7cb3270f78424184aea0f;hpb=eea86017e1fba59ec51656ac0c8cba63c3420bc1;p=strace diff --git a/file_ioctl.c b/file_ioctl.c index b065db91..fc45aa69 100644 --- a/file_ioctl.c +++ b/file_ioctl.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016 Jeff Mahoney + * Copyright (c) 2016-2018 The strace developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,11 +37,11 @@ #endif #ifndef FICLONE -# define FICLONE _IOW(0x94, 9, int) +# define FICLONE _IOW(0x94, 9, int) #endif #ifndef FICLONERANGE -# define FICLONERANGE _IOW(0x94, 13, struct file_clone_range) +# define FICLONERANGE _IOW(0x94, 13, struct file_clone_range) struct file_clone_range { int64_t src_fd; uint64_t src_offset; @@ -50,7 +51,7 @@ struct file_clone_range { #endif #ifndef FIDEDUPERANGE -# define FIDEDUPERANGE _IOWR(0x94, 54, struct file_dedupe_range) +# define FIDEDUPERANGE _IOWR(0x94, 54, struct file_dedupe_range) struct file_dedupe_range_info { int64_t dest_fd; /* in - destination file */ uint64_t dest_offset; /* in - start of extent in destination */ @@ -80,6 +81,15 @@ print_file_dedupe_range_info(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data) { const struct file_dedupe_range_info *info = elem_buf; + unsigned int *count = data; + + if (count) { + if (*count == 0) { + tprints("..."); + return false; + } + --*count; + } if (entering(tcp)) { tprints("{dest_fd="); @@ -114,7 +124,8 @@ print_fiemap_extent(struct tcb *tcp, void *elem_buf, size_t elem_size, void *dat #endif /* HAVE_LINUX_FIEMAP_H */ int -file_ioctl(struct tcb *tcp, const unsigned int code, const long arg) +file_ioctl(struct tcb *const tcp, const unsigned int code, + const kernel_ulong_t arg) { switch (code) { case FICLONE: /* W */ @@ -141,6 +152,10 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg) case FIDEDUPERANGE: { /* RW */ struct file_dedupe_range args; + struct file_dedupe_range_info info; + unsigned int *limit = NULL; + unsigned int count = 2; + bool rc; if (entering(tcp)) tprints(", "); @@ -162,19 +177,16 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg) (uint16_t) args.dest_count); } - bool rc = false; tprints("info="); - if (abbrev(tcp)) { - tprints("..."); - } else { - struct file_dedupe_range_info info; - rc = print_array(tcp, - arg + offsetof(typeof(args), info), - args.dest_count, - &info, sizeof(info), - umoven_or_printaddr, - print_file_dedupe_range_info, 0); - } + + /* Limit how many elements we print in abbrev mode. */ + if (abbrev(tcp) && args.dest_count > count) + limit = &count; + + rc = print_array(tcp, arg + offsetof(typeof(args), info), + args.dest_count, &info, sizeof(info), + tfetch_mem, + print_file_dedupe_range_info, limit); tprints("}"); if (!rc || exiting(tcp)) @@ -213,15 +225,15 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg) "FIEMAP_FLAG_???"); tprintf(", fm_mapped_extents=%u", args.fm_mapped_extents); - tprints(", fm_extents="); if (abbrev(tcp)) { - tprints("..."); + tprints(", ..."); } else { struct fiemap_extent fe; + tprints(", fm_extents="); print_array(tcp, arg + offsetof(typeof(args), fm_extents), args.fm_mapped_extents, &fe, sizeof(fe), - umoven_or_printaddr, + tfetch_mem, print_fiemap_extent, 0); } tprints("}"); @@ -234,5 +246,5 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg) return RVAL_DECODED; }; - return RVAL_DECODED | 1; + return RVAL_IOCTL_DECODED; }