17 Apr, 2020

1 commit

  • commit c36d451ad386b34f452fc3c8621ff14b9eaa31a6 upstream.

    Inspired by the recent Coverity report, I looked for other places where
    the offset wasn't being converted to an unsigned long before being
    shifted, and I found one in xas_pause() when the entry being paused is
    of order >32.

    Fixes: b803b42823d0 ("xarray: Add XArray iterators")
    Signed-off-by: Matthew Wilcox (Oracle)
    Cc: stable@vger.kernel.org
    Signed-off-by: Greg Kroah-Hartman

    Matthew Wilcox (Oracle)
     

08 Apr, 2020

1 commit

  • [ Upstream commit bd40b17ca49d7d110adf456e647701ce74de2241 ]

    Coverity pointed out that xas_sibling() was shifting xa_offset without
    promoting it to an unsigned long first, so the shift could cause an
    overflow and we'd get the wrong answer. The fix is obvious, and the
    new test-case provokes UBSAN to report an error:
    runtime error: shift exponent 60 is too large for 32-bit type 'int'

    Fixes: 19c30f4dd092 ("XArray: Fix xa_find_after with multi-index entries")
    Reported-by: Bjorn Helgaas
    Reported-by: Kees Cook
    Signed-off-by: Matthew Wilcox (Oracle)
    Cc: stable@vger.kernel.org
    Signed-off-by: Sasha Levin

    Matthew Wilcox (Oracle)
     

06 Feb, 2020

1 commit

  • [ Upstream commit 82a22311b7a68a78709699dc8c098953b70e4fd2 ]

    If we were unlucky enough to call xas_pause() when the index was at
    ULONG_MAX (or a multi-slot entry which ends at ULONG_MAX), we would
    wrap the index back around to 0 and restart the iteration from the
    beginning. Use the XAS_BOUNDS state to indicate that we should just
    stop the iteration.

    Signed-off-by: Matthew Wilcox (Oracle)
    Signed-off-by: Sasha Levin

    Matthew Wilcox (Oracle)
     

29 Jan, 2020

3 commits

  • commit c44aa5e8ab58b5f4cf473970ec784c3333496a2e upstream.

    If you call xas_find() with the initial index > max, it should have
    returned NULL but was returning the entry at index.

    Signed-off-by: Matthew Wilcox (Oracle)
    Cc: stable@vger.kernel.org
    Signed-off-by: Greg Kroah-Hartman

    Matthew Wilcox (Oracle)
     
  • commit 19c30f4dd0923ef191f35c652ee4058e91e89056 upstream.

    If the entry is of an order which is a multiple of XA_CHUNK_SIZE,
    the current detection of sibling entries does not work. Factor out
    an xas_sibling() function to make xa_find_after() a little more
    understandable, and write a new implementation that doesn't suffer from
    the same bug.

    Signed-off-by: Matthew Wilcox (Oracle)
    Cc: stable@vger.kernel.org
    Signed-off-by: Greg Kroah-Hartman

    Matthew Wilcox (Oracle)
     
  • commit 430f24f94c8a174d411a550d7b5529301922e67a upstream.

    If there is an entry at ULONG_MAX, xa_for_each() will overflow the
    'index + 1' in xa_find_after() and wrap around to 0. Catch this case
    and terminate the loop by returning NULL.

    Signed-off-by: Matthew Wilcox (Oracle)
    Cc: stable@vger.kernel.org
    Signed-off-by: Greg Kroah-Hartman

    Matthew Wilcox (Oracle)
     

02 Jul, 2019

1 commit

  • If there is only a single entry at 0, the first time we call xas_next(),
    we return the entry. Unfortunately, all subsequent times we call
    xas_next(), we also return the entry at 0 instead of noticing that the
    xa_index is now greater than zero. This broke find_get_pages_contig().

    Fixes: 64d3e9a9e0cc ("xarray: Step through an XArray")
    Reported-by: Kent Overstreet
    Signed-off-by: Matthew Wilcox (Oracle)

    Matthew Wilcox (Oracle)
     

03 Jun, 2019

1 commit


22 Feb, 2019

2 commits


21 Feb, 2019

1 commit

  • xa_cmpxchg() was a little too magic in turning ZERO entries into NULL,
    and would leave the entry set to the ZERO entry instead of releasing
    it for future use. After careful review of existing users of
    xa_cmpxchg(), change the semantics so that it does not translate either
    incoming argument from NULL into ZERO entries.

    Add several tests to the test-suite to make sure this problem doesn't
    come back.

    Reported-by: Jason Gunthorpe
    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     

