u64 cur_inode_mode;
        u64 cur_inode_rdev;
        u64 cur_inode_last_extent;
+       u64 cur_inode_next_write_offset;
 
        u64 send_progress;
 
                        break;
                offset += len;
        }
+       sctx->cur_inode_next_write_offset = offset;
 tlv_put_failure:
        fs_path_free(p);
        return ret;
        } else {
                ret = send_extent_data(sctx, offset, len);
        }
+       sctx->cur_inode_next_write_offset = offset + len;
 out:
        return ret;
 }
        u64 right_gid;
        int need_chmod = 0;
        int need_chown = 0;
+       int need_truncate = 1;
        int pending_move = 0;
        int refs_processed = 0;
 
                need_chown = 1;
                if (!S_ISLNK(sctx->cur_inode_mode))
                        need_chmod = 1;
+               if (sctx->cur_inode_next_write_offset == sctx->cur_inode_size)
+                       need_truncate = 0;
        } else {
+               u64 old_size;
+
                ret = get_inode_info(sctx->parent_root, sctx->cur_ino,
-                               NULL, NULL, &right_mode, &right_uid,
+                               &old_size, NULL, &right_mode, &right_uid,
                                &right_gid, NULL);
                if (ret < 0)
                        goto out;
                        need_chown = 1;
                if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode)
                        need_chmod = 1;
+               if ((old_size == sctx->cur_inode_size) ||
+                   (sctx->cur_inode_size > old_size &&
+                    sctx->cur_inode_next_write_offset == sctx->cur_inode_size))
+                       need_truncate = 0;
        }
 
        if (S_ISREG(sctx->cur_inode_mode)) {
                                        goto out;
                        }
                }
-               ret = send_truncate(sctx, sctx->cur_ino, sctx->cur_inode_gen,
-                               sctx->cur_inode_size);
-               if (ret < 0)
-                       goto out;
+               if (need_truncate) {
+                       ret = send_truncate(sctx, sctx->cur_ino,
+                                           sctx->cur_inode_gen,
+                                           sctx->cur_inode_size);
+                       if (ret < 0)
+                               goto out;
+               }
        }
 
        if (need_chown) {
        sctx->cur_ino = key->objectid;
        sctx->cur_inode_new_gen = 0;
        sctx->cur_inode_last_extent = (u64)-1;
+       sctx->cur_inode_next_write_offset = 0;
 
        /*
         * Set send_progress to current inode. This will tell all get_cur_xxx