diff options
Diffstat (limited to 'fs/seq_file.c')
| -rw-r--r-- | fs/seq_file.c | 130 |
1 files changed, 127 insertions, 3 deletions
diff --git a/fs/seq_file.c b/fs/seq_file.c index eae7d9dbf3ff..e1f437be6c3c 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -674,7 +674,6 @@ struct list_head *seq_list_start(struct list_head *head, loff_t pos) | |||
| 674 | 674 | ||
| 675 | return NULL; | 675 | return NULL; |
| 676 | } | 676 | } |
| 677 | |||
| 678 | EXPORT_SYMBOL(seq_list_start); | 677 | EXPORT_SYMBOL(seq_list_start); |
| 679 | 678 | ||
| 680 | struct list_head *seq_list_start_head(struct list_head *head, loff_t pos) | 679 | struct list_head *seq_list_start_head(struct list_head *head, loff_t pos) |
| @@ -684,7 +683,6 @@ struct list_head *seq_list_start_head(struct list_head *head, loff_t pos) | |||
| 684 | 683 | ||
| 685 | return seq_list_start(head, pos - 1); | 684 | return seq_list_start(head, pos - 1); |
| 686 | } | 685 | } |
| 687 | |||
| 688 | EXPORT_SYMBOL(seq_list_start_head); | 686 | EXPORT_SYMBOL(seq_list_start_head); |
| 689 | 687 | ||
| 690 | struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos) | 688 | struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos) |
| @@ -695,5 +693,131 @@ struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos) | |||
| 695 | ++*ppos; | 693 | ++*ppos; |
| 696 | return lh == head ? NULL : lh; | 694 | return lh == head ? NULL : lh; |
| 697 | } | 695 | } |
| 698 | |||
| 699 | EXPORT_SYMBOL(seq_list_next); | 696 | EXPORT_SYMBOL(seq_list_next); |
| 697 | |||
| 698 | /** | ||
| 699 | * seq_hlist_start - start an iteration of a hlist | ||
| 700 | * @head: the head of the hlist | ||
| 701 | * @pos: the start position of the sequence | ||
| 702 | * | ||
| 703 | * Called at seq_file->op->start(). | ||
| 704 | */ | ||
| 705 | struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos) | ||
| 706 | { | ||
| 707 | struct hlist_node *node; | ||
| 708 | |||
| 709 | hlist_for_each(node, head) | ||
| 710 | if (pos-- == 0) | ||
| 711 | return node; | ||
| 712 | return NULL; | ||
| 713 | } | ||
| 714 | EXPORT_SYMBOL(seq_hlist_start); | ||
| 715 | |||
| 716 | /** | ||
| 717 | * seq_hlist_start_head - start an iteration of a hlist | ||
| 718 | * @head: the head of the hlist | ||
| 719 | * @pos: the start position of the sequence | ||
| 720 | * | ||
| 721 | * Called at seq_file->op->start(). Call this function if you want to | ||
| 722 | * print a header at the top of the output. | ||
| 723 | */ | ||
| 724 | struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos) | ||
| 725 | { | ||
| 726 | if (!pos) | ||
| 727 | return SEQ_START_TOKEN; | ||
| 728 | |||
| 729 | return seq_hlist_start(head, pos - 1); | ||
| 730 | } | ||
| 731 | EXPORT_SYMBOL(seq_hlist_start_head); | ||
| 732 | |||
| 733 | /** | ||
| 734 | * seq_hlist_next - move to the next position of the hlist | ||
| 735 | * @v: the current iterator | ||
| 736 | * @head: the head of the hlist | ||
| 737 | * @ppos: the current position | ||
| 738 | * | ||
| 739 | * Called at seq_file->op->next(). | ||
| 740 | */ | ||
| 741 | struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head, | ||
| 742 | loff_t *ppos) | ||
| 743 | { | ||
| 744 | struct hlist_node *node = v; | ||
| 745 | |||
| 746 | ++*ppos; | ||
| 747 | if (v == SEQ_START_TOKEN) | ||
| 748 | return head->first; | ||
| 749 | else | ||
| 750 | return node->next; | ||
| 751 | } | ||
| 752 | EXPORT_SYMBOL(seq_hlist_next); | ||
| 753 | |||
| 754 | /** | ||
| 755 | * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU | ||
| 756 | * @head: the head of the hlist | ||
| 757 | * @pos: the start position of the sequence | ||
| 758 | * | ||
| 759 | * Called at seq_file->op->start(). | ||
| 760 | * | ||
| 761 | * This list-traversal primitive may safely run concurrently with | ||
| 762 | * the _rcu list-mutation primitives such as hlist_add_head_rcu() | ||
| 763 | * as long as the traversal is guarded by rcu_read_lock(). | ||
| 764 | */ | ||
| 765 | struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head, | ||
| 766 | loff_t pos) | ||
| 767 | { | ||
| 768 | struct hlist_node *node; | ||
| 769 | |||
| 770 | __hlist_for_each_rcu(node, head) | ||
| 771 | if (pos-- == 0) | ||
| 772 | return node; | ||
| 773 | return NULL; | ||
| 774 | } | ||
| 775 | EXPORT_SYMBOL(seq_hlist_start_rcu); | ||
| 776 | |||
| 777 | /** | ||
| 778 | * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU | ||
| 779 | * @head: the head of the hlist | ||
| 780 | * @pos: the start position of the sequence | ||
| 781 | * | ||
| 782 | * Called at seq_file->op->start(). Call this function if you want to | ||
| 783 | * print a header at the top of the output. | ||
| 784 | * | ||
| 785 | * This list-traversal primitive may safely run concurrently with | ||
| 786 | * the _rcu list-mutation primitives such as hlist_add_head_rcu() | ||
| 787 | * as long as the traversal is guarded by rcu_read_lock(). | ||
| 788 | */ | ||
| 789 | struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, | ||
| 790 | loff_t pos) | ||
| 791 | { | ||
| 792 | if (!pos) | ||
| 793 | return SEQ_START_TOKEN; | ||
| 794 | |||
| 795 | return seq_hlist_start_rcu(head, pos - 1); | ||
| 796 | } | ||
| 797 | EXPORT_SYMBOL(seq_hlist_start_head_rcu); | ||
| 798 | |||
| 799 | /** | ||
| 800 | * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU | ||
| 801 | * @v: the current iterator | ||
| 802 | * @head: the head of the hlist | ||
| 803 | * @ppos: the current position | ||
| 804 | * | ||
| 805 | * Called at seq_file->op->next(). | ||
| 806 | * | ||
| 807 | * This list-traversal primitive may safely run concurrently with | ||
| 808 | * the _rcu list-mutation primitives such as hlist_add_head_rcu() | ||
| 809 | * as long as the traversal is guarded by rcu_read_lock(). | ||
| 810 | */ | ||
| 811 | struct hlist_node *seq_hlist_next_rcu(void *v, | ||
| 812 | struct hlist_head *head, | ||
| 813 | loff_t *ppos) | ||
| 814 | { | ||
| 815 | struct hlist_node *node = v; | ||
| 816 | |||
| 817 | ++*ppos; | ||
| 818 | if (v == SEQ_START_TOKEN) | ||
| 819 | return rcu_dereference(head->first); | ||
| 820 | else | ||
| 821 | return rcu_dereference(node->next); | ||
| 822 | } | ||
| 823 | EXPORT_SYMBOL(seq_hlist_next_rcu); | ||
