From nobody Wed Oct 1 23:27:49 2025 Received: from out-170.mta0.migadu.com (out-170.mta0.migadu.com [91.218.175.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 901D6258CD7 for ; Fri, 26 Sep 2025 02:23:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758853423; cv=none; b=lqgbEmMGcCjBEjT0714kVEovLfFIuHImP/viBUsG8yHTxyKjUq0XBh7y2UxnZmGcexkLj7rD9eS0Ky8XZWAy25XRfwUMfe7E4cQSqj4cQ6z9xtYLSx/yzTCn6niyUqLGfGVEyulWTFnOXYymoumeT323ndCZcTqgBL39550oysA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758853423; c=relaxed/simple; bh=03intFBuR12n5Xre+XE44wZlrnRELjVcZ4XDVUx8RH4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BWO6r4Y0Y+zG0T2E05b4Gki1/tyfckiqkD8D6ZiN5fvwX2jRUXKtQLxFWwiZXL3YjQcb3OJrtYQDSJhRbcRXsW2PNZeRUuBrVgXqbM/4QRGmpfjATS3rXveLX0qrYYK1+XcYyivubWJsmTlkXUvRpKHNHHUVvovylQfj9iNdlHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=BNiipk4o; arc=none smtp.client-ip=91.218.175.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="BNiipk4o" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1758853418; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zANDTeVI0tZPCMAhDyTdeSxz2VUrPHZhrCLKm1twdBY=; b=BNiipk4o8RtLlbVthb7EA9hU0SJLmSFpohGEW5ezyJfim+VwLZdkWU4x8NQi70LoQZp6Fd 2bGIGolWRjTxuwtatvCerlYAt8LxgIHcU9/Qzc2cqiTyBE3R6HqS8DB5m7x8/me+6jSLEw IYHodkPKh4i2DU+erMxd4G9pAxLusXg= From: Youling Tang To: Kent Overstreet Cc: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org, youling.tang@linux.dev, Youling Tang Subject: [PATCH 1/3] bcachefs: return -EMLINK instead of -EINVAL when hard link count exceeds limit Date: Fri, 26 Sep 2025 10:21:48 +0800 Message-ID: <20250926022150.493115-2-youling.tang@linux.dev> In-Reply-To: <20250926022150.493115-1-youling.tang@linux.dev> References: <20250926022150.493115-1-youling.tang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Youling Tang Currently bcachefs returns -EINVAL when the hard link count reaches U32_MAX. However, -EINVAL is a generic invalid argument error that doesn't accurately convey the specific "too many links" condition. This patch changes the error return code from -EINVAL to -EMLINK when the hard link count limit is exceeded, providing more precise error information to userspace and making it consistent with other filesystems' behavior. Signed-off-by: Youling Tang --- fs/bcachefs/errcode.h | 1 + fs/bcachefs/inode.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h index acc3b7b67704..b22a694ec750 100644 --- a/fs/bcachefs/errcode.h +++ b/fs/bcachefs/errcode.h @@ -215,6 +215,7 @@ 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/inode.c b/fs/bcachefs/inode.c index ef4cc7395b86..5765144b4d65 100644 --- a/fs/bcachefs/inode.c +++ b/fs/bcachefs/inode.c @@ -1193,7 +1193,7 @@ int bch2_inode_nlink_inc(struct bch_inode_unpacked *b= i) bi->bi_flags &=3D ~BCH_INODE_unlinked; else { if (bi->bi_nlink =3D=3D U32_MAX) - return -EINVAL; + return -BCH_ERR_too_many_links; =20 bi->bi_nlink++; } --=20 2.43.0 From nobody Wed Oct 1 23:27:49 2025 Received: from out-184.mta0.migadu.com (out-184.mta0.migadu.com [91.218.175.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4FB1838DE1 for ; Fri, 26 Sep 2025 02:23:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758853424; cv=none; b=eRY6jvQ809UCCn3hGVpu0OKsS5TgZ99E3NIC0sBQD5KzavYlAXB/OL2pvsU0YgJ6Uc3ohqnxk19PZa8FCImm0rNMlqeKd4JfTEjiSk5xSiCYFsipw80NZjqfj01gy5FLArkfE5vaxvQrZZuTQ9PHx62COAGra0TflULreJ9IIF8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758853424; c=relaxed/simple; bh=04GF3OnZ/QyVrtEwN7P7etDZ6D8+7rjpnX26eWB/D34=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cObN65W9RFW/GrPktSDJ6D2bTiwj3I+8lhFr7O4vI5H789dkOX8LVqeLynyWmJVz0lED1T+bk0/+wbZf0KcCKXUIDFwsJxeuDzEP4MqLJ8WypGfw5AWj3TsoQ4KCWwBdwMaMVOKBPYXCqJ1ED+nPZNiqHxptUJSjX0oK2NsYg0s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=xjEVrX1C; arc=none smtp.client-ip=91.218.175.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="xjEVrX1C" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1758853420; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YNKNWfE1GCfxOnqhCzzOBU2T4tSbBc4ZLZn+yzvKoWA=; b=xjEVrX1CbvdFD/dNj5SNlLvH/uTQpgumurH/yvZ96H0RJzZjIk+g3wVrKwylOq/YOL7w9e 4zP6PqRV1Prv0DHls3KdlRmAJ0u1RHVtAqk8kFNMBILWv0tlsjgw3TCD3Bd7HivdwyC8Ys ctLPf+1/sbDch7nCS5rLrMlt9kCYRMU= From: Youling Tang To: Kent Overstreet Cc: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org, youling.tang@linux.dev, Youling Tang Subject: [PATCH 2/3] bcachefs: Fix maximum link count check when creating hard links Date: Fri, 26 Sep 2025 10:21:49 +0800 Message-ID: <20250926022150.493115-3-youling.tang@linux.dev> In-Reply-To: <20250926022150.493115-1-youling.tang@linux.dev> References: <20250926022150.493115-1-youling.tang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Youling Tang When I changed the maximum link count U32_MAX to 4 for testing purposes, I discovered that for regular files, the maximum number of hard links created could actually reach 5 (`inode->i_nlink`). This occurs because `bi->bi_nlink` does not represent the actual `inode->i_= nlink` value, but rather equals `inode->i_nlink - nlink_bias(bi->bi_mode)`. Theref= ore, the `bi->bi_nlink` check in bch2_inode_nlink_inc() needs to be corrected. Signed-off-by: Youling Tang --- NOTE: If pathconf is to be added to support _PC_LINK_MAX for bcachefs in libc later, BCH_LINK_MAX can be defined as ((1U << 31) - 1U) like xfs. fs/bcachefs/bcachefs.h | 1 + fs/bcachefs/inode.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index ddfacad0f70c..9d5e6866b1b6 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -714,6 +714,7 @@ struct btree_debug { unsigned id; }; =20 +#define BCH_LINK_MAX U32_MAX #define BCH_TRANSACTIONS_NR 128 =20 struct btree_transaction_stats { diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c index 5765144b4d65..eedffb505517 100644 --- a/fs/bcachefs/inode.c +++ b/fs/bcachefs/inode.c @@ -1192,7 +1192,7 @@ int bch2_inode_nlink_inc(struct bch_inode_unpacked *b= i) if (bi->bi_flags & BCH_INODE_unlinked) bi->bi_flags &=3D ~BCH_INODE_unlinked; else { - if (bi->bi_nlink =3D=3D U32_MAX) + if (bi->bi_nlink =3D=3D BCH_LINK_MAX - nlink_bias(bi->bi_mode)) return -BCH_ERR_too_many_links; =20 bi->bi_nlink++; --=20 2.43.0 From nobody Wed Oct 1 23:27:49 2025 Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [91.218.175.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9AB042405E1 for ; Fri, 26 Sep 2025 02:23:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758853425; cv=none; b=X+56I8OC735JZl0EtOB1MEv678KMX4Tz2drZuSCOOZOtN2JbQLRCVpEjv74yhHNknsPvxy/URDhU5AFMjZbdmGH0y2PUuCxsCxNOexqoR+BG03axQbzPZs3Y4SAyKd5LLKiv+yWvicUH/PPYinOSjN+qAR9X69w2ttEJtJ0WMu4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758853425; c=relaxed/simple; bh=0NXTGrLTPNSxZcUiq6+ZbqY/OReSGiuA7MewAxYgCiw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VpxNufP03u9d4U6Kd7Vxb7k8+XbeedvgeKCOi/EU4BPmlFeVdGaOnx1QnHE/c+pZhtGUuKNv9YxA5DfyNGROcB4cptqc4leCvEqmbeu+rOnf3pYqVG7yDbB43uiI6cWUVr/RJ2rPiTgAQPHbx0s5jqLdSw2wdqoAShHBSO6+XYc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=GrCqayRs; arc=none smtp.client-ip=91.218.175.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="GrCqayRs" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1758853421; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=73MJ7cpZle+sMbrPOgXtkiLILSGA2P6+DUvxQ0cmryc=; b=GrCqayRshtnlk4PLiLqMbdEKJqnAHc/DgbGbDqUqtrKXwoJqO5YVpN7vaukGrLUupLH41f C5nOhHSU3vGtErDeuTO60+Tk2AN7t5ADbjQrX4X9WMtoieil9G+mcuhIoKLgwE88TgUOVO 8Uv4XH/hqm4jzIZYOapwOp1XFKVK91c= From: Youling Tang To: Kent Overstreet Cc: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org, youling.tang@linux.dev, Youling Tang Subject: [PATCH 3/3] bcachefs: Move the link counting check to the VFS layer Date: Fri, 26 Sep 2025 10:21:50 +0800 Message-ID: <20250926022150.493115-4-youling.tang@linux.dev> In-Reply-To: <20250926022150.493115-1-youling.tang@linux.dev> References: <20250926022150.493115-1-youling.tang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Youling Tang 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 --- 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 =3D c->sb.nsec_per_time_unit; sb->s_time_min =3D div_s64(S64_MIN, c->sb.time_units_per_sec) + 1; sb->s_time_max =3D div_s64(S64_MAX, c->sb.time_units_per_sec); + sb->s_max_links =3D BCH_LINK_MAX; super_set_uuid(sb, c->sb.user_uuid.b, sizeof(c->sb.user_uuid)); =20 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 inu= m) return ret; } =20 -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 &=3D ~BCH_INODE_unlinked; - else { - if (bi->bi_nlink =3D=3D BCH_LINK_MAX - nlink_bias(bi->bi_mode)) - return -BCH_ERR_too_many_links; - + else bi->bi_nlink++; - } - - return 0; } =20 void bch2_inode_nlink_dec(struct btree_trans *trans, struct bch_inode_unpa= cked *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_inod= e_unpacked *bi, } } =20 -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 = *); =20 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; =20 inode_u->bi_ctime =3D now; - ret =3D bch2_inode_nlink_inc(inode_u); - if (ret) - goto err; + bch2_inode_nlink_inc(inode_u); =20 ret =3D bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent); if (ret) --=20 2.43.0