lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 6 Jun 2011 22:01:13 +0300
From:	"Amir G." <amir73il@...rs.sourceforge.net>
To:	Lukas Czerner <lczerner@...hat.com>
Cc:	linux-ext4@...r.kernel.org, tytso@....edu,
	Amir Goldstein <amir73il@...rs.sf.net>,
	Yongqiang Yang <xiaoqiangnk@...il.com>
Subject: Re: [PATCH RFC 03/30] ext4: snapshot hooks - inside JBD hooks

On Mon, Jun 6, 2011 at 6:53 PM, Lukas Czerner <lczerner@...hat.com> wrote:
> On Mon, 9 May 2011, amir73il@...rs.sourceforge.net wrote:
>
>> From: Amir Goldstein <amir73il@...rs.sf.net>
>>
>> Before every metadata buffer write, the journal API is called,
>> namely, one of the ext4_journal_get_XXX_access() functions.
>> We use these journal hooks to call the snapshot API, namely
>> ext4_snapshot_get_XXX_access(), to COW the metadata buffer before
>> it is modified for the first time.
>>
>> Signed-off-by: Amir Goldstein <amir73il@...rs.sf.net>
>> Signed-off-by: Yongqiang Yang <xiaoqiangnk@...il.com>
>> ---
>>  fs/ext4/ext4_jbd2.c   |    9 +++++++--
>>  fs/ext4/ext4_jbd2.h   |   15 +++++++++++----
>>  fs/ext4/extents.c     |    3 ++-
>>  fs/ext4/inode.c       |   22 +++++++++++++++-------
>>  fs/ext4/move_extent.c |    3 ++-
>>  5 files changed, 37 insertions(+), 15 deletions(-)
>>
>> diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
>> index 560020d..833969b 100644
>> --- a/fs/ext4/ext4_jbd2.c
>> +++ b/fs/ext4/ext4_jbd2.c
>> @@ -23,13 +23,16 @@ int __ext4_journal_get_undo_access(const char *where, unsigned int line,
>>       return err;
>>  }
>>
>> -int __ext4_journal_get_write_access(const char *where, unsigned int line,
>> -                                 handle_t *handle, struct buffer_head *bh)
>> +int __ext4_journal_get_write_access_inode(const char *where, unsigned int line,
>> +                                      handle_t *handle, struct inode *inode,
>> +                                      struct buffer_head *bh, int exclude)
>>  {
>>       int err = 0;
>>
>>       if (ext4_handle_valid(handle)) {
>>               err = jbd2_journal_get_write_access(handle, bh);
>> +             if (!err && !exclude)
>> +                     err = ext4_snapshot_get_write_access(handle, inode, bh);
>
> Agh, this is not defined anywhere again. Actually it is defined only if
> snapshot is not configured in. It is quite painful to review when half
> of the code is missing really. And also something like this will break
> bisecting for all of us. Is not there really the other way ?

Oh, sorry for the pain, I was trying to make life easier for reviewers, but that
often results in the opposite outcome...
These 'core' patches are not meant for merging, just for initial review.
In the 'full' patches, ext4_snapshot_get_write_access() is defined for
both configurations.


>
> Also, could you document the new parameters ?
>
> Anyway:
>        if (!err && !exclude && inode)
>

It's documented in the snapshot hooks that inode can be NULL, so in the 'full'
patches that should be clear. sorry :-/
I promise to post the 'full' series soon.

>>               if (err)
>>                       ext4_journal_abort_handle(where, line, __func__, bh,
>>                                                 handle, err);
>> @@ -111,6 +114,8 @@ int __ext4_journal_get_create_access(const char *where, unsigned int line,
>>
>>       if (ext4_handle_valid(handle)) {
>>               err = jbd2_journal_get_create_access(handle, bh);
>> +             if (!err)
>> +                     err = ext4_snapshot_get_create_access(handle, bh);
>>               if (err)
>>                       ext4_journal_abort_handle(where, line, __func__,
>>                                                 bh, handle, err);
>> diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
>> index 8ffffb1..75662f7 100644
>> --- a/fs/ext4/ext4_jbd2.h
>> +++ b/fs/ext4/ext4_jbd2.h
>> @@ -132,9 +132,9 @@ void ext4_journal_abort_handle(const char *caller, unsigned int line,
>>  int __ext4_journal_get_undo_access(const char *where, unsigned int line,
>>                                  handle_t *handle, struct buffer_head *bh);
>>
>> -int __ext4_journal_get_write_access(const char *where, unsigned int line,
>> -                                 handle_t *handle, struct buffer_head *bh);
>> -
>> +int __ext4_journal_get_write_access_inode(const char *where, unsigned int line,
>> +                                      handle_t *handle, struct inode *inode,
>> +                                      struct buffer_head *bh, int exclude);
>>  int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
>>                 int is_metadata, struct inode *inode,
>>                 struct buffer_head *bh, ext4_fsblk_t blocknr);
>> @@ -151,8 +151,15 @@ int __ext4_handle_dirty_super(const char *where, unsigned int line,
>>
>>  #define ext4_journal_get_undo_access(handle, bh) \
>>       __ext4_journal_get_undo_access(__func__, __LINE__, (handle), (bh))
>> +#define ext4_journal_get_write_access_exclude(handle, bh) \
>> +     __ext4_journal_get_write_access_inode(__func__, __LINE__, \
>> +                                              (handle), NULL, (bh), 1)
>>  #define ext4_journal_get_write_access(handle, bh) \
>> -     __ext4_journal_get_write_access(__func__, __LINE__, (handle), (bh))
>> +     __ext4_journal_get_write_access_inode(__func__, __LINE__, \
>> +                                              (handle), NULL, (bh), 0)
>> +#define ext4_journal_get_write_access_inode(handle, inode, bh) \
>> +     __ext4_journal_get_write_access_inode(__func__, __LINE__, \
>> +                                             (handle), (inode), (bh), 0)
>
> Could you add some comments so everyone knows when to use the _exclude
> helper and when not?

Will do. nobody should use it except for exclude bitmap write access.
I should change the name to get_exclude_bitmap_access to make that
more clear.

>
>>  #define ext4_forget(handle, is_metadata, inode, bh, block_nr) \
>>       __ext4_forget(__func__, __LINE__, (handle), (is_metadata), (inode), \
>>                     (bh), (block_nr))
>> diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
>> index 0c3ea93..c8cab3d 100644
>> --- a/fs/ext4/extents.c
>> +++ b/fs/ext4/extents.c
>> @@ -77,7 +77,8 @@ static int ext4_ext_get_access(handle_t *handle, struct inode *inode,
>>  {
>>       if (path->p_bh) {
>>               /* path points to block */
>> -             return ext4_journal_get_write_access(handle, path->p_bh);
>> +             return ext4_journal_get_write_access_inode(handle,
>> +                                     inode, path->p_bh);
>>       }
>>       /* path points to leaf/index in inode body */
>>       /* we use in-core data, no need to protect them */
>> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
>> index a597ff1..b848072 100644
>> --- a/fs/ext4/inode.c
>> +++ b/fs/ext4/inode.c
>> @@ -874,7 +874,8 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
>>        */
>>       if (where->bh) {
>>               BUFFER_TRACE(where->bh, "get_write_access");
>> -             err = ext4_journal_get_write_access(handle, where->bh);
>> +             err = ext4_journal_get_write_access_inode(handle, inode,
>> +                                                        where->bh);
>>               if (err)
>>                       goto err_out;
>>       }
>> @@ -4172,7 +4173,8 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
>>                       goto out_err;
>>               if (bh) {
>>                       BUFFER_TRACE(bh, "retaking write access");
>> -                     err = ext4_journal_get_write_access(handle, bh);
>> +                     err = ext4_journal_get_write_access_inode(handle,
>> +                                                               inode, bh);
>>                       if (unlikely(err))
>>                               goto out_err;
>>               }
>> @@ -4223,7 +4225,8 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
>>
>>       if (this_bh) {                          /* For indirect block */
>>               BUFFER_TRACE(this_bh, "get_write_access");
>> -             err = ext4_journal_get_write_access(handle, this_bh);
>> +             err = ext4_journal_get_write_access_inode(handle, inode,
>> +                                                        this_bh);
>>               /* Important: if we can't update the indirect pointers
>>                * to the blocks, we can't free them. */
>>               if (err)
>> @@ -4386,8 +4389,8 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
>>                                * pointed to by an indirect block: journal it
>>                                */
>>                               BUFFER_TRACE(parent_bh, "get_write_access");
>> -                             if (!ext4_journal_get_write_access(handle,
>> -                                                                parent_bh)){
>> +                             if (!ext4_journal_get_write_access_inode(
>> +                                         handle, inode, parent_bh)){
>>                                       *p = 0;
>>                                       BUFFER_TRACE(parent_bh,
>>                                       "call ext4_handle_dirty_metadata");
>> @@ -4759,9 +4762,14 @@ has_buffer:
>>
>>  int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
>>  {
>> -     /* We have all inode data except xattrs in memory here. */
>> -     return __ext4_get_inode_loc(inode, iloc,
>> +     int in_mem = (!EXT4_SNAPSHOTS(inode->i_sb) &&
>>               !ext4_test_inode_state(inode, EXT4_STATE_XATTR));
>> +
>> +     /*
>> +      * We have all inode's data except xattrs in memory here,
>> +      * but we must always read-in the entire inode block for COW.
>> +      */
>> +     return __ext4_get_inode_loc(inode, iloc, in_mem);
>>  }
>>
>>  void ext4_set_inode_flags(struct inode *inode)
>> diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
>> index b9f3e78..ad5409a 100644
>> --- a/fs/ext4/move_extent.c
>> +++ b/fs/ext4/move_extent.c
>> @@ -421,7 +421,8 @@ mext_insert_extents(handle_t *handle, struct inode *orig_inode,
>>
>>       if (depth) {
>>               /* Register to journal */
>> -             ret = ext4_journal_get_write_access(handle, orig_path->p_bh);
>> +             ret = ext4_journal_get_write_access_inode(handle,
>> +                                     orig_inode, orig_path->p_bh);
>>               if (ret)
>>                       return ret;
>>       }
>>
>
> --
>
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