send deltas when requesting packed object extraction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
diff --git a/lib/privsep.c b/lib/privsep.c
index fbd2510..74df15b 100644
--- a/lib/privsep.c
+++ b/lib/privsep.c
@@ -214,9 +214,49 @@ got_privsep_send_stop(int fd)
return err;
}
+static const struct got_error *
+send_delta(struct got_delta *delta, struct imsgbuf *ibuf)
+{
+ struct got_imsg_delta idelta;
+ size_t offset, remain;
+
+ idelta.offset = delta->offset;
+ idelta.tslen = delta->tslen;
+ idelta.type = delta->type;
+ idelta.size = delta->size;
+ idelta.data_offset = delta->data_offset;
+ idelta.delta_len = delta->delta_len;
+
+ if (imsg_compose(ibuf, GOT_IMSG_DELTA, 0, 0, -1,
+ &idelta, sizeof(idelta)) == -1)
+ return got_error_from_errno();
+
+ if (imsg_flush(ibuf) == -1)
+ return got_error_from_errno();
+
+ offset = 0;
+ remain = delta->delta_len;
+ while (remain > 0) {
+ size_t n = MIN(MAX_IMSGSIZE - IMSG_HEADER_SIZE, remain);
+
+ if (imsg_compose(ibuf, GOT_IMSG_DELTA_STREAM, 0, 0, -1,
+ delta->delta_buf + offset, n) == -1)
+ return got_error_from_errno();
+
+ if (imsg_flush(ibuf) == -1)
+ return got_error_from_errno();
+
+ offset += n;
+ remain -= n;
+ }
+
+ return NULL;
+}
+
const struct got_error *
got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
{
+ const struct got_error *err = NULL;
struct got_imsg_object iobj, *iobjp = NULL;
size_t iobj_size = 0;
int imsg_code = GOT_IMSG_OBJECT_REQUEST;
@@ -229,6 +269,7 @@ got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
case GOT_OBJ_TYPE_COMMIT:
imsg_code = GOT_IMSG_COMMIT_REQUEST;
break;
+ /* Blobs are handled in got_privsep_send_blob_req(). */
default:
return got_error(GOT_ERR_OBJ_TYPE);
}
@@ -248,7 +289,20 @@ got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
if (imsg_compose(ibuf, imsg_code, 0, 0, fd, iobjp, iobj_size) == -1)
return got_error_from_errno();
- return flush_imsg(ibuf);
+ err = flush_imsg(ibuf);
+ if (err)
+ return err;
+
+ if (obj && obj->flags & GOT_OBJ_FLAG_DELTIFIED) {
+ struct got_delta *delta;
+ SIMPLEQ_FOREACH(delta, &obj->deltas.entries, entry) {
+ err = send_delta(delta, ibuf);
+ if (err)
+ break;
+ }
+ }
+
+ return err;
}
const struct got_error *
@@ -278,45 +332,6 @@ got_privsep_send_blob_req(struct imsgbuf *ibuf, int outfd, int infd)
return flush_imsg(ibuf);
}
-static const struct got_error *
-send_delta(struct got_delta *delta, struct imsgbuf *ibuf)
-{
- struct got_imsg_delta idelta;
- size_t offset, remain;
-
- idelta.offset = delta->offset;
- idelta.tslen = delta->tslen;
- idelta.type = delta->type;
- idelta.size = delta->size;
- idelta.data_offset = delta->data_offset;
- idelta.delta_len = delta->delta_len;
-
- if (imsg_compose(ibuf, GOT_IMSG_DELTA, 0, 0, -1,
- &idelta, sizeof(idelta)) == -1)
- return got_error_from_errno();
-
- if (imsg_flush(ibuf) == -1)
- return got_error_from_errno();
-
- offset = 0;
- remain = delta->delta_len;
- while (remain > 0) {
- size_t n = MIN(MAX_IMSGSIZE - IMSG_HEADER_SIZE, remain);
-
- if (imsg_compose(ibuf, GOT_IMSG_DELTA_STREAM, 0, 0, -1,
- delta->delta_buf + offset, n) == -1)
- return got_error_from_errno();
-
- if (imsg_flush(ibuf) == -1)
- return got_error_from_errno();
-
- offset += n;
- remain -= n;
- }
-
- return NULL;
-}
-
const struct got_error *
got_privsep_send_obj(struct imsgbuf *ibuf, struct got_object *obj)
{