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
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.
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.
© 2016 - 2025 Red Hat, Inc.