btrfs-progs: check: introduce function to check shared block ref
[platform/upstream/btrfs-progs.git] / send-stream.c
index 88e18e2..66c0488 100644 (file)
@@ -204,7 +204,7 @@ out:
                int __len; \
                TLV_GET(s, attr, (void**)&__tmp, &__len); \
                TLV_CHECK_LEN(sizeof(*__tmp), __len); \
-               *v = le##bits##_to_cpu(*__tmp); \
+               *v = get_unaligned_le##bits(__tmp); \
        } while (0)
 
 #define TLV_GET_U8(s, attr, v) TLV_GET_INT(s, attr, 8, v)
@@ -216,7 +216,7 @@ static int tlv_get_string(struct btrfs_send_stream *s, int attr, char **str)
 {
        int ret;
        void *data;
-       int len;
+       int len = 0;
 
        TLV_GET(s, attr, &data, &len);
 
@@ -435,13 +435,21 @@ out:
        return ret;
 }
 
+/*
+ * If max_errors is 0, then don't stop processing the stream if one of the
+ * callbacks in btrfs_send_ops structure returns an error. If greater than
+ * zero, stop after max_errors errors happened.
+ */
 int btrfs_read_and_process_send_stream(int fd,
                                       struct btrfs_send_ops *ops, void *user,
-                                      int honor_end_cmd)
+                                      int honor_end_cmd,
+                                      u64 max_errors)
 {
        int ret;
        struct btrfs_send_stream s;
        struct btrfs_stream_header hdr;
+       u64 errors = 0;
+       int last_err = 0;
 
        s.fd = fd;
        s.ops = ops;
@@ -471,9 +479,12 @@ int btrfs_read_and_process_send_stream(int fd,
 
        while (1) {
                ret = read_and_process_cmd(&s);
-               if (ret < 0)
-                       goto out;
-               if (ret) {
+               if (ret < 0) {
+                       last_err = ret;
+                       errors++;
+                       if (max_errors > 0 && errors >= max_errors)
+                               goto out;
+               } else if (ret > 0) {
                        if (!honor_end_cmd)
                                ret = 0;
                        goto out;
@@ -481,5 +492,8 @@ int btrfs_read_and_process_send_stream(int fd,
        }
 
 out:
+       if (last_err && !ret)
+               ret = last_err;
+
        return ret;
 }