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)
{
int ret;
void *data;
- int len;
+ int len = 0;
TLV_GET(s, attr, &data, &len);
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;
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;
}
out:
+ if (last_err && !ret)
+ ret = last_err;
+
return ret;
}