09 Feb, 2019

1 commit


07 Feb, 2019

4 commits

  • This differs slightly from the IDR equivalent in five ways.

    1. It can allocate up to UINT_MAX instead of being limited to INT_MAX,
    like xa_alloc(). Also like xa_alloc(), it will write to the 'id'
    pointer before placing the entry in the XArray.
    2. The 'next' cursor is allocated separately from the XArray instead
    of being part of the IDR. This saves memory for all the users which
    do not use the cyclic allocation API and suits some users better.
    3. It returns -EBUSY instead of -ENOSPC.
    4. It will attempt to wrap back to the minimum value on memory allocation
    failure as well as on an -EBUSY error, assuming that a user would
    rather allocate a small ID than suffer an ID allocation failure.
    5. It reports whether it has wrapped, which is important to some users.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • It was too easy to forget to initialise the start index. Add an
    xa_limit data structure which can be used to pass min & max, and
    define a couple of special values for common cases. Also add some
    more tests cribbed from the IDR test suite. Change the return value
    from -ENOSPC to -EBUSY to match xa_insert().

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • A lot of places want to allocate IDs starting at 1 instead of 0.
    While the xa_alloc() API supports this, it's not very efficient if lots
    of IDs are allocated, due to having to walk down to the bottom of the
    tree to see if ID 1 is available, then all the way over to the next
    non-allocated ID. This method marks ID 0 as being occupied which wastes
    one slot in the XArray, but preserves xa_empty() as working.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • Userspace translates EEXIST to "File exists" which isn't a very good
    error message for the problem. "Device or resource busy" is a better
    indication of what went wrong.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     

05 Feb, 2019

1 commit


15 Jan, 2019

1 commit

  • We do not currently check that the loop in xas_squash_marks() doesn't have
    an off-by-one error in it. It didn't, but a patch which introduced an
    off-by-one error wasn't caught by any existing test. Switch the roles
    of XA_MARK_1 and XA_MARK_2 to catch that bug.

    Reported-by: Cyrill Gorcunov
    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     

07 Jan, 2019

4 commits

  • xa_insert() should treat reserved entries as occupied, not as available.
    Also, it should treat requests to insert a NULL pointer as a request
    to reserve the slot. Add xa_insert_bh() and xa_insert_irq() for
    completeness.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • On m68k, statically allocated pointers may only be two-byte aligned.
    This clashes with the XArray's method for tagging internal pointers.
    Permit storing these pointers in single slots (ie not in multislots).

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • There were three problems with this API:
    1. It took too many arguments; almost all users wanted to iterate over
    every element in the array rather than a subset.
    2. It required that 'index' be initialised before use, and there's no
    realistic way to make GCC catch that.
    3. 'index' and 'entry' were the opposite way round from every other
    member of the XArray APIs.

    So split it into three different APIs:

    xa_for_each(xa, index, entry)
    xa_for_each_start(xa, index, entry, start)
    xa_for_each_marked(xa, index, entry, filter)

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • 0day picked up that I'd forgotten to add locking to this new test.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     

14 Dec, 2018

1 commit

  • Specifying a starting ID greater than the maximum ID isn't something
    attempted very often, but it should fail. It was succeeding due to
    xas_find_marked() returning the wrong error state, so add tests for
    both xa_alloc() and xas_find_marked().

    Fixes: b803b42823d0 ("xarray: Add XArray iterators")
    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     

06 Dec, 2018

2 commits


19 Nov, 2018

1 commit


17 Nov, 2018

1 commit


06 Nov, 2018

2 commits

  • The xa_reserve() function was a little unusual in that it attempted to
    be callable for all kinds of locking scenarios. Make it look like the
    other APIs with __xa_reserve, xa_reserve_bh and xa_reserve_irq variants.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     
  • The following sequence of calls would result in an infinite loop in
    xa_find_after():

    xa_store(xa, 0, x, GFP_KERNEL);
    index = 0;
    xa_for_each(xa, entry, index, ULONG_MAX, XA_PRESENT) { }

    xa_find_after() was confusing the situation where we found no entry in
    the tree with finding a multiorder entry, so it would look for the
    successor entry forever. Just check for this case explicitly. Includes
    a few new checks in the test suite to be sure this doesn't reappear.

    Signed-off-by: Matthew Wilcox

    Matthew Wilcox
     

21 Oct, 2018

11 commits