Lines Matching +full:- +full:n
9 * See the COPYING file in the top-level directory.
30 "0123456789-/_"
81 if (tx->base_tx == *new_tx_id) { in nobble_tx()
83 tx->base_tx = XBT_NULL; in nobble_tx()
93 tx_id = ++s->last_tx; in next_tx()
94 } while (tx_id == XBT_NULL || tx_id == s->root_tx || in next_tx()
95 g_hash_table_lookup(s->transactions, GINT_TO_POINTER(tx_id))); in next_tx()
99 * is based on the (previous incarnation of the) newly-allocated TX id. in next_tx()
101 g_hash_table_foreach(s->transactions, nobble_tx, &tx_id); in next_tx()
108 XsNode *n = g_new0(XsNode, 1); in xs_node_new() local
109 n->ref = 1; in xs_node_new()
113 xs_node_list = g_list_prepend(xs_node_list, n); in xs_node_new()
115 return n; in xs_node_new()
118 static inline XsNode *xs_node_ref(XsNode *n) in xs_node_ref() argument
121 g_assert(n->ref < INT_MAX); in xs_node_ref()
123 g_assert(n->ref); in xs_node_ref()
124 n->ref++; in xs_node_ref()
125 return n; in xs_node_ref()
128 static inline void xs_node_unref(XsNode *n) in xs_node_unref() argument
130 if (!n) { in xs_node_unref()
133 g_assert(n->ref); in xs_node_unref()
134 if (--n->ref) { in xs_node_unref()
138 if (n->content) { in xs_node_unref()
139 g_byte_array_unref(n->content); in xs_node_unref()
141 if (n->perms) { in xs_node_unref()
142 g_list_free_full(n->perms, g_free); in xs_node_unref()
144 if (n->children) { in xs_node_unref()
145 g_hash_table_unref(n->children); in xs_node_unref()
148 g_free(n->name); in xs_node_unref()
149 nr_xs_nodes--; in xs_node_unref()
150 xs_node_list = g_list_remove(xs_node_list, n); in xs_node_unref()
152 g_free(n); in xs_node_unref()
171 letter = 'n'; in xs_perm_as_string()
185 XsNode *n = xs_node_new(); in xs_node_create() local
189 n->name = g_strdup(name); in xs_node_create()
193 n->perms = g_list_copy_deep(perms, do_perm_copy, NULL); in xs_node_create()
195 return n; in xs_node_create()
206 XsNode *n = xs_node_new(); in xs_node_copy() local
208 n->gencnt = old->gencnt; in xs_node_copy()
211 if (n->name) { in xs_node_copy()
212 n->name = g_strdup(old->name); in xs_node_copy()
217 if (old->children) { in xs_node_copy()
218 n->children = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, in xs_node_copy()
220 g_hash_table_foreach(old->children, do_child_insert, n->children); in xs_node_copy()
222 if (old->perms) { in xs_node_copy()
223 n->perms = g_list_copy_deep(old->perms, do_perm_copy, NULL); in xs_node_copy()
225 if (old->content) { in xs_node_copy()
226 n->content = g_byte_array_ref(old->content); in xs_node_copy()
228 return n; in xs_node_copy()
232 static bool xs_node_add_child(XsNode *n, const char *path_elem, XsNode *child) in xs_node_add_child() argument
237 assert(n->children); in xs_node_add_child()
238 return g_hash_table_remove(n->children, path_elem); in xs_node_add_child()
242 g_free(child->name); in xs_node_add_child()
243 child->name = g_strdup(path_elem); in xs_node_add_child()
245 if (!n->children) { in xs_node_add_child()
246 n->children = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, in xs_node_add_child()
257 return g_hash_table_insert(n->children, g_strdup(path_elem), child); in xs_node_add_child()
263 int (*op_fn)(XsNode **n, struct walk_op *op);
298 if (!op->mutating || op->in_transaction) { in fire_watches()
303 l = op->watches; in fire_watches()
306 w = g_hash_table_lookup(op->s->watches, op->path); in fire_watches()
310 w = l->data; in fire_watches()
311 l = l->next; in fire_watches()
315 assert(strlen(op->path) > w->rel_prefix); in fire_watches()
316 w->cb(w->cb_opaque, op->path + w->rel_prefix, w->token); in fire_watches()
318 w = w->next; in fire_watches()
322 static int xs_node_add_content(XsNode **n, struct walk_op *op) in xs_node_add_content() argument
324 GByteArray *data = op->op_opaque; in xs_node_add_content()
326 if (op->dom_id) { in xs_node_add_content()
332 if (data->len > XS_MAX_NODE_SIZE) { in xs_node_add_content()
337 if (!op->inplace) { in xs_node_add_content()
338 XsNode *old = *n; in xs_node_add_content()
339 *n = xs_node_copy(old); in xs_node_add_content()
343 if ((*n)->content) { in xs_node_add_content()
344 g_byte_array_unref((*n)->content); in xs_node_add_content()
346 (*n)->content = g_byte_array_ref(data); in xs_node_add_content()
347 if (op->tx_id != XBT_NULL) { in xs_node_add_content()
348 (*n)->modified_in_tx = true; in xs_node_add_content()
353 static int xs_node_get_content(XsNode **n, struct walk_op *op) in xs_node_get_content() argument
355 GByteArray *data = op->op_opaque; in xs_node_get_content()
358 assert(op->inplace); in xs_node_get_content()
359 assert(*n); in xs_node_get_content()
361 node_data = (*n)->content; in xs_node_get_content()
363 g_byte_array_append(data, node_data->data, node_data->len); in xs_node_get_content()
372 int path_len = strlen(op->path); in node_rm_recurse()
374 XsNode *n = value; in node_rm_recurse() local
375 bool this_inplace = op->inplace; in node_rm_recurse()
377 if (n->ref != 1) { in node_rm_recurse()
378 op->inplace = 0; in node_rm_recurse()
381 assert(key_len + path_len + 2 <= sizeof(op->path)); in node_rm_recurse()
382 op->path[path_len] = '/'; in node_rm_recurse()
383 memcpy(op->path + path_len + 1, key, key_len + 1); in node_rm_recurse()
385 if (n->children) { in node_rm_recurse()
386 g_hash_table_foreach_remove(n->children, node_rm_recurse, op); in node_rm_recurse()
388 op->new_nr_nodes--; in node_rm_recurse()
395 op->path[path_len] = '\0'; in node_rm_recurse()
411 GHashTable *siblings = op->op_opaque2; in copy_deleted_recurse()
412 XsNode *n = xs_node_copy_deleted(value, op); in copy_deleted_recurse() local
416 * 'children' hash table. Having stashed it from op->op_opaque2 in copy_deleted_recurse()
420 g_hash_table_insert(siblings, g_strdup(key), n); in copy_deleted_recurse()
425 XsNode *n = xs_node_new(); in xs_node_copy_deleted() local
427 n->gencnt = old->gencnt; in xs_node_copy_deleted()
430 if (old->name) { in xs_node_copy_deleted()
431 n->name = g_strdup(old->name); in xs_node_copy_deleted()
435 if (old->children) { in xs_node_copy_deleted()
436 n->children = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, in xs_node_copy_deleted()
438 op->op_opaque2 = n->children; in xs_node_copy_deleted()
439 g_hash_table_foreach(old->children, copy_deleted_recurse, op); in xs_node_copy_deleted()
441 if (old->perms) { in xs_node_copy_deleted()
442 n->perms = g_list_copy_deep(old->perms, do_perm_copy, NULL); in xs_node_copy_deleted()
444 n->deleted_in_tx = true; in xs_node_copy_deleted()
446 if (old->content) { in xs_node_copy_deleted()
447 n->modified_in_tx = true; in xs_node_copy_deleted()
449 op->new_nr_nodes--; in xs_node_copy_deleted()
450 return n; in xs_node_copy_deleted()
453 static int xs_node_rm(XsNode **n, struct walk_op *op) in xs_node_rm() argument
455 bool this_inplace = op->inplace; in xs_node_rm()
457 if (op->tx_id != XBT_NULL) { in xs_node_rm()
459 XsNode *old = *n; in xs_node_rm()
460 *n = xs_node_copy_deleted(old, op); in xs_node_rm()
466 if ((*n)->children) { in xs_node_rm()
467 g_hash_table_foreach_remove((*n)->children, node_rm_recurse, op); in xs_node_rm()
469 op->new_nr_nodes--; in xs_node_rm()
472 xs_node_unref(*n); in xs_node_rm()
474 *n = NULL; in xs_node_rm()
478 static int xs_node_get_perms(XsNode **n, struct walk_op *op) in xs_node_get_perms() argument
480 GList **perms = op->op_opaque; in xs_node_get_perms()
482 assert(op->inplace); in xs_node_get_perms()
483 assert(*n); in xs_node_get_perms()
485 *perms = g_list_copy_deep((*n)->perms, do_perm_copy, NULL); in xs_node_get_perms()
491 unsigned int n = sscanf(perm, "%c%u", letter, dom_id); in parse_perm() local
493 assert(n == 2); in parse_perm()
498 unsigned int i, n; in can_access() local
507 n = g_list_length(perms); in can_access()
508 assert(n >= 1); in can_access()
512 * read-write access. in can_access()
524 for (i = 1; i < n; i++) { in can_access()
535 static int xs_node_set_perms(XsNode **n, struct walk_op *op) in xs_node_set_perms() argument
537 GList *perms = op->op_opaque; in xs_node_set_perms()
539 if (op->dom_id) { in xs_node_set_perms()
544 if (!can_access(op->dom_id, (*n)->perms, "")) { in xs_node_set_perms()
549 parse_perm(perms->data, &perm_letter, &perm_dom_id); in xs_node_set_perms()
550 if (perm_dom_id != op->dom_id) { in xs_node_set_perms()
560 if (!op->inplace) { in xs_node_set_perms()
561 XsNode *old = *n; in xs_node_set_perms()
562 *n = xs_node_copy(old); in xs_node_set_perms()
566 if ((*n)->perms) { in xs_node_set_perms()
567 g_list_free_full((*n)->perms, g_free); in xs_node_set_perms()
569 (*n)->perms = g_list_copy_deep(perms, do_perm_copy, NULL); in xs_node_set_perms()
570 if (op->tx_id != XBT_NULL) { in xs_node_set_perms()
571 (*n)->modified_in_tx = true; in xs_node_set_perms()
577 * Passed a full reference in *n which it may free if it needs to COW.
579 * When changing the tree, the op->inplace flag indicates whether this
582 * refcount is higher, we must clear op->inplace and COW from there
584 * (which works like 'mkdir -p' does). In which case those newly
587 static int xs_node_walk(XsNode **n, struct walk_op *op) in xs_node_walk() argument
591 XsNode *old = *n, *child = NULL; in xs_node_walk()
597 namelen = strlen(op->path); in xs_node_walk()
598 watch = g_hash_table_lookup(op->s->watches, op->path); in xs_node_walk()
600 /* Is there a child, or do we hit the double-NUL termination? */ in xs_node_walk()
601 if (op->path[namelen + 1]) { in xs_node_walk()
603 child_name = op->path + namelen + 1; in xs_node_walk()
608 op->path[namelen] = '/'; in xs_node_walk()
612 if (op->mutating && old->ref != 1) { in xs_node_walk()
613 op->inplace = false; in xs_node_walk()
617 const char *letters = op->mutating ? "wb" : "rb"; in xs_node_walk()
619 if (!can_access(op->dom_id, old->perms, letters)) { in xs_node_walk()
625 err = op->op_fn(n, op); in xs_node_walk()
632 /* op->inplace will be further modified during the recursion */ in xs_node_walk()
633 this_inplace = op->inplace; in xs_node_walk()
635 if (old && old->children) { in xs_node_walk()
636 child = g_hash_table_lookup(old->children, child_name); in xs_node_walk()
641 if (child->deleted_in_tx) { in xs_node_walk()
642 assert(child->ref == 1); in xs_node_walk()
643 /* Cannot actually set child->deleted_in_tx = false until later */ in xs_node_walk()
652 if (op->mutating && this_inplace) { in xs_node_walk()
653 g_hash_table_remove(old->children, child_name); in xs_node_walk()
656 } else if (op->create_dirs) { in xs_node_walk()
657 assert(op->mutating); in xs_node_walk()
659 if (!can_access(op->dom_id, old->perms, "wb")) { in xs_node_walk()
664 if (op->dom_id && op->new_nr_nodes >= XS_MAX_DOMAIN_NODES) { in xs_node_walk()
669 child = xs_node_create(child_name, old->perms); in xs_node_walk()
670 op->new_nr_nodes++; in xs_node_walk()
676 op->inplace = true; in xs_node_walk()
687 op->watches = g_list_append(op->watches, watch); in xs_node_walk()
691 * Except for the temporary child-stealing as noted, our node has not in xs_node_walk()
697 op->watches = g_list_remove(op->watches, watch); in xs_node_walk()
700 if (err || !op->mutating) { in xs_node_walk()
703 g_hash_table_replace(old->children, g_strdup(child_name), child); in xs_node_walk()
716 *n = xs_node_copy(old); in xs_node_walk()
724 if (op->create_dirs && child && child->deleted_in_tx) { in xs_node_walk()
725 op->new_nr_nodes++; in xs_node_walk()
726 child->deleted_in_tx = false; in xs_node_walk()
739 if ((xs_node_add_child(*n, child_name, child) && !stole_child) || !child) { in xs_node_walk()
740 (*n)->gencnt++; in xs_node_walk()
744 op->path[namelen] = '\0'; in xs_node_walk()
746 assert(!op->watches); in xs_node_walk()
754 if (!err && op->mutating) { in xs_node_walk()
755 if (!op->in_transaction) { in xs_node_walk()
756 if (op->s->root_tx != op->s->last_tx) { in xs_node_walk()
757 op->s->root_tx = next_tx(op->s); in xs_node_walk()
759 op->s->nr_nodes = op->new_nr_nodes; in xs_node_walk()
761 XsTransaction *tx = g_hash_table_lookup(op->s->transactions, in xs_node_walk()
762 GINT_TO_POINTER(op->tx_id)); in xs_node_walk()
764 tx->nr_nodes = op->new_nr_nodes; in xs_node_walk()
780 static int xs_node_directory(XsNode **n, struct walk_op *op) in xs_node_directory() argument
782 GList **items = op->op_opaque; in xs_node_directory()
784 assert(op->inplace); in xs_node_directory()
785 assert(*n); in xs_node_directory()
787 if ((*n)->children) { in xs_node_directory()
788 g_hash_table_foreach((*n)->children, append_directory_item, items); in xs_node_directory()
791 if (op->op_opaque2) { in xs_node_directory()
792 *(uint64_t *)op->op_opaque2 = (*n)->gencnt; in xs_node_directory()
831 int ret = validate_path(op->path, path, dom_id); in init_walk_op()
841 op->path[strlen(op->path) + 1] = '\0'; in init_walk_op()
842 op->watches = NULL; in init_walk_op()
843 op->path[0] = '\0'; in init_walk_op()
844 op->inplace = true; in init_walk_op()
845 op->mutating = false; in init_walk_op()
846 op->create_dirs = false; in init_walk_op()
847 op->in_transaction = false; in init_walk_op()
848 op->dom_id = dom_id; in init_walk_op()
849 op->tx_id = tx_id; in init_walk_op()
850 op->s = s; in init_walk_op()
853 *rootp = &s->root; in init_walk_op()
854 op->new_nr_nodes = s->nr_nodes; in init_walk_op()
856 XsTransaction *tx = g_hash_table_lookup(s->transactions, in init_walk_op()
861 *rootp = &tx->root; in init_walk_op()
862 op->new_nr_nodes = tx->nr_nodes; in init_walk_op()
863 op->in_transaction = true; in init_walk_op()
877 XsNode **n; in xs_impl_read() local
880 ret = init_walk_op(s, &op, tx_id, dom_id, path, &n); in xs_impl_read()
886 return xs_node_walk(n, &op); in xs_impl_read()
897 XsNode **n; in xs_impl_write() local
900 ret = init_walk_op(s, &op, tx_id, dom_id, path, &n); in xs_impl_write()
908 return xs_node_walk(n, &op); in xs_impl_write()
921 XsNode **n; in xs_impl_directory() local
924 ret = init_walk_op(s, &op, tx_id, dom_id, path, &n); in xs_impl_directory()
931 return xs_node_walk(n, &op); in xs_impl_directory()
943 if (dom_id && s->nr_domu_transactions >= XS_MAX_TRANSACTIONS) { in xs_impl_transaction_start()
949 tx->nr_nodes = s->nr_nodes; in xs_impl_transaction_start()
950 tx->tx_id = next_tx(s); in xs_impl_transaction_start()
951 tx->base_tx = s->root_tx; in xs_impl_transaction_start()
952 tx->root = xs_node_ref(s->root); in xs_impl_transaction_start()
953 tx->dom_id = dom_id; in xs_impl_transaction_start()
955 g_hash_table_insert(s->transactions, GINT_TO_POINTER(tx->tx_id), tx); in xs_impl_transaction_start()
957 s->nr_domu_transactions++; in xs_impl_transaction_start()
959 *tx_id = tx->tx_id; in xs_impl_transaction_start()
967 int path_len = strlen(op->path); in tx_commit_walk()
971 XsNode *n = value; in tx_commit_walk() local
973 if (n->ref != 1) { in tx_commit_walk()
977 if (n->deleted_in_tx) { in tx_commit_walk()
983 fire_parents = !op->deleted_in_tx; in tx_commit_walk()
986 op->deleted_in_tx = true; in tx_commit_walk()
989 assert(key_len + path_len + 2 <= sizeof(op->path)); in tx_commit_walk()
990 op->path[path_len] = '/'; in tx_commit_walk()
991 memcpy(op->path + path_len + 1, key, key_len + 1); in tx_commit_walk()
993 watch = g_hash_table_lookup(op->s->watches, op->path); in tx_commit_walk()
995 op->watches = g_list_append(op->watches, watch); in tx_commit_walk()
998 if (n->children) { in tx_commit_walk()
999 g_hash_table_foreach_remove(n->children, tx_commit_walk, op); in tx_commit_walk()
1003 op->watches = g_list_remove(op->watches, watch); in tx_commit_walk()
1011 if (n->modified_in_tx || n->deleted_in_tx) { in tx_commit_walk()
1013 n->modified_in_tx = false; in tx_commit_walk()
1015 op->path[path_len] = '\0'; in tx_commit_walk()
1018 return n->deleted_in_tx; in tx_commit_walk()
1024 XsNode **n; in transaction_commit() local
1027 if (s->root_tx != tx->base_tx) { in transaction_commit()
1030 xs_node_unref(s->root); in transaction_commit()
1031 s->root = tx->root; in transaction_commit()
1032 tx->root = NULL; in transaction_commit()
1033 s->root_tx = tx->tx_id; in transaction_commit()
1034 s->nr_nodes = tx->nr_nodes; in transaction_commit()
1036 ret = init_walk_op(s, &op, XBT_NULL, tx->dom_id, "/", &n); in transaction_commit()
1042 * trying to do is fire the resulting watches on newly-committed nodes. in transaction_commit()
1053 if (s->root->children) { in transaction_commit()
1054 g_hash_table_foreach_remove(s->root->children, tx_commit_walk, &op); in transaction_commit()
1064 XsTransaction *tx = g_hash_table_lookup(s->transactions, in xs_impl_transaction_end()
1067 if (!tx || tx->dom_id != dom_id) { in xs_impl_transaction_end()
1075 g_hash_table_remove(s->transactions, GINT_TO_POINTER(tx_id)); in xs_impl_transaction_end()
1077 assert(s->nr_domu_transactions); in xs_impl_transaction_end()
1078 s->nr_domu_transactions--; in xs_impl_transaction_end()
1087 XsNode **n; in xs_impl_rm() local
1090 ret = init_walk_op(s, &op, tx_id, dom_id, path, &n); in xs_impl_rm()
1096 return xs_node_walk(n, &op); in xs_impl_rm()
1103 XsNode **n; in xs_impl_get_perms() local
1106 ret = init_walk_op(s, &op, tx_id, dom_id, path, &n); in xs_impl_get_perms()
1112 return xs_node_walk(n, &op); in xs_impl_get_perms()
1132 case 'n': in is_valid_perm()
1148 XsNode **n; in xs_impl_set_perms() local
1161 ret = init_walk_op(s, &op, tx_id, dom_id, path, &n); in xs_impl_set_perms()
1168 return xs_node_walk(n, &op); in xs_impl_set_perms()
1186 l = w = g_hash_table_lookup(s->watches, abspath); in do_xs_impl_watch()
1188 if (!g_strcmp0(token, w->token) && opaque == w->cb_opaque && in do_xs_impl_watch()
1189 fn == w->cb && dom_id == w->dom_id) { in do_xs_impl_watch()
1192 w = w->next; in do_xs_impl_watch()
1195 if (dom_id && s->nr_domu_watches >= XS_MAX_WATCHES) { in do_xs_impl_watch()
1200 w->token = g_strdup(token); in do_xs_impl_watch()
1201 w->cb = fn; in do_xs_impl_watch()
1202 w->cb_opaque = opaque; in do_xs_impl_watch()
1203 w->dom_id = dom_id; in do_xs_impl_watch()
1204 w->rel_prefix = strlen(abspath) - strlen(path); in do_xs_impl_watch()
1208 w->next = l->next; in do_xs_impl_watch()
1209 l->next = w; in do_xs_impl_watch()
1211 g_hash_table_insert(s->watches, g_strdup(abspath), w); in do_xs_impl_watch()
1214 s->nr_domu_watches++; in do_xs_impl_watch()
1235 XsWatch *next = w->next; in free_watch()
1237 if (w->dom_id) { in free_watch()
1238 assert(s->nr_domu_watches); in free_watch()
1239 s->nr_domu_watches--; in free_watch()
1242 g_free(w->token); in free_watch()
1261 w = g_hash_table_lookup(s->watches, abspath); in xs_impl_unwatch()
1272 if (!g_strcmp0(token, w->token) && fn == w->cb && opaque == w->cb_opaque && in xs_impl_unwatch()
1273 dom_id == w->dom_id) { in xs_impl_unwatch()
1274 if (w->next) { in xs_impl_unwatch()
1276 g_hash_table_insert(s->watches, g_strdup(abspath), w->next); in xs_impl_unwatch()
1279 g_hash_table_remove(s->watches, abspath); in xs_impl_unwatch()
1290 for (l = &w->next; *l; l = &w->next) { in xs_impl_unwatch()
1293 if (!g_strcmp0(token, w->token) && fn == w->cb && in xs_impl_unwatch()
1294 opaque != w->cb_opaque && dom_id == w->dom_id) { in xs_impl_unwatch()
1309 watch_paths = (char **)g_hash_table_get_keys_as_array(s->watches, in xs_impl_reset_watches()
1313 XsWatch *w1 = g_hash_table_lookup(s->watches, watch_paths[i]); in xs_impl_reset_watches()
1318 * w2 is the head of our newly-filtered list. in xs_impl_reset_watches()
1326 if (w->dom_id == dom_id) { in xs_impl_reset_watches()
1329 w2 = w->next; in xs_impl_reset_watches()
1333 l = &w->next; in xs_impl_reset_watches()
1342 g_hash_table_steal(s->watches, watch_paths[i]); in xs_impl_reset_watches()
1346 * single-threaded and nobody saw it in the meantime). And in xs_impl_reset_watches()
1352 g_hash_table_insert(s->watches, watch_paths[i], w2); in xs_impl_reset_watches()
1365 if (tx->root) { in xs_tx_free()
1366 xs_node_unref(tx->root); in xs_tx_free()
1376 s->watches = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); in xs_impl_create()
1377 s->transactions = g_hash_table_new_full(g_direct_hash, g_direct_equal, in xs_impl_create()
1381 s->root = xs_node_create("/", perms); in xs_impl_create()
1383 s->nr_nodes = 1; in xs_impl_create()
1385 s->root_tx = s->last_tx = 1; in xs_impl_create()
1392 XsNode *n = value; in clear_serialized_tx() local
1394 n->serialized_tx = XBT_NULL; in clear_serialized_tx()
1395 if (n->children) { in clear_serialized_tx()
1396 g_hash_table_foreach(n->children, clear_serialized_tx, NULL); in clear_serialized_tx()
1405 clear_serialized_tx(NULL, t->root, NULL); in clear_tx_serialized_tx()
1427 XsNode *n = value; in save_node() local
1433 g_byte_array_append(ss->bytes, key, strlen(key) + 1); in save_node()
1442 if (n->serialized_tx != XBT_NULL) { in save_node()
1444 g_byte_array_append(ss->bytes, &flag, 1); in save_node()
1445 write_be32(ss->bytes, n->serialized_tx); in save_node()
1448 n->serialized_tx = ss->tx_id; in save_node()
1450 if (n->modified_in_tx) { in save_node()
1453 if (n->deleted_in_tx) { in save_node()
1456 g_byte_array_append(ss->bytes, &flag, 1); in save_node()
1458 if (n->content) { in save_node()
1459 write_be32(ss->bytes, n->content->len); in save_node()
1460 g_byte_array_append(ss->bytes, n->content->data, n->content->len); in save_node()
1462 write_be32(ss->bytes, 0); in save_node()
1465 for (l = n->perms; l; l = l->next) { in save_node()
1466 g_byte_array_append(ss->bytes, l->data, strlen(l->data) + 1); in save_node()
1469 g_byte_array_append(ss->bytes, (void *)"", 1); in save_node()
1471 if (n->children) { in save_node()
1472 g_hash_table_foreach(n->children, save_node, ss); in save_node()
1475 g_byte_array_append(ss->bytes, (void *)"", 1); in save_node()
1481 write_be32(ss->bytes, tx_id); in save_tree()
1482 ss->tx_id = tx_id; in save_tree()
1490 XsTransaction *n = value; in save_tx() local
1492 write_be32(ss->bytes, n->base_tx); in save_tx()
1493 write_be32(ss->bytes, n->dom_id); in save_tx()
1495 save_tree(ss, tx_id, n->root); in save_tx()
1504 if (w->dom_id) { in save_watch()
1505 gpointer relpath = key + w->rel_prefix; in save_watch()
1506 g_byte_array_append(ss->bytes, relpath, strlen(relpath) + 1); in save_watch()
1507 g_byte_array_append(ss->bytes, (void *)w->token, strlen(w->token) + 1); in save_watch()
1550 if (s->serialized) { in xs_impl_serialize()
1551 clear_serialized_tx(NULL, s->root, NULL); in xs_impl_serialize()
1552 g_hash_table_foreach(s->transactions, clear_tx_serialized_tx, NULL); in xs_impl_serialize()
1555 s->serialized = true; in xs_impl_serialize()
1557 write_be32(ss.bytes, s->last_tx); in xs_impl_serialize()
1558 save_tree(&ss, s->root_tx, s->root); in xs_impl_serialize()
1559 g_hash_table_foreach(s->transactions, save_tx, &ss); in xs_impl_serialize()
1563 g_hash_table_foreach(s->watches, save_watch, &ss); in xs_impl_serialize()
1582 if (us->l < sizeof(d)) { in consume_be32()
1583 return -EINVAL; in consume_be32()
1585 memcpy(&d, us->d, sizeof(d)); in consume_be32()
1587 us->d += sizeof(d); in consume_be32()
1588 us->l -= sizeof(d); in consume_be32()
1596 if (!us->l) { in consume_string()
1597 return -EINVAL; in consume_string()
1600 l = strnlen((void *)us->d, us->l); in consume_string()
1601 if (l == us->l) { in consume_string()
1602 return -EINVAL; in consume_string()
1606 *str = (void *)us->d; in consume_string()
1612 us->d += l + 1; in consume_string()
1613 us->l -= l + 1; in consume_string()
1617 static XsNode *lookup_node(XsNode *n, char *path) in lookup_node() argument
1623 return n; in lookup_node()
1630 if (!n->children) { in lookup_node()
1633 child = g_hash_table_lookup(n->children, path); in lookup_node()
1648 if (tx_id == us->s->root_tx) { in lookup_tx_node()
1649 return lookup_node(us->s->root, us->path + 1); in lookup_tx_node()
1652 t = g_hash_table_lookup(us->s->transactions, GINT_TO_POINTER(tx_id)); in lookup_tx_node()
1656 g_assert(t->root); in lookup_tx_node()
1657 return lookup_node(t->root, us->path + 1); in lookup_tx_node()
1663 XsNode *n = value; in count_child_nodes() local
1667 if (n->children) { in count_child_nodes()
1668 g_hash_table_foreach(n->children, count_child_nodes, nr_nodes); in count_child_nodes()
1675 XsNode *n = NULL; in consume_node() local
1679 if (us->l < 1) { in consume_node()
1680 return -EINVAL; in consume_node()
1682 flags = us->d[0]; in consume_node()
1683 us->d++; in consume_node()
1684 us->l--; in consume_node()
1694 n = lookup_tx_node(us, tx); in consume_node()
1695 if (!n) { in consume_node()
1696 return -EINVAL; in consume_node()
1698 n->ref++; in consume_node()
1699 if (n->children) { in consume_node()
1700 g_hash_table_foreach(n->children, count_child_nodes, nr_nodes); in consume_node()
1706 return -EINVAL; in consume_node()
1708 n = xs_node_new(); in consume_node()
1711 n->deleted_in_tx = true; in consume_node()
1714 n->modified_in_tx = true; in consume_node()
1718 xs_node_unref(n); in consume_node()
1719 return -EINVAL; in consume_node()
1722 if (datalen > us->l) { in consume_node()
1723 xs_node_unref(n); in consume_node()
1724 return -EINVAL; in consume_node()
1728 g_byte_array_append(node_data, us->d, datalen); in consume_node()
1729 us->d += datalen; in consume_node()
1730 us->l -= datalen; in consume_node()
1731 n->content = node_data; in consume_node()
1733 if (us->root_walk) { in consume_node()
1734 n->modified_in_tx = true; in consume_node()
1743 xs_node_unref(n); in consume_node()
1751 n->perms = g_list_append(n->perms, g_strdup(perm)); in consume_node()
1763 xs_node_unref(n); in consume_node()
1771 pathend = us->path + strlen(us->path); in consume_node()
1772 strncat(us->path, "/", sizeof(us->path) - 1); in consume_node()
1773 strncat(us->path, childname, sizeof(us->path) - 1); in consume_node()
1778 xs_node_unref(n); in consume_node()
1782 xs_node_add_child(n, childname, child); in consume_node()
1789 if (us->root_walk && !n->children) { in consume_node()
1790 n->modified_in_tx = true; in consume_node()
1794 if (!n->deleted_in_tx) { in consume_node()
1798 *nodep = n; in consume_node()
1806 ret = consume_be32(us, &t->tx_id); in consume_tree()
1811 if (t->tx_id > us->s->last_tx) { in consume_tree()
1812 return -EINVAL; in consume_tree()
1815 us->path[0] = '\0'; in consume_tree()
1817 return consume_node(us, &t->root, &t->nr_nodes); in consume_tree()
1830 us.d = bytes->data; in xs_impl_deserialize()
1831 us.l = bytes->len; in xs_impl_deserialize()
1834 g_hash_table_remove_all(s->transactions); in xs_impl_deserialize()
1836 xs_node_unref(s->root); in xs_impl_deserialize()
1837 s->root = NULL; in xs_impl_deserialize()
1838 s->root_tx = s->last_tx = XBT_NULL; in xs_impl_deserialize()
1840 ret = consume_be32(&us, &s->last_tx); in xs_impl_deserialize()
1888 t->base_tx = base_tx; in xs_impl_deserialize()
1890 ret = consume_be32(&us, &t->dom_id); in xs_impl_deserialize()
1898 g_assert(t->root); in xs_impl_deserialize()
1899 if (t->dom_id) { in xs_impl_deserialize()
1900 s->nr_domu_transactions++; in xs_impl_deserialize()
1902 g_hash_table_insert(s->transactions, GINT_TO_POINTER(t->tx_id), t); in xs_impl_deserialize()
1933 return -EINVAL; in xs_impl_deserialize()