btrfs: Remove code referencing unused TRANS_USERSPACE
[sfrench/cifs-2.6.git] / fs / btrfs / send.c
index 484e2af793de2a86fa206196661d47cda078f0c2..1f5748c7d1c74cd6538fcf9cad55f8759337a188 100644 (file)
 #include <linux/vmalloc.h>
 #include <linux/string.h>
 #include <linux/compat.h>
+#include <linux/crc32c.h>
 
 #include "send.h"
 #include "backref.h"
-#include "hash.h"
 #include "locking.h"
 #include "disk-io.h"
 #include "btrfs_inode.h"
@@ -112,6 +112,7 @@ struct send_ctx {
        u64 cur_inode_mode;
        u64 cur_inode_rdev;
        u64 cur_inode_last_extent;
+       u64 cur_inode_next_write_offset;
 
        u64 send_progress;
 
@@ -270,6 +271,7 @@ struct name_cache_entry {
        char name[];
 };
 
+__cold
 static void inconsistent_snapshot_error(struct send_ctx *sctx,
                                        enum btrfs_compare_tree_result result,
                                        const char *what)
@@ -611,9 +613,9 @@ static int tlv_put_btrfs_timespec(struct send_ctx *sctx, u16 attr,
 }
 
 
-#define TLV_PUT(sctx, attrtype, attrlen, data) \
+#define TLV_PUT(sctx, attrtype, data, attrlen) \
        do { \
-               ret = tlv_put(sctx, attrtype, attrlen, data); \
+               ret = tlv_put(sctx, attrtype, data, attrlen); \
                if (ret < 0) \
                        goto tlv_put_failure; \
        } while (0)
@@ -695,7 +697,7 @@ static int send_cmd(struct send_ctx *sctx)
        hdr->len = cpu_to_le32(sctx->send_size - sizeof(*hdr));
        hdr->crc = 0;
 
-       crc = btrfs_crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size);
+       crc = crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size);
        hdr->crc = cpu_to_le32(crc);
 
        ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size,
@@ -5029,6 +5031,7 @@ static int send_hole(struct send_ctx *sctx, u64 end)
                        break;
                offset += len;
        }
+       sctx->cur_inode_next_write_offset = offset;
 tlv_put_failure:
        fs_path_free(p);
        return ret;
@@ -5264,6 +5267,7 @@ static int send_write_or_clone(struct send_ctx *sctx,
        } else {
                ret = send_extent_data(sctx, offset, len);
        }
+       sctx->cur_inode_next_write_offset = offset + len;
 out:
        return ret;
 }
@@ -5788,6 +5792,7 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
        u64 right_gid;
        int need_chmod = 0;
        int need_chown = 0;
+       int need_truncate = 1;
        int pending_move = 0;
        int refs_processed = 0;
 
@@ -5825,9 +5830,13 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
                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;
@@ -5836,6 +5845,10 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
                        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)) {
@@ -5854,10 +5867,13 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
                                        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) {
@@ -5911,6 +5927,7 @@ static int changed_inode(struct send_ctx *sctx,
        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