@@ -782,28 +782,37 @@ struct pid_namespace *ipc_seq_pid_ns(struct seq_file *s)
782
782
return iter -> pid_ns ;
783
783
}
784
784
785
- /*
786
- * This routine locks the ipc structure found at least at position pos.
785
+ /**
786
+ * sysvipc_find_ipc - Find and lock the ipc structure based on seq pos
787
+ * @ids: ipc identifier set
788
+ * @pos: expected position
789
+ *
790
+ * The function finds an ipc structure, based on the sequence file
791
+ * position @pos. If there is no ipc structure at position @pos, then
792
+ * the successor is selected.
793
+ * If a structure is found, then it is locked (both rcu_read_lock() and
794
+ * ipc_lock_object()) and @pos is set to the position needed to locate
795
+ * the found ipc structure.
796
+ * If nothing is found (i.e. EOF), @pos is not modified.
797
+ *
798
+ * The function returns the found ipc structure, or NULL at EOF.
787
799
*/
788
- static struct kern_ipc_perm * sysvipc_find_ipc (struct ipc_ids * ids , loff_t pos ,
789
- loff_t * new_pos )
800
+ static struct kern_ipc_perm * sysvipc_find_ipc (struct ipc_ids * ids , loff_t * pos )
790
801
{
791
- struct kern_ipc_perm * ipc = NULL ;
792
- int max_idx = ipc_get_maxidx ( ids ) ;
802
+ int tmpidx ;
803
+ struct kern_ipc_perm * ipc ;
793
804
794
- if ( max_idx == -1 || pos > max_idx )
795
- goto out ;
805
+ /* convert from position to idr index -> "-1" */
806
+ tmpidx = * pos - 1 ;
796
807
797
- for (; pos <= max_idx ; pos ++ ) {
798
- ipc = idr_find ( & ids -> ipcs_idr , pos );
799
- if ( ipc != NULL ) {
800
- rcu_read_lock ( );
801
- ipc_lock_object ( ipc );
802
- break ;
803
- }
808
+ ipc = idr_get_next ( & ids -> ipcs_idr , & tmpidx );
809
+ if ( ipc != NULL ) {
810
+ rcu_read_lock ();
811
+ ipc_lock_object ( ipc );
812
+
813
+ /* convert from idr index to position -> "+1" */
814
+ * pos = tmpidx + 1 ;
804
815
}
805
- out :
806
- * new_pos = pos + 1 ;
807
816
return ipc ;
808
817
}
809
818
@@ -817,11 +826,13 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
817
826
if (ipc && ipc != SEQ_START_TOKEN )
818
827
ipc_unlock (ipc );
819
828
820
- return sysvipc_find_ipc (& iter -> ns -> ids [iface -> ids ], * pos , pos );
829
+ /* Next -> search for *pos+1 */
830
+ (* pos )++ ;
831
+ return sysvipc_find_ipc (& iter -> ns -> ids [iface -> ids ], pos );
821
832
}
822
833
823
834
/*
824
- * File positions: pos 0 -> header, pos n -> ipc id = n - 1.
835
+ * File positions: pos 0 -> header, pos n -> ipc idx = n - 1.
825
836
* SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START.
826
837
*/
827
838
static void * sysvipc_proc_start (struct seq_file * s , loff_t * pos )
@@ -846,8 +857,8 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
846
857
if (* pos == 0 )
847
858
return SEQ_START_TOKEN ;
848
859
849
- /* Find the (pos-1)th ipc */
850
- return sysvipc_find_ipc (ids , * pos - 1 , pos );
860
+ /* Otherwise return the correct ipc structure */
861
+ return sysvipc_find_ipc (ids , pos );
851
862
}
852
863
853
864
static void sysvipc_proc_stop (struct seq_file * s , void * it )
0 commit comments