mirror of https://gitee.com/openkylin/linux.git
Filesystems: Documentation: Replace deprecated :c:func: Usage
Replace :c:func: with func() as the previous usage is deprecated. Signed-off-by: Puranjay Mohan <puranjay12@gmail.com> Link: https://lore.kernel.org/r/20200810184828.29297-1-puranjay12@gmail.com Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
1fc0fd6739
commit
7caf3e3f17
|
@ -10,27 +10,27 @@ Details
|
||||||
The journalling layer is easy to use. You need to first of all create a
|
The journalling layer is easy to use. You need to first of all create a
|
||||||
journal_t data structure. There are two calls to do this dependent on
|
journal_t data structure. There are two calls to do this dependent on
|
||||||
how you decide to allocate the physical media on which the journal
|
how you decide to allocate the physical media on which the journal
|
||||||
resides. The :c:func:`jbd2_journal_init_inode` call is for journals stored in
|
resides. The jbd2_journal_init_inode() call is for journals stored in
|
||||||
filesystem inodes, or the :c:func:`jbd2_journal_init_dev` call can be used
|
filesystem inodes, or the jbd2_journal_init_dev() call can be used
|
||||||
for journal stored on a raw device (in a continuous range of blocks). A
|
for journal stored on a raw device (in a continuous range of blocks). A
|
||||||
journal_t is a typedef for a struct pointer, so when you are finally
|
journal_t is a typedef for a struct pointer, so when you are finally
|
||||||
finished make sure you call :c:func:`jbd2_journal_destroy` on it to free up
|
finished make sure you call jbd2_journal_destroy() on it to free up
|
||||||
any used kernel memory.
|
any used kernel memory.
|
||||||
|
|
||||||
Once you have got your journal_t object you need to 'mount' or load the
|
Once you have got your journal_t object you need to 'mount' or load the
|
||||||
journal file. The journalling layer expects the space for the journal
|
journal file. The journalling layer expects the space for the journal
|
||||||
was already allocated and initialized properly by the userspace tools.
|
was already allocated and initialized properly by the userspace tools.
|
||||||
When loading the journal you must call :c:func:`jbd2_journal_load` to process
|
When loading the journal you must call jbd2_journal_load() to process
|
||||||
journal contents. If the client file system detects the journal contents
|
journal contents. If the client file system detects the journal contents
|
||||||
does not need to be processed (or even need not have valid contents), it
|
does not need to be processed (or even need not have valid contents), it
|
||||||
may call :c:func:`jbd2_journal_wipe` to clear the journal contents before
|
may call jbd2_journal_wipe() to clear the journal contents before
|
||||||
calling :c:func:`jbd2_journal_load`.
|
calling jbd2_journal_load().
|
||||||
|
|
||||||
Note that jbd2_journal_wipe(..,0) calls
|
Note that jbd2_journal_wipe(..,0) calls
|
||||||
:c:func:`jbd2_journal_skip_recovery` for you if it detects any outstanding
|
jbd2_journal_skip_recovery() for you if it detects any outstanding
|
||||||
transactions in the journal and similarly :c:func:`jbd2_journal_load` will
|
transactions in the journal and similarly jbd2_journal_load() will
|
||||||
call :c:func:`jbd2_journal_recover` if necessary. I would advise reading
|
call jbd2_journal_recover() if necessary. I would advise reading
|
||||||
:c:func:`ext4_load_journal` in fs/ext4/super.c for examples on this stage.
|
ext4_load_journal() in fs/ext4/super.c for examples on this stage.
|
||||||
|
|
||||||
Now you can go ahead and start modifying the underlying filesystem.
|
Now you can go ahead and start modifying the underlying filesystem.
|
||||||
Almost.
|
Almost.
|
||||||
|
@ -39,57 +39,57 @@ You still need to actually journal your filesystem changes, this is done
|
||||||
by wrapping them into transactions. Additionally you also need to wrap
|
by wrapping them into transactions. Additionally you also need to wrap
|
||||||
the modification of each of the buffers with calls to the journal layer,
|
the modification of each of the buffers with calls to the journal layer,
|
||||||
so it knows what the modifications you are actually making are. To do
|
so it knows what the modifications you are actually making are. To do
|
||||||
this use :c:func:`jbd2_journal_start` which returns a transaction handle.
|
this use jbd2_journal_start() which returns a transaction handle.
|
||||||
|
|
||||||
:c:func:`jbd2_journal_start` and its counterpart :c:func:`jbd2_journal_stop`,
|
jbd2_journal_start() and its counterpart jbd2_journal_stop(),
|
||||||
which indicates the end of a transaction are nestable calls, so you can
|
which indicates the end of a transaction are nestable calls, so you can
|
||||||
reenter a transaction if necessary, but remember you must call
|
reenter a transaction if necessary, but remember you must call
|
||||||
:c:func:`jbd2_journal_stop` the same number of times as
|
jbd2_journal_stop() the same number of times as
|
||||||
:c:func:`jbd2_journal_start` before the transaction is completed (or more
|
jbd2_journal_start() before the transaction is completed (or more
|
||||||
accurately leaves the update phase). Ext4/VFS makes use of this feature to
|
accurately leaves the update phase). Ext4/VFS makes use of this feature to
|
||||||
simplify handling of inode dirtying, quota support, etc.
|
simplify handling of inode dirtying, quota support, etc.
|
||||||
|
|
||||||
Inside each transaction you need to wrap the modifications to the
|
Inside each transaction you need to wrap the modifications to the
|
||||||
individual buffers (blocks). Before you start to modify a buffer you
|
individual buffers (blocks). Before you start to modify a buffer you
|
||||||
need to call :c:func:`jbd2_journal_get_create_access()` /
|
need to call jbd2_journal_get_create_access() /
|
||||||
:c:func:`jbd2_journal_get_write_access()` /
|
jbd2_journal_get_write_access() /
|
||||||
:c:func:`jbd2_journal_get_undo_access()` as appropriate, this allows the
|
jbd2_journal_get_undo_access() as appropriate, this allows the
|
||||||
journalling layer to copy the unmodified
|
journalling layer to copy the unmodified
|
||||||
data if it needs to. After all the buffer may be part of a previously
|
data if it needs to. After all the buffer may be part of a previously
|
||||||
uncommitted transaction. At this point you are at last ready to modify a
|
uncommitted transaction. At this point you are at last ready to modify a
|
||||||
buffer, and once you are have done so you need to call
|
buffer, and once you are have done so you need to call
|
||||||
:c:func:`jbd2_journal_dirty_metadata`. Or if you've asked for access to a
|
jbd2_journal_dirty_metadata(). Or if you've asked for access to a
|
||||||
buffer you now know is now longer required to be pushed back on the
|
buffer you now know is now longer required to be pushed back on the
|
||||||
device you can call :c:func:`jbd2_journal_forget` in much the same way as you
|
device you can call jbd2_journal_forget() in much the same way as you
|
||||||
might have used :c:func:`bforget` in the past.
|
might have used bforget() in the past.
|
||||||
|
|
||||||
A :c:func:`jbd2_journal_flush` may be called at any time to commit and
|
A jbd2_journal_flush() may be called at any time to commit and
|
||||||
checkpoint all your transactions.
|
checkpoint all your transactions.
|
||||||
|
|
||||||
Then at umount time , in your :c:func:`put_super` you can then call
|
Then at umount time , in your put_super() you can then call
|
||||||
:c:func:`jbd2_journal_destroy` to clean up your in-core journal object.
|
jbd2_journal_destroy() to clean up your in-core journal object.
|
||||||
|
|
||||||
Unfortunately there a couple of ways the journal layer can cause a
|
Unfortunately there a couple of ways the journal layer can cause a
|
||||||
deadlock. The first thing to note is that each task can only have a
|
deadlock. The first thing to note is that each task can only have a
|
||||||
single outstanding transaction at any one time, remember nothing commits
|
single outstanding transaction at any one time, remember nothing commits
|
||||||
until the outermost :c:func:`jbd2_journal_stop`. This means you must complete
|
until the outermost jbd2_journal_stop(). This means you must complete
|
||||||
the transaction at the end of each file/inode/address etc. operation you
|
the transaction at the end of each file/inode/address etc. operation you
|
||||||
perform, so that the journalling system isn't re-entered on another
|
perform, so that the journalling system isn't re-entered on another
|
||||||
journal. Since transactions can't be nested/batched across differing
|
journal. Since transactions can't be nested/batched across differing
|
||||||
journals, and another filesystem other than yours (say ext4) may be
|
journals, and another filesystem other than yours (say ext4) may be
|
||||||
modified in a later syscall.
|
modified in a later syscall.
|
||||||
|
|
||||||
The second case to bear in mind is that :c:func:`jbd2_journal_start` can block
|
The second case to bear in mind is that jbd2_journal_start() can block
|
||||||
if there isn't enough space in the journal for your transaction (based
|
if there isn't enough space in the journal for your transaction (based
|
||||||
on the passed nblocks param) - when it blocks it merely(!) needs to wait
|
on the passed nblocks param) - when it blocks it merely(!) needs to wait
|
||||||
for transactions to complete and be committed from other tasks, so
|
for transactions to complete and be committed from other tasks, so
|
||||||
essentially we are waiting for :c:func:`jbd2_journal_stop`. So to avoid
|
essentially we are waiting for jbd2_journal_stop(). So to avoid
|
||||||
deadlocks you must treat :c:func:`jbd2_journal_start` /
|
deadlocks you must treat jbd2_journal_start() /
|
||||||
:c:func:`jbd2_journal_stop` as if they were semaphores and include them in
|
jbd2_journal_stop() as if they were semaphores and include them in
|
||||||
your semaphore ordering rules to prevent
|
your semaphore ordering rules to prevent
|
||||||
deadlocks. Note that :c:func:`jbd2_journal_extend` has similar blocking
|
deadlocks. Note that jbd2_journal_extend() has similar blocking
|
||||||
behaviour to :c:func:`jbd2_journal_start` so you can deadlock here just as
|
behaviour to jbd2_journal_start() so you can deadlock here just as
|
||||||
easily as on :c:func:`jbd2_journal_start`.
|
easily as on jbd2_journal_start().
|
||||||
|
|
||||||
Try to reserve the right number of blocks the first time. ;-). This will
|
Try to reserve the right number of blocks the first time. ;-). This will
|
||||||
be the maximum number of blocks you are going to touch in this
|
be the maximum number of blocks you are going to touch in this
|
||||||
|
@ -116,8 +116,8 @@ called after each transaction commit. You can also use
|
||||||
that need processing when the transaction commits.
|
that need processing when the transaction commits.
|
||||||
|
|
||||||
JBD2 also provides a way to block all transaction updates via
|
JBD2 also provides a way to block all transaction updates via
|
||||||
:c:func:`jbd2_journal_lock_updates()` /
|
jbd2_journal_lock_updates() /
|
||||||
:c:func:`jbd2_journal_unlock_updates()`. Ext4 uses this when it wants a
|
jbd2_journal_unlock_updates(). Ext4 uses this when it wants a
|
||||||
window with a clean and stable fs for a moment. E.g.
|
window with a clean and stable fs for a moment. E.g.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
Loading…
Reference in New Issue