From ce7a7eed776f994d5672ad76adb671580bd083ac Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 25 Sep 2020 17:14:42 +1000 Subject: doc: seq_file: clarify role of *pos in ->next() There are behavioural requirements on the seq_file next() function in terms of how it updates *pos at end-of-file, and these are now enforced by a warning. I was recently attempting to justify the reason this was needed, and couldn't remember the details, and didn't find them in the documentation. So I re-read the code until I understood it again, and updated the documentation to match. I also enhanced the text about SEQ_START_TOKEN as it seemed potentially misleading. Cc: Vasily Averin Signed-off-by: NeilBrown Link: https://lore.kernel.org/r/87eemqiazh.fsf@notabene.neil.brown.name Signed-off-by: Jonathan Corbet --- Documentation/filesystems/seq_file.rst | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'Documentation/filesystems') diff --git a/Documentation/filesystems/seq_file.rst b/Documentation/filesystems/seq_file.rst index 7f7ee06b2693..56856481dc8d 100644 --- a/Documentation/filesystems/seq_file.rst +++ b/Documentation/filesystems/seq_file.rst @@ -129,7 +129,9 @@ also a special value which can be returned by the start() function called SEQ_START_TOKEN; it can be used if you wish to instruct your show() function (described below) to print a header at the top of the output. SEQ_START_TOKEN should only be used if the offset is zero, -however. +however. SEQ_START_TOKEN has no special meaning to the core seq_file +code. It is provided as a convenience for a start() funciton to +communicate with the next() and show() functions. The next function to implement is called, amazingly, next(); its job is to move the iterator forward to the next position in the sequence. The @@ -145,6 +147,22 @@ complete. Here's the example version:: return spos; } +The next() function should set ``*pos`` to a value that start() can use +to find the new location in the sequence. When the iterator is being +stored in the private data area, rather than being reinitialized on each +start(), it might seem sufficient to simply set ``*pos`` to any non-zero +value (zero always tells start() to restart the sequence). This is not +sufficient due to historical problems. + +Historically, many next() functions have *not* updated ``*pos`` at +end-of-file. If the value is then used by start() to initialise the +iterator, this can result in corner cases where the last entry in the +sequence is reported twice in the file. In order to discourage this bug +from being resurrected, the core seq_file code now produces a warning if +a next() function does not change the value of ``*pos``. Consequently a +next() function *must* change the value of ``*pos``, and of course must +set it to a non-zero value. + The stop() function closes a session; its job, of course, is to clean up. If dynamic memory is allocated for the iterator, stop() is the place to free it; if a lock was taken by start(), stop() must release -- cgit v1.2.3