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)
break;
case BTRFS_SEND_C_UTIMES:
TLV_GET_STRING(s, BTRFS_SEND_A_PATH, &path);
- if (strstr(path, ".bak_1.log")) {
- ret = 0;
- }
TLV_GET_TIMESPEC(s, BTRFS_SEND_A_ATIME, &at);
TLV_GET_TIMESPEC(s, BTRFS_SEND_A_MTIME, &mt);
TLV_GET_TIMESPEC(s, BTRFS_SEND_A_CTIME, &ct);
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)
+ struct btrfs_send_ops *ops, void *user,
+ 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) {
- ret = 0;
+ 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;
}