From: Alexander Block <ablock84@googlemail.com>
To: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Cc: linux-btrfs@vger.kernel.org
Subject: Re: btrfs send/receive: if new inode ino is less than its new directory ino, incorrect path is sent
Date: Sat, 28 Jul 2012 11:56:19 +0200 [thread overview]
Message-ID: <CAB9VWqAPvjyQ3EhcZQC59b0qcGr3QFozP60A0q+=FiRv3wxgbg@mail.gmail.com> (raw)
In-Reply-To: <CAHf9xvYApp7yEmX7BCi1Y3Ut7hX2VDxAkJgAxNp-FtkQCBiXUQ@mail.gmail.com>
On Fri, Jul 27, 2012 at 4:37 PM, Alex Lyakas
<alex.bolshoy.btrfs@gmail.com> wrote:
> Hi Alexander,
> your solution is simple and elegant. I this this issue is solved now. Thanks!
> Two minor issues:
> 1)
> /*
> * We need some special handling for inodes that get processed before the parent
> * directory got created. See process_all_refs for details.
> * This function does the check if we already created the dir out of order.
> */
> /*
> * Only creates the inode if it is:
> * 1. Not a directory
> * 2. Or a directory which was not created already due to out of order
> * directories. See did_create_dir and process_all_refs for details.
> */
>
> These comments tell to look at process_all_refs(), while we should
> look at process_recorded_refs().
>
> 2)
> * We can however not delete the orphan in case the inode relies
> * in a directory that was not created yet (see
> * __record_new_ref)
> */
> This part should be removed, because your new solution does not work this way.
Whoops...corrected all comments.
>
>
> If you find, time, pls look at the two attached scripts.
>
> btrfs_test_1.sh:
> it tries to explore the is_first_ref() issue and founds a problem.
> Proposed patch - compare also the (dir,gen) tuple and only the name:
>
> diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
> index 68e504c..b83ec5f 100644
> --- a/fs/btrfs/send.c
> +++ b/fs/btrfs/send.c
> @@ -1597,7 +1597,7 @@ out:
>
> static int is_first_ref(struct send_ctx *sctx,
> struct btrfs_root *root,
> - u64 ino, u64 dir,
> + u64 ino, u64 dir, u64 dir_gen,
> const char *name, int name_len)
> {
> int ret;
> @@ -1613,6 +1613,11 @@ static int is_first_ref(struct send_ctx *sctx,
> if (ret < 0)
> goto out;
>
> + if (dir != tmp_dir || dir_gen != tmp_dir_gen) {
> + ret = 0;
> + goto out;
> + }
> +
> if (name_len != fs_path_len(tmp_name)) {
> ret = 0;
> goto out;
> @@ -2834,7 +2839,7 @@ verbose_printk("btrfs: process_recorded_refs
> %llu\n", sctx->cur_ino);
> goto out;
> if (ret) {
> ret = is_first_ref(sctx, sctx->parent_root,
> - ow_inode, cur->dir, cur->name,
> + ow_inode, cur->dir,
> cur->dir_gen, cur->name,
> cur->name_len);
> if (ret < 0)
> goto out;
>
I did not apply the patch but instead added a check for dir != tmp_dir
only. The reason to not check for gen is that I have a rule in my
mind: I only pass the generation number to functions where I want to
know the *current* state. is_first_ref is for permanent state, the
return value never changes while sending. I could however not
reproduce the problem with test_1.sh, but it should fix it.
>
> btrfs_test_2.sh
> The last test exposes an interesting issue: when a directory has a
> deleted reference recorded, this deleted reference is not added to the
> 'check_dirs' list. As a result, the upper directory (already
> orphanized) is not rmdir'd.
You'll find a commit in my repo to fix this. The problem was, that
moved directories do not get into the delete_refs loop and thus the
parent of the old location is never added to the check_dirs list.
I have force pushed to for-alex, if you have time I'd be happy if you
test again :)
>
> Thanks,
> Alex.
next prev parent reply other threads:[~2012-07-28 9:56 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-18 17:45 btrfs send/receive: if new inode ino is less than its new directory ino, incorrect path is sent Alex Lyakas
2012-07-24 20:26 ` Alexander Block
2012-07-26 10:52 ` Alex Lyakas
2012-07-26 14:04 ` Alex Lyakas
2012-07-26 14:07 ` Alexander Block
2012-07-26 21:42 ` Alexander Block
2012-07-27 14:37 ` Alex Lyakas
2012-07-28 9:56 ` Alexander Block [this message]
2012-07-29 15:06 ` Alex Lyakas
2012-07-30 17:35 ` Alex Lyakas
2012-07-30 20:17 ` Alexander Block
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='CAB9VWqAPvjyQ3EhcZQC59b0qcGr3QFozP60A0q+=FiRv3wxgbg@mail.gmail.com' \
--to=ablock84@googlemail.com \
--cc=alex.bolshoy.btrfs@gmail.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).