diff options
author | Matthew Wilcox <willy@infradead.org> | 2017-12-04 00:11:48 -0500 |
---|---|---|
committer | Matthew Wilcox <willy@infradead.org> | 2018-10-21 10:45:59 -0400 |
commit | 2264f5132fe45571139727ebdeb78696b35d1506 (patch) | |
tree | 6982c4c48af09fc39c1faf5da5b39c5d4fc41ad0 /lib/xarray.c | |
parent | 4e99d4e9579d3b950bf4b38d0d64eb1b9be78761 (diff) |
xarray: Add xas_create_range
This hopefully temporary function is useful for users who have not yet
been converted to multi-index entries.
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'lib/xarray.c')
-rw-r--r-- | lib/xarray.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/xarray.c b/lib/xarray.c index 41f8ebc651f5..ff37516fe832 100644 --- a/lib/xarray.c +++ b/lib/xarray.c | |||
@@ -637,6 +637,56 @@ static void *xas_create(struct xa_state *xas) | |||
637 | return entry; | 637 | return entry; |
638 | } | 638 | } |
639 | 639 | ||
640 | /** | ||
641 | * xas_create_range() - Ensure that stores to this range will succeed | ||
642 | * @xas: XArray operation state. | ||
643 | * | ||
644 | * Creates all of the slots in the range covered by @xas. Sets @xas to | ||
645 | * create single-index entries and positions it at the beginning of the | ||
646 | * range. This is for the benefit of users which have not yet been | ||
647 | * converted to use multi-index entries. | ||
648 | */ | ||
649 | void xas_create_range(struct xa_state *xas) | ||
650 | { | ||
651 | unsigned long index = xas->xa_index; | ||
652 | unsigned char shift = xas->xa_shift; | ||
653 | unsigned char sibs = xas->xa_sibs; | ||
654 | |||
655 | xas->xa_index |= ((sibs + 1) << shift) - 1; | ||
656 | if (xas_is_node(xas) && xas->xa_node->shift == xas->xa_shift) | ||
657 | xas->xa_offset |= sibs; | ||
658 | xas->xa_shift = 0; | ||
659 | xas->xa_sibs = 0; | ||
660 | |||
661 | for (;;) { | ||
662 | xas_create(xas); | ||
663 | if (xas_error(xas)) | ||
664 | goto restore; | ||
665 | if (xas->xa_index <= (index | XA_CHUNK_MASK)) | ||
666 | goto success; | ||
667 | xas->xa_index -= XA_CHUNK_SIZE; | ||
668 | |||
669 | for (;;) { | ||
670 | struct xa_node *node = xas->xa_node; | ||
671 | xas->xa_node = xa_parent_locked(xas->xa, node); | ||
672 | xas->xa_offset = node->offset - 1; | ||
673 | if (node->offset != 0) | ||
674 | break; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | restore: | ||
679 | xas->xa_shift = shift; | ||
680 | xas->xa_sibs = sibs; | ||
681 | xas->xa_index = index; | ||
682 | return; | ||
683 | success: | ||
684 | xas->xa_index = index; | ||
685 | if (xas->xa_node) | ||
686 | xas_set_offset(xas); | ||
687 | } | ||
688 | EXPORT_SYMBOL_GPL(xas_create_range); | ||
689 | |||
640 | static void update_node(struct xa_state *xas, struct xa_node *node, | 690 | static void update_node(struct xa_state *xas, struct xa_node *node, |
641 | int count, int values) | 691 | int count, int values) |
642 | { | 692 | { |