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..5afd554efad3 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 | * @pos: the current posision | ||
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 | * @pos: the current posision | ||
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); | ||