[PATCH 3/3] bcachefs: Move the link counting check to the VFS layer

Youling Tang posted 3 patches 5 days, 21 hours ago
[PATCH 3/3] bcachefs: Move the link counting check to the VFS layer
Posted by Youling Tang 5 days, 21 hours ago
From: Youling Tang <tangyouling@kylinos.cn>

Currently bcachefs only performs link count checks during link operations,
during rename and mkdir operations, the link count should also be checked.

This patch moves the checks to the vfs_{link,rename,mkdir} functions when
sb->s_max_links is set, eliminating the need for filesystem-specific checks.

Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
 fs/bcachefs/errcode.h |  1 -
 fs/bcachefs/fs.c      |  1 +
 fs/bcachefs/inode.c   | 10 ++--------
 fs/bcachefs/inode.h   |  2 +-
 fs/bcachefs/namei.c   |  4 +---
 5 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h
index b22a694ec750..acc3b7b67704 100644
--- a/fs/bcachefs/errcode.h
+++ b/fs/bcachefs/errcode.h
@@ -215,7 +215,6 @@
 	x(EINVAL,			varint_decode_error)			\
 	x(EINVAL,			erasure_coding_found_btree_node)	\
 	x(EINVAL,			option_negative)			\
-	x(EMLINK,			too_many_links)				\
 	x(EOPNOTSUPP,			may_not_use_incompat_feature)		\
 	x(EROFS,			erofs_trans_commit)			\
 	x(EROFS,			erofs_no_writes)			\
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index 687af0eea0c2..6b60c97c5610 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -2526,6 +2526,7 @@ static int bch2_fs_get_tree(struct fs_context *fc)
 	sb->s_time_gran		= c->sb.nsec_per_time_unit;
 	sb->s_time_min		= div_s64(S64_MIN, c->sb.time_units_per_sec) + 1;
 	sb->s_time_max		= div_s64(S64_MAX, c->sb.time_units_per_sec);
+	sb->s_max_links		= BCH_LINK_MAX;
 	super_set_uuid(sb, c->sb.user_uuid.b, sizeof(c->sb.user_uuid));
 
 	if (c->sb.multi_device)
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
index eedffb505517..20e58258c813 100644
--- a/fs/bcachefs/inode.c
+++ b/fs/bcachefs/inode.c
@@ -1187,18 +1187,12 @@ int bch2_inode_rm(struct bch_fs *c, subvol_inum inum)
 	return ret;
 }
 
-int bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
+void bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
 {
 	if (bi->bi_flags & BCH_INODE_unlinked)
 		bi->bi_flags &= ~BCH_INODE_unlinked;
-	else {
-		if (bi->bi_nlink == BCH_LINK_MAX - nlink_bias(bi->bi_mode))
-			return -BCH_ERR_too_many_links;
-
+	else
 		bi->bi_nlink++;
-	}
-
-	return 0;
 }
 
 void bch2_inode_nlink_dec(struct btree_trans *trans, struct bch_inode_unpacked *bi)
diff --git a/fs/bcachefs/inode.h b/fs/bcachefs/inode.h
index b8ec3e628d90..99de17e9f32c 100644
--- a/fs/bcachefs/inode.h
+++ b/fs/bcachefs/inode.h
@@ -285,7 +285,7 @@ static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi,
 	}
 }
 
-int bch2_inode_nlink_inc(struct bch_inode_unpacked *);
+void bch2_inode_nlink_inc(struct bch_inode_unpacked *);
 void bch2_inode_nlink_dec(struct btree_trans *, struct bch_inode_unpacked *);
 
 struct bch_opts bch2_inode_opts_to_opts(struct bch_inode_unpacked *);
diff --git a/fs/bcachefs/namei.c b/fs/bcachefs/namei.c
index c3f87c59922d..42e06baa2e43 100644
--- a/fs/bcachefs/namei.c
+++ b/fs/bcachefs/namei.c
@@ -221,9 +221,7 @@ int bch2_link_trans(struct btree_trans *trans,
 		return ret;
 
 	inode_u->bi_ctime = now;
-	ret = bch2_inode_nlink_inc(inode_u);
-	if (ret)
-		goto err;
+	bch2_inode_nlink_inc(inode_u);
 
 	ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent);
 	if (ret)
-- 
2.43.0
Re: [PATCH 3/3] bcachefs: Move the link counting check to the VFS layer
Posted by Kent Overstreet 5 days, 19 hours ago
On Fri, Sep 26, 2025 at 10:21:50AM +0800, Youling Tang wrote:
> From: Youling Tang <tangyouling@kylinos.cn>
> 
> Currently bcachefs only performs link count checks during link operations,
> during rename and mkdir operations, the link count should also be checked.
> 
> This patch moves the checks to the vfs_{link,rename,mkdir} functions when
> sb->s_max_links is set, eliminating the need for filesystem-specific checks.
> 
> Signed-off-by: Youling Tang <tangyouling@kylinos.cn>

I applied the other two patches, but not this one. We can't rely on the
VFS for checks like this, there's lots of routes to modifying the
filesystem that don't go through the VFS.
Re: [PATCH 3/3] bcachefs: Move the link counting check to the VFS layer
Posted by Youling Tang 5 days, 19 hours ago
Hi, Kent
On 9/26/25 11:42, Kent Overstreet wrote:
> On Fri, Sep 26, 2025 at 10:21:50AM +0800, Youling Tang wrote:
>> From: Youling Tang <tangyouling@kylinos.cn>
>>
>> Currently bcachefs only performs link count checks during link operations,
>> during rename and mkdir operations, the link count should also be checked.
>>
>> This patch moves the checks to the vfs_{link,rename,mkdir} functions when
>> sb->s_max_links is set, eliminating the need for filesystem-specific checks.
>>
>> Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
> I applied the other two patches, but not this one. We can't rely on the
> VFS for checks like this, there's lots of routes to modifying the
> filesystem that don't go through the VFS.
```
vfs_link
     bch2_link
         __bch2_link
             bch2_link_trans
                 bch2_inode_nlink_inc

bch2_symlink
     __bch2_link
```
I have traversed the bcachefs code and found that bch2_inode_nlink_inc is
called only once by bch2_link_trans, which in turn is called only once
by __bch2_link.

Although __bch2_link is also called by bch2_symlink, symlink operations
don't involve i_nlink values. Therefore, all effective calls to
bch2_inode_nlink_incoriginate from vfs_link. Please let me know if
there are any calls from other sources.

Even without moving to the VFS layer, do we still need to add link count
validation in bch2_{mkdir, rename}?

Thanks,
Youling.