Commit 4a5c8d89 authored by Matthew Wilcox's avatar Matthew Wilcox
Browse files

XArray: Fix xa_reserve for 2-byte aligned entries



If we reserve index 0, the next entry to be stored there might be 2-byte
aligned.  That means we have to create the root xa_node at the time of
reserving the initial entry.

Signed-off-by: default avatarMatthew Wilcox <willy@infradead.org>
parent 2fbe967b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1355,6 +1355,10 @@ static void check_align_1(struct xarray *xa, char *name)
	xa_destroy(xa);
}

/*
 * We should always be able to store without allocating memory after
 * reserving a slot.
 */
static void check_align_2(struct xarray *xa, char *name)
{
	int i;
@@ -1366,6 +1370,12 @@ static void check_align_2(struct xarray *xa, char *name)
		xa_erase(xa, 0);
	}

	for (i = 0; i < 8; i++) {
		XA_BUG_ON(xa, xa_reserve(xa, 0, GFP_KERNEL) != 0);
		XA_BUG_ON(xa, xa_store(xa, 0, name + i, 0) != NULL);
		xa_erase(xa, 0);
	}

	XA_BUG_ON(xa, !xa_empty(xa));
}

+5 −3
Original line number Diff line number Diff line
@@ -767,10 +767,12 @@ void *xas_store(struct xa_state *xas, void *entry)
	void *first, *next;
	bool value = xa_is_value(entry);

	if (entry)
		first = xas_create(xas, !xa_is_node(entry));
	else
	if (entry) {
		bool allow_root = !xa_is_node(entry) && !xa_is_zero(entry);
		first = xas_create(xas, allow_root);
	} else {
		first = xas_load(xas);
	}

	if (xas_invalid(xas))
		return first;