The example in seq_file.rst hands proc_create() file operations built
from an open method that calls seq_open() and from seq_read(),
seq_lseek() and seq_release(). procfs doesn't work that way anymore. It
opens and releases the seq_file itself when the entry declares its
seq_operations or its show function in struct proc_ops. Say so, and
point the extra-simple version at ->proc_show() for /proc files.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 Documentation/filesystems/seq_file.rst | 42 ++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/Documentation/filesystems/seq_file.rst 
b/Documentation/filesystems/seq_file.rst
index d753d8177bcb..8cfb5fdabe99 100644
--- a/Documentation/filesystems/seq_file.rst
+++ b/Documentation/filesystems/seq_file.rst
@@ -68,7 +68,7 @@ kernel 3.10. Current versions require the following update::
     -  entry = create_proc_entry("sequence", 0, NULL);
     -  if (entry)
     -          entry->proc_fops = &ct_file_ops;
-    +  entry = proc_create("sequence", 0, NULL, &ct_file_ops);
+    +  entry = proc_create("sequence", 0, NULL, &ct_proc_ops);
 
 The iterator interface
 ======================
@@ -277,9 +277,10 @@ seq_file system, but we have not yet turned them into a 
file that a user
 can see. Creating a file within the kernel requires, of course, the
 creation of a set of file_operations which implement the operations on that
 file. The seq_file interface provides a set of canned operations which do
-most of the work. The virtual file author still must implement the open()
-method, however, to hook everything up. The open function is often a single
-line, as in the example module::
+most of the work. A file in /proc is special, procfs hooks the seq_file up
+itself, see below. Everywhere else the virtual file author still must
+implement the open() method to do that. The open function is often a
+single line::
 
        static int ct_open(struct inode *inode, struct file *file)
        {
@@ -343,19 +344,38 @@ file_operations structure will look like::
 There is also a seq_release_private() which passes the contents of the
 seq_file private field to kfree() before releasing the structure.
 
-The final step is the creation of the /proc file itself. In the example
-code, that is done in the initialization code in the usual way::
+The final step is the creation of the file itself. A file in /proc is
+special here: procfs opens and releases the seq_file itself, so there is
+no open method and no file_operations for it. The entry declares its
+seq_operations in struct proc_ops instead, and the size of a private
+block in proc_state_size if it wants procfs to allocate one like
+seq_open_private() would::
+
+       static const struct proc_ops ct_proc_ops = {
+               .proc_seq_ops = &ct_seq_ops,
+       };
 
        static int ct_init(void)
        {
-               struct proc_dir_entry *entry;
-
-               proc_create("sequence", 0, NULL, &ct_file_ops);
+               proc_create("sequence", 0, NULL, &ct_proc_ops);
                return 0;
        }
 
        module_init(ct_init);
 
+A ->proc_open() method of such an entry finds the seq_file in
+file->private_data and may set up more state; ->proc_release() releases
+only that. It runs when the entry is removed, which can be while a reader
+is still copying out of the seq_file, so it must leave the seq_file
+alone. procfs only calls into the entry between start() and stop() with
+the entry pinned, so nothing that runs there may wait for something a
+reader can hold while it copies to userspace, like the seq_file's lock.
+start() and next() may return ERR_PTR(-EIO) to say that the entry is
+gone; procfs unpins it right away then. An entry that wants to start out
+with a larger buffer, like single_open_size() gives, calls
+seq_preallocate() from ->proc_open(). The file_operations above are what
+a file elsewhere, in debugfs for example, uses.
+
 And that is pretty much it.
 
 
@@ -394,3 +414,7 @@ value given to single_open() can be found in the private 
field of the
 seq_file structure. When using single_open(), the programmer should use
 single_release() instead of seq_release() in the file_operations structure
 to avoid a memory leak.
+
+A file in /proc puts the show() function into the proc_show field of its
+struct proc_ops instead and procfs does the rest, with the entry's data in
+the private field of the seq_file structure.

-- 
2.53.0


Reply via email to