X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=send-stream.c;h=78f2571ae40be82cbce1b7eb40e80c5293acd6c8;hb=335b7011352bfe27d59094d622abe111177021d4;hp=3720e7dfec0cc382f1f97a5cb1c7f2121b0a957f;hpb=4c066138426be59c9f8c6956f4d02c941042c55c;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/send-stream.c b/send-stream.c index 3720e7d..78f2571 100644 --- a/send-stream.c +++ b/send-stream.c @@ -33,10 +33,23 @@ struct btrfs_send_stream { struct btrfs_tlv_header *cmd_attrs[BTRFS_SEND_A_MAX + 1]; u32 version; + /* + * end of last successful read, equivalent to start of current + * malformated part of block + */ + size_t stream_pos; + struct btrfs_send_ops *ops; void *user; }; +/* + * Read len bytes to buf. + * Return: + * 0 - success + * < 0 - negative errno in case of error + * > 0 - no data read, EOF + */ static int read_buf(struct btrfs_send_stream *sctx, char *buf, size_t len) { int ret; @@ -54,13 +67,20 @@ static int read_buf(struct btrfs_send_stream *sctx, char *buf, size_t len) } if (rbytes == 0) { ret = 1; - goto out; + goto out_eof; } pos += rbytes; } - ret = 0; +out_eof: + if (0 < pos && pos < len) { + error("short read from stream: expected %zu read %zu", len, pos); + ret = -EIO; + } else { + sctx->stream_pos += pos; + } + out: return ret; } @@ -68,11 +88,15 @@ out: /* * Reads a single command from kernel space and decodes the TLV's into * sctx->cmd_attrs + * + * Returns: + * 0 - success + * < 0 - an error in the command */ static int read_cmd(struct btrfs_send_stream *sctx) { int ret; - int cmd; + u16 cmd; u32 cmd_len; char *data; u32 pos; @@ -158,7 +182,7 @@ out: static int tlv_get(struct btrfs_send_stream *sctx, int attr, void **data, int *len) { int ret; - struct btrfs_tlv_header *h; + struct btrfs_tlv_header *hdr; if (attr <= 0 || attr > BTRFS_SEND_A_MAX) { error("invalid attribute requested, attr = %d", attr); @@ -166,15 +190,15 @@ static int tlv_get(struct btrfs_send_stream *sctx, int attr, void **data, int *l goto out; } - h = sctx->cmd_attrs[attr]; - if (!h) { + hdr = sctx->cmd_attrs[attr]; + if (!hdr) { error("attribute %d requested but not present", attr); ret = -ENOENT; goto out; } - *len = le16_to_cpu(h->tlv_len); - *data = h + 1; + *len = le16_to_cpu(hdr->tlv_len); + *data = hdr + 1; ret = 0; @@ -462,12 +486,13 @@ int btrfs_read_and_process_send_stream(int fd, sctx.fd = fd; sctx.ops = ops; sctx.user = user; + sctx.stream_pos = 0; ret = read_buf(&sctx, (char*)&hdr, sizeof(hdr)); if (ret < 0) goto out; if (ret) { - ret = 1; + ret = -ENODATA; goto out; }