From: liubo <liubo2009@cn.fujitsu.com>
To: Linux Btrfs <linux-btrfs@vger.kernel.org>
Subject: Re: [PATCH] btrfs: make inode ref log recovery faster
Date: Wed, 23 Feb 2011 09:12:36 +0800 [thread overview]
Message-ID: <4D645F04.4060608@cn.fujitsu.com> (raw)
In-Reply-To: <20110222143203.GB18570@twin.jikos.cz>
On 02/22/2011 10:32 PM, David Sterba wrote:
> Hi,
>
> no deeper analysis done, but the double free error was obvious :)
>
> On Tue, Feb 22, 2011 at 07:42:25PM +0800, liubo wrote:
>> When we recover from crash via write-ahead log tree and process
>> the inode refs, for each btrfs_inode_ref item, we will
>> 1) check if we already have a perfect match in fs/file tree, if
>> we have, then we're done.
>> 2) search the corresponding back reference in fs/file tree, and
>> check all the names in this back reference to see if they are
>> also in the log to avoid conflict corners.
>> 3) recover the logged inode refs to fs/file tree.
>>
>> In current btrfs, however,
>> - for 2)'s check, once is enough, since the checked back references
>> will remain unchanged after processing all the inode refs belonged
>> to the key.
>> - it has no need to do another 1) between 2) and 3).
>>
>> This patch focus on the above problems and
>> I've made a small test to show how it improves,
>>
>> $dd if=/dev/zero of=foobar bs=4K count=1
>> $sync
>> $make 100 hard links continuously, like ln foobar link_i
>> $fsync foobar
>> $echo b > /proc/sysrq-trigger
>> after reboot
>> $time mount DEV PATH
>>
>> without patch:
>> real 0m0.285s
>> user 0m0.001s
>> sys 0m0.009s
>>
>> with patch:
>> real 0m0.123s
>> user 0m0.000s
>> sys 0m0.010s
>>
>> Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
>> ---
>> fs/btrfs/tree-log.c | 33 +++++++++++----------------------
>> 1 files changed, 11 insertions(+), 22 deletions(-)
>>
>> diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
>> index a4bbb85..8f2a9f3 100644
>> --- a/fs/btrfs/tree-log.c
>> +++ b/fs/btrfs/tree-log.c
>> @@ -799,12 +799,12 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
>> struct inode *dir;
>> int ret;
>> struct btrfs_inode_ref *ref;
>> - struct btrfs_dir_item *di;
>> struct inode *inode;
>> char *name;
>> int namelen;
>> unsigned long ref_ptr;
>> unsigned long ref_end;
>> + int search_done = 0;
>>
>> /*
>> * it is possible that we didn't log all the parent directories
>> @@ -845,7 +845,10 @@ again:
>> * existing back reference, and we don't want to create
>> * dangling pointers in the directory.
>> */
>> -conflict_again:
>> +
>> + if (search_done)
>> + goto insert;
>> +
>> ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
>> if (ret == 0) {
>> char *victim_name;
>> @@ -888,35 +891,21 @@ conflict_again:
>> victim_name_len);
>> kfree(victim_name);
> ^^^^^^^^^^^^^^^^^^^
>> btrfs_release_path(root, path);
>> - goto conflict_again;
>> }
>> kfree(victim_name);
> ^^^^^^^^^^^^^^^^^^^
> double free
thanks for reviewing, but the first one is followed by a goto phrase, so IMO it is ok.
>
>> ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
>> }
>> BUG_ON(ret);
>> - }
>> - btrfs_release_path(root, path);
>>
>> - /* look for a conflicting sequence number */
>> - di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino,
>> - btrfs_inode_ref_index(eb, ref),
>> - name, namelen, 0);
>> - if (di && !IS_ERR(di)) {
>> - ret = drop_one_dir_item(trans, root, path, dir, di);
>> - BUG_ON(ret);
>> - }
>> - btrfs_release_path(root, path);
>> -
>> -
>> - /* look for a conflicting name */
>> - di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino,
>> - name, namelen, 0);
>> - if (di && !IS_ERR(di)) {
>> - ret = drop_one_dir_item(trans, root, path, dir, di);
>> - BUG_ON(ret);
>> + /*
>> + * NOTE: we have searched root tree and checked the
>> + * coresponding ref, it does not need to check again.
>> + */
>> + search_done = 1;
>> }
>> btrfs_release_path(root, path);
>>
>> +insert:
>> /* insert our name */
>> ret = btrfs_add_link(trans, dir, inode, name, namelen, 0,
>> btrfs_inode_ref_index(eb, ref));
>> --
>
> d/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
next prev parent reply other threads:[~2011-02-23 1:12 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-22 11:42 [PATCH] btrfs: make inode ref log recovery faster liubo
2011-02-22 14:32 ` David Sterba
2011-02-23 1:12 ` liubo [this message]
2011-02-23 1:30 ` Josef Bacik
2011-02-23 1:42 ` liubo
2011-02-23 7:09 ` [PATCH v2] " liubo
2011-02-23 7:20 ` Li Zefan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D645F04.4060608@cn.fujitsu.com \
--to=liubo2009@cn.fujitsu.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).