All of lore.kernel.org
 help / color / mirror / Atom feed
From: Guoyu Ou <benogy@gmail.com>
To: Kent Overstreet <kent.overstreet@linux.dev>
Cc: linux-bcachefs@vger.kernel.org, benogy@gmail.com
Subject: Re: [PATCH v3] bcachefs: skip invisible entries in empty subvolume checking
Date: Wed, 14 Feb 2024 15:03:15 +0800	[thread overview]
Message-ID: <ZcxlXyHP8evlVLUB@ousvr> (raw)
In-Reply-To: <bkgmhj35rvon4e2gawwn5qepeitppss4kiharvetcl46q6x2pj@3c7jrrbtxco4>

sorry for cc linux-bcachefs...

On Tue, Feb 13, 2024 at 09:38:39PM -0500, Kent Overstreet wrote:
> On Tue, Feb 13, 2024 at 04:20:04PM +0800, Guoyu Ou wrote:
> > When we are checking whether a subvolume is empty in the specified snapshot,
> > entries that do not belong to this subvolume should be skipped.
> > 
> > This fixes the following case:
> > 
> >     $ bcachefs subvolume create ./sub
> >     $ cd sub
> >     $ bcachefs subvolume create ./sub2
> >     $ bcachefs subvolume snapshot . ./snap
> >     $ ls -a snap
> >     . ..
> >     $ rmdir snap
> >     rmdir: failed to remove 'snap': Directory not empty
> > 
> > As Kent suggested, we pass 0 in may_delete_deleted_inode() to ignore subvols
> > in the subvol we are checking, because inode.bi_subvol is only set on
> > subvolume roots, and we can't go through every inode in the subvolume and
> > change bi_subvol when taking a snapshot. It makes the check less strict, but
> > that's ok, the rest of fsck will still catch it.
> > 
> > Signed-off-by: Guoyu Ou <benogy@gmail.com>
> > ---
> >  fs/bcachefs/dirent.c | 7 +++++--
> >  fs/bcachefs/dirent.h | 2 +-
> >  fs/bcachefs/inode.c  | 2 +-
> >  3 files changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c
> > index 4ae1e9f002a0..82c5bff01411 100644
> > --- a/fs/bcachefs/dirent.c
> > +++ b/fs/bcachefs/dirent.c
> > @@ -508,7 +508,7 @@ u64 bch2_dirent_lookup(struct bch_fs *c, subvol_inum dir,
> >  	return ret;
> >  }
> >  
> > -int bch2_empty_dir_snapshot(struct btree_trans *trans, u64 dir, u32 snapshot)
> > +int bch2_empty_dir_snapshot(struct btree_trans *trans, u64 dir, u32 subvol, u32 snapshot)
> >  {
> >  	struct btree_iter iter;
> >  	struct bkey_s_c k;
> > @@ -518,6 +518,9 @@ int bch2_empty_dir_snapshot(struct btree_trans *trans, u64 dir, u32 snapshot)
> >  			   SPOS(dir, 0, snapshot),
> >  			   POS(dir, U64_MAX), 0, k, ret)
> >  		if (k.k->type == KEY_TYPE_dirent) {
> > +			struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k);
> > +			if (d.v->d_type == DT_SUBVOL && le32_to_cpu(d.v->d_parent_subvol) != subvol)
> > +				continue;
> 
> 
> if (d.v->d_type == DT_SUBVOL && (le32_to_cpu(d.v->d_parent_subvol) != subvol || !subvol))

If 0 is an invalid value for subvolume ids, the predicate

le32_to_cpu(d.v->d_parent_subvol) != subvol

is always true for subvol == 0 and there's no need to add !subvol.

Otherwise, I think it's better to add a flag to indicate whether we are checking subvol in
bch2_empty_dir_snapshot(), like

int bch2_empty_dir_snapshot(struct btree_trans *, u64 dir, u32 subvol, bool check_subvol, u32 snapshot)
{
    ...
        if (d.v->d_type == DT_SUBVOL && (check_subvol && le32_to_cpu(d.v->d_parent_subvol) != subvol))
}

or can we use a different helper function, rather than bch2_empty_dir_snapshot(), for may_delete_deleted_inode() ?

> 
> >  			ret = -ENOTEMPTY;
> >  			break;
> >  		}
> > @@ -531,7 +534,7 @@ int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
> >  	u32 snapshot;
> >  
> >  	return bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot) ?:
> > -		bch2_empty_dir_snapshot(trans, dir.inum, snapshot);
> > +		bch2_empty_dir_snapshot(trans, dir.inum, dir.subvol, snapshot);
> >  }
> >  
> >  int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
> > diff --git a/fs/bcachefs/dirent.h b/fs/bcachefs/dirent.h
> > index 21ffeb78f02e..aeb8207ca9f2 100644
> > --- a/fs/bcachefs/dirent.h
> > +++ b/fs/bcachefs/dirent.h
> > @@ -69,7 +69,7 @@ u64 bch2_dirent_lookup(struct bch_fs *, subvol_inum,
> >  		       const struct bch_hash_info *,
> >  		       const struct qstr *, subvol_inum *);
> >  
> > -int bch2_empty_dir_snapshot(struct btree_trans *, u64, u32);
> > +int bch2_empty_dir_snapshot(struct btree_trans *, u64, u32, u32);
> >  int bch2_empty_dir_trans(struct btree_trans *, subvol_inum);
> >  int bch2_readdir(struct bch_fs *, subvol_inum, struct dir_context *);
> >  
> > diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
> > index 086f0090b03a..84a6e5011032 100644
> > --- a/fs/bcachefs/inode.c
> > +++ b/fs/bcachefs/inode.c
> > @@ -1088,7 +1088,7 @@ static int may_delete_deleted_inode(struct btree_trans *trans,
> >  		goto out;
> >  
> >  	if (S_ISDIR(inode.bi_mode)) {
> > -		ret = bch2_empty_dir_snapshot(trans, pos.offset, pos.snapshot);
> > +		ret = bch2_empty_dir_snapshot(trans, pos.offset, 0, pos.snapshot);
> >  		if (fsck_err_on(ret == -ENOTEMPTY, c, deleted_inode_is_dir,
> >  				"non empty directory %llu:%u in deleted_inodes btree",
> >  				pos.offset, pos.snapshot))
> > -- 
> > 2.43.0
> > 

  reply	other threads:[~2024-02-14  7:03 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-13  8:20 [PATCH v3] bcachefs: skip invisible entries in empty subvolume checking Guoyu Ou
2024-02-14  2:38 ` Kent Overstreet
2024-02-14  7:03   ` Guoyu Ou [this message]
2024-02-16  0:26     ` Kent Overstreet

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=ZcxlXyHP8evlVLUB@ousvr \
    --to=benogy@gmail.com \
    --cc=kent.overstreet@linux.dev \
    --cc=linux-bcachefs@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.