The function uses a ternary return value (<, >, == 0) defined as an int. The code in in this function uses int64_t types to collect ftell() return values and use their difference as the return value. Unfortunately, narrowing of integer types results in the disposal of the left-most bits that won't fit in the target type. Here, for values larger than 2GB, the resulting value will be randomly negative or positive, based on total number of blocks. The patch ensures that only +1, -1, or 0 are returned to properly report status.
diff -u -r a/block-migration.c b/block-migration.c --- a/block-migration.c 2014-04-17 08:30:59.000000000 -0500 +++ b/block-migration.c 2014-11-10 12:39:10.727431187 -0600 @@ -628,6 +628,7 @@ { int ret; int64_t last_ftell = qemu_ftell(f); + int64_t delta_ftell; DPRINTF("Enter save live iterate submitted %d transferred %d\n", block_mig_state.submitted, block_mig_state.transferred); @@ -677,7 +678,8 @@ } qemu_put_be64(f, BLK_MIG_FLAG_EOS); - return qemu_ftell(f) - last_ftell; + delta_ftell = qemu_ftell(f) - last_ftell; + return( (delta_ftell > 0) ? 1 : (delta_ftell < 0) ? -1 : 0 ); } /* Called with iothread lock taken. */