aboutsummaryrefslogtreecommitdiffstats
path: root/lib/xarray.c
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2018-06-01 22:46:02 -0400
committerMatthew Wilcox <willy@infradead.org>2018-10-21 10:45:59 -0400
commit4e99d4e9579d3b950bf4b38d0d64eb1b9be78761 (patch)
treea3ecd9d06b4f0eb8bb05369887c9fbe133218e01 /lib/xarray.c
parent64d3e9a9e0cc51957d243dd2b0adc5d74ff5e128 (diff)
xarray: Add xas_for_each_conflict
This iterator iterates over each entry that is stored in the index or indices specified by the xa_state. This is intended for use for a conditional store of a multiindex entry, or to allow entries which are about to be removed from the xarray to be disposed of properly. Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'lib/xarray.c')
-rw-r--r--lib/xarray.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/xarray.c b/lib/xarray.c
index 303c46579598..41f8ebc651f5 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -1111,6 +1111,67 @@ max:
1111EXPORT_SYMBOL_GPL(xas_find_marked); 1111EXPORT_SYMBOL_GPL(xas_find_marked);
1112 1112
1113/** 1113/**
1114 * xas_find_conflict() - Find the next present entry in a range.
1115 * @xas: XArray operation state.
1116 *
1117 * The @xas describes both a range and a position within that range.
1118 *
1119 * Context: Any context. Expects xa_lock to be held.
1120 * Return: The next entry in the range covered by @xas or %NULL.
1121 */
1122void *xas_find_conflict(struct xa_state *xas)
1123{
1124 void *curr;
1125
1126 if (xas_error(xas))
1127 return NULL;
1128
1129 if (!xas->xa_node)
1130 return NULL;
1131
1132 if (xas_top(xas->xa_node)) {
1133 curr = xas_start(xas);
1134 if (!curr)
1135 return NULL;
1136 while (xa_is_node(curr)) {
1137 struct xa_node *node = xa_to_node(curr);
1138 curr = xas_descend(xas, node);
1139 }
1140 if (curr)
1141 return curr;
1142 }
1143
1144 if (xas->xa_node->shift > xas->xa_shift)
1145 return NULL;
1146
1147 for (;;) {
1148 if (xas->xa_node->shift == xas->xa_shift) {
1149 if ((xas->xa_offset & xas->xa_sibs) == xas->xa_sibs)
1150 break;
1151 } else if (xas->xa_offset == XA_CHUNK_MASK) {
1152 xas->xa_offset = xas->xa_node->offset;
1153 xas->xa_node = xa_parent_locked(xas->xa, xas->xa_node);
1154 if (!xas->xa_node)
1155 break;
1156 continue;
1157 }
1158 curr = xa_entry_locked(xas->xa, xas->xa_node, ++xas->xa_offset);
1159 if (xa_is_sibling(curr))
1160 continue;
1161 while (xa_is_node(curr)) {
1162 xas->xa_node = xa_to_node(curr);
1163 xas->xa_offset = 0;
1164 curr = xa_entry_locked(xas->xa, xas->xa_node, 0);
1165 }
1166 if (curr)
1167 return curr;
1168 }
1169 xas->xa_offset -= xas->xa_sibs;
1170 return NULL;
1171}
1172EXPORT_SYMBOL_GPL(xas_find_conflict);
1173
1174/**
1114 * xa_init_flags() - Initialise an empty XArray with flags. 1175 * xa_init_flags() - Initialise an empty XArray with flags.
1115 * @xa: XArray. 1176 * @xa: XArray.
1116 * @flags: XA_FLAG values. 1177 * @flags: XA_FLAG values.