@@ -73,6 +73,7 @@ struct ovsdb_idl_row {
struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */
struct ovsdb_idl_table *table; /* Containing table. */
struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */
+ bool parsed; /* Whether the row is parsed. */
/* Transactional data. */
struct ovsdb_datum *new_datum; /* Modified data (null to delete row). */
@@ -88,6 +89,7 @@ struct ovsdb_idl_row {
unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX];
struct ovs_list track_node; /* Rows modified/added/deleted by IDL */
unsigned long int *updated; /* Bitmap of columns updated by IDL */
+ struct ovsdb_datum *tracked_old_datum; /* Old deleted data. */
};
struct ovsdb_idl_column {
@@ -1828,7 +1828,16 @@ ovsdb_idl_db_track_clear(struct ovsdb_idl_db *db)
}
ovs_list_remove(&row->track_node);
ovs_list_init(&row->track_node);
- if (ovsdb_idl_row_is_orphan(row)) {
+ if (ovsdb_idl_row_is_orphan(row) && row->tracked_old_datum) {
+ ovsdb_idl_row_unparse(row);
+ const struct ovsdb_idl_table_class *class =
+ row->table->class_;
+ for (size_t c = 0; c < class->n_columns; c++) {
+ ovsdb_datum_destroy(&row->tracked_old_datum[c],
+ &class->columns[c].type);
+ }
+ free(row->tracked_old_datum);
+ row->tracked_old_datum = NULL;
free(row);
}
}
@@ -2665,10 +2674,14 @@ ovsdb_idl_row_parse(struct ovsdb_idl_row *row)
const struct ovsdb_idl_table_class *class = row->table->class_;
size_t i;
+ if (row->parsed) {
+ ovsdb_idl_row_unparse(row);
+ }
for (i = 0; i < class->n_columns; i++) {
const struct ovsdb_idl_column *c = &class->columns[i];
(c->parse)(row, &row->old_datum[i]);
}
+ row->parsed = true;
}
static void
@@ -2677,10 +2690,14 @@ ovsdb_idl_row_unparse(struct ovsdb_idl_row *row)
const struct ovsdb_idl_table_class *class = row->table->class_;
size_t i;
+ if (!row->parsed) {
+ return;
+ }
for (i = 0; i < class->n_columns; i++) {
const struct ovsdb_idl_column *c = &class->columns[i];
(c->unparse)(row);
}
+ row->parsed = false;
}
/* The OVSDB-IDL Compound Indexes feature allows for the creation of custom
@@ -3008,13 +3025,18 @@ ovsdb_idl_row_clear_old(struct ovsdb_idl_row *row)
{
ovs_assert(row->old_datum == row->new_datum);
if (!ovsdb_idl_row_is_orphan(row)) {
- const struct ovsdb_idl_table_class *class = row->table->class_;
- size_t i;
+ if (ovsdb_idl_track_is_set(row->table)) {
+ row->tracked_old_datum = row->old_datum;
+ } else {
+ const struct ovsdb_idl_table_class *class = row->table->class_;
+ size_t i;
- for (i = 0; i < class->n_columns; i++) {
- ovsdb_datum_destroy(&row->old_datum[i], &class->columns[i].type);
+ for (i = 0; i < class->n_columns; i++) {
+ ovsdb_datum_destroy(&row->old_datum[i],
+ &class->columns[i].type);
+ }
+ free(row->old_datum);
}
- free(row->old_datum);
row->old_datum = row->new_datum = NULL;
}
}
@@ -3187,6 +3209,7 @@ ovsdb_idl_row_destroy_postprocess(struct ovsdb_idl_db *db)
LIST_FOR_EACH_SAFE(row, next, track_node, &table->track_list) {
if (!ovsdb_idl_track_is_set(row->table)) {
ovs_list_remove(&row->track_node);
+ ovsdb_idl_row_unparse(row);
free(row);
}
}
@@ -3217,7 +3240,6 @@ static void
ovsdb_idl_delete_row(struct ovsdb_idl_row *row)
{
ovsdb_idl_remove_from_indexes(row);
- ovsdb_idl_row_unparse(row);
ovsdb_idl_row_clear_arcs(row, true);
ovsdb_idl_row_clear_old(row);
if (ovs_list_is_empty(&row->dst_arcs)) {