diff options
Diffstat (limited to 'lib/xarray.c')
-rw-r--r-- | lib/xarray.c | 58 |
1 files changed, 25 insertions, 33 deletions
diff --git a/lib/xarray.c b/lib/xarray.c index b55aa8c1c20f..a9d28013f9dc 100644 --- a/lib/xarray.c +++ b/lib/xarray.c | |||
@@ -1361,23 +1361,21 @@ void *xa_erase(struct xarray *xa, unsigned long index) | |||
1361 | EXPORT_SYMBOL(xa_erase); | 1361 | EXPORT_SYMBOL(xa_erase); |
1362 | 1362 | ||
1363 | /** | 1363 | /** |
1364 | * xa_store() - Store this entry in the XArray. | 1364 | * __xa_store() - Store this entry in the XArray. |
1365 | * @xa: XArray. | 1365 | * @xa: XArray. |
1366 | * @index: Index into array. | 1366 | * @index: Index into array. |
1367 | * @entry: New entry. | 1367 | * @entry: New entry. |
1368 | * @gfp: Memory allocation flags. | 1368 | * @gfp: Memory allocation flags. |
1369 | * | 1369 | * |
1370 | * After this function returns, loads from this index will return @entry. | 1370 | * You must already be holding the xa_lock when calling this function. |
1371 | * Storing into an existing multislot entry updates the entry of every index. | 1371 | * It will drop the lock if needed to allocate memory, and then reacquire |
1372 | * The marks associated with @index are unaffected unless @entry is %NULL. | 1372 | * it afterwards. |
1373 | * | 1373 | * |
1374 | * Context: Process context. Takes and releases the xa_lock. May sleep | 1374 | * Context: Any context. Expects xa_lock to be held on entry. May |
1375 | * if the @gfp flags permit. | 1375 | * release and reacquire xa_lock if @gfp flags permit. |
1376 | * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry | 1376 | * Return: The old entry at this index or xa_err() if an error happened. |
1377 | * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation | ||
1378 | * failed. | ||
1379 | */ | 1377 | */ |
1380 | void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) | 1378 | void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) |
1381 | { | 1379 | { |
1382 | XA_STATE(xas, xa, index); | 1380 | XA_STATE(xas, xa, index); |
1383 | void *curr; | 1381 | void *curr; |
@@ -1386,49 +1384,43 @@ void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) | |||
1386 | return XA_ERROR(-EINVAL); | 1384 | return XA_ERROR(-EINVAL); |
1387 | 1385 | ||
1388 | do { | 1386 | do { |
1389 | xas_lock(&xas); | ||
1390 | curr = xas_store(&xas, entry); | 1387 | curr = xas_store(&xas, entry); |
1391 | if (xa_track_free(xa) && entry) | 1388 | if (xa_track_free(xa) && entry) |
1392 | xas_clear_mark(&xas, XA_FREE_MARK); | 1389 | xas_clear_mark(&xas, XA_FREE_MARK); |
1393 | xas_unlock(&xas); | 1390 | } while (__xas_nomem(&xas, gfp)); |
1394 | } while (xas_nomem(&xas, gfp)); | ||
1395 | 1391 | ||
1396 | return xas_result(&xas, curr); | 1392 | return xas_result(&xas, curr); |
1397 | } | 1393 | } |
1398 | EXPORT_SYMBOL(xa_store); | 1394 | EXPORT_SYMBOL(__xa_store); |
1399 | 1395 | ||
1400 | /** | 1396 | /** |
1401 | * __xa_store() - Store this entry in the XArray. | 1397 | * xa_store() - Store this entry in the XArray. |
1402 | * @xa: XArray. | 1398 | * @xa: XArray. |
1403 | * @index: Index into array. | 1399 | * @index: Index into array. |
1404 | * @entry: New entry. | 1400 | * @entry: New entry. |
1405 | * @gfp: Memory allocation flags. | 1401 | * @gfp: Memory allocation flags. |
1406 | * | 1402 | * |
1407 | * You must already be holding the xa_lock when calling this function. | 1403 | * After this function returns, loads from this index will return @entry. |
1408 | * It will drop the lock if needed to allocate memory, and then reacquire | 1404 | * Storing into an existing multislot entry updates the entry of every index. |
1409 | * it afterwards. | 1405 | * The marks associated with @index are unaffected unless @entry is %NULL. |
1410 | * | 1406 | * |
1411 | * Context: Any context. Expects xa_lock to be held on entry. May | 1407 | * Context: Any context. Takes and releases the xa_lock. |
1412 | * release and reacquire xa_lock if @gfp flags permit. | 1408 | * May sleep if the @gfp flags permit. |
1413 | * Return: The old entry at this index or xa_err() if an error happened. | 1409 | * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry |
1410 | * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation | ||
1411 | * failed. | ||
1414 | */ | 1412 | */ |
1415 | void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) | 1413 | void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) |
1416 | { | 1414 | { |
1417 | XA_STATE(xas, xa, index); | ||
1418 | void *curr; | 1415 | void *curr; |
1419 | 1416 | ||
1420 | if (WARN_ON_ONCE(xa_is_internal(entry))) | 1417 | xa_lock(xa); |
1421 | return XA_ERROR(-EINVAL); | 1418 | curr = __xa_store(xa, index, entry, gfp); |
1422 | 1419 | xa_unlock(xa); | |
1423 | do { | ||
1424 | curr = xas_store(&xas, entry); | ||
1425 | if (xa_track_free(xa) && entry) | ||
1426 | xas_clear_mark(&xas, XA_FREE_MARK); | ||
1427 | } while (__xas_nomem(&xas, gfp)); | ||
1428 | 1420 | ||
1429 | return xas_result(&xas, curr); | 1421 | return curr; |
1430 | } | 1422 | } |
1431 | EXPORT_SYMBOL(__xa_store); | 1423 | EXPORT_SYMBOL(xa_store); |
1432 | 1424 | ||
1433 | /** | 1425 | /** |
1434 | * __xa_cmpxchg() - Store this entry in the XArray. | 1426 | * __xa_cmpxchg() - Store this entry in the XArray. |