* command (since protocol v2, data must be the last attribute).
         */
        bool put_data;
+       struct page **send_buf_pages;
        u64 flags;      /* 'flags' member of btrfs_ioctl_send_args is u64 */
        /* Protocol version compatibility requested */
        u32 proto;
 
        sctx->clone_roots_cnt = arg->clone_sources_count;
 
-       if (sctx->proto >= 2)
+       if (sctx->proto >= 2) {
+               u32 send_buf_num_pages;
+
                sctx->send_max_size = ALIGN(SZ_16K + BTRFS_MAX_COMPRESSED, PAGE_SIZE);
-       else
+               sctx->send_buf = vmalloc(sctx->send_max_size);
+               if (!sctx->send_buf) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               send_buf_num_pages = sctx->send_max_size >> PAGE_SHIFT;
+               sctx->send_buf_pages = kcalloc(send_buf_num_pages,
+                                              sizeof(*sctx->send_buf_pages),
+                                              GFP_KERNEL);
+               if (!sctx->send_buf_pages) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               for (i = 0; i < send_buf_num_pages; i++) {
+                       sctx->send_buf_pages[i] =
+                               vmalloc_to_page(sctx->send_buf + (i << PAGE_SHIFT));
+               }
+       } else {
                sctx->send_max_size = BTRFS_SEND_BUF_SIZE_V1;
-
-       sctx->send_buf = kvmalloc(sctx->send_max_size, GFP_KERNEL);
+               sctx->send_buf = kvmalloc(sctx->send_max_size, GFP_KERNEL);
+       }
        if (!sctx->send_buf) {
                ret = -ENOMEM;
                goto out;
                        fput(sctx->send_filp);
 
                kvfree(sctx->clone_roots);
+               kfree(sctx->send_buf_pages);
                kvfree(sctx->send_buf);
 
                name_cache_free(sctx);