Commit 671f7335 authored by Fox Chen's avatar Fox Chen Committed by Jonathan Corbet
Browse files

docs: path-lookup: update i_op->put_link and cookie description



No inode->put_link operation anymore. We use delayed_call to
deal with link destruction. Cookie has been replaced with
struct delayed_call.

Related commit: commit fceef393 ("switch ->get_link() to
delayed_call, kill ->put_link()")

Signed-off-by: default avatarFox Chen <foxhlchen@gmail.com>
Reviewed-by: default avatarNeilBrown <neilb@suse.de>
Link: https://lore.kernel.org/r/20210527091618.287093-9-foxhlchen@gmail.com


Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
parent 4a00e4bd
Loading
Loading
Loading
Loading
+8 −22
Original line number Original line Diff line number Diff line
@@ -1066,34 +1066,20 @@ method. This is called both in RCU-walk and REF-walk. In RCU-walk the
RCU-walk.  Much like the ``i_op->permission()`` method we
RCU-walk.  Much like the ``i_op->permission()`` method we
looked at previously, ``->get_link()`` would need to be careful that
looked at previously, ``->get_link()`` would need to be careful that
all the data structures it references are safe to be accessed while
all the data structures it references are safe to be accessed while
holding no counted reference, only the RCU lock.  Though getting a
holding no counted reference, only the RCU lock. A callback
reference with ``->follow_link()`` is not yet done in RCU-walk mode, the
``struct delayed_called`` will be passed to ``->get_link()``:
code is ready to release the reference when that does happen.
file systems can set their own put_link function and argument through

``set_delayed_call()``. Later on, when VFS wants to put link, it will call
This need to drop the reference to a symlink adds significant
``do_delayed_call()`` to invoke that callback function with the argument.
complexity.  It requires a reference to the inode so that the
``i_op->put_link()`` inode operation can be called.  In REF-walk, that
reference is kept implicitly through a reference to the dentry, so
keeping the ``struct path`` of the symlink is easiest.  For RCU-walk,
the pointer to the inode is kept separately.  To allow switching from
RCU-walk back to REF-walk in the middle of processing nested symlinks
we also need the seq number for the dentry so we can confirm that
switching back was safe.

Finally, when providing a reference to a symlink, the filesystem also
provides an opaque "cookie" that must be passed to ``->put_link()`` so that it
knows what to free.  This might be the allocated memory area, or a
pointer to the ``struct page`` in the page cache, or something else
completely.  Only the filesystem knows what it is.


In order for the reference to each symlink to be dropped when the walk completes,
In order for the reference to each symlink to be dropped when the walk completes,
whether in RCU-walk or REF-walk, the symlink stack needs to contain,
whether in RCU-walk or REF-walk, the symlink stack needs to contain,
along with the path remnants:
along with the path remnants:


- the ``struct path`` to provide a reference to the inode in REF-walk
- the ``struct path`` to provide a reference to the previous path
- the ``struct inode *`` to provide a reference to the inode in RCU-walk
- the ``const char *`` to provide a reference to the to previous name
- the ``seq`` to allow the path to be safely switched from RCU-walk to REF-walk
- the ``seq`` to allow the path to be safely switched from RCU-walk to REF-walk
- the ``cookie`` that tells ``->put_path()`` what to put.
- the ``struct delayed_call`` for later invocation.


This means that each entry in the symlink stack needs to hold five
This means that each entry in the symlink stack needs to hold five
pointers and an integer instead of just one pointer (the path
pointers and an integer instead of just one pointer (the path