]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
XArray: Fix xa_reserve for 2-byte aligned entries
authorMatthew Wilcox <willy@infradead.org>
Thu, 21 Feb 2019 22:54:44 +0000 (17:54 -0500)
committerMatthew Wilcox <willy@infradead.org>
Thu, 21 Feb 2019 22:54:44 +0000 (17:54 -0500)
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: Matthew Wilcox <willy@infradead.org>
lib/test_xarray.c
lib/xarray.c

index bc202d468a6b0817ad1ca9fd1e23c420f77aeb0c..5d4bad8bd96a0621018f6dc8aaa5f4b73305decb 100644 (file)
@@ -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));
 }
 
index 2cc3798672f7dcc790d9147f1ca9b7f2ed90cb02..6be3acbb861f3388863212616828136a303c0bc3 100644 (file)
@@ -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;