From: Darrick J. Wong Date: Mon, 29 Jul 2024 23:23:02 +0000 (-0700) Subject: mkfs/repair: pin inodes that would otherwise overflow link count X-Git-Tag: v6.10.0~21^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ebf05a446c09336c08865dc29a6332be6ff8223c;p=thirdparty%2Fxfsprogs-dev.git mkfs/repair: pin inodes that would otherwise overflow link count Update userspace utilities not to allow integer overflows of inode link counts to result in a file that is referenced by parent directories but has zero link count. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- diff --git a/libxfs/util.c b/libxfs/util.c index dc54e3ee..74eea0fc 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -252,7 +252,8 @@ libxfs_bumplink( xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); - inc_nlink(inode); + if (inode->i_nlink != XFS_NLINK_PINNED) + inc_nlink(inode); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } diff --git a/repair/incore_ino.c b/repair/incore_ino.c index 0dd7a2f0..6618e534 100644 --- a/repair/incore_ino.c +++ b/repair/incore_ino.c @@ -89,26 +89,30 @@ nlink_grow_16_to_32(ino_tree_node_t *irec) void add_inode_ref(struct ino_tree_node *irec, int ino_offset) { + union ino_nlink *c; + ASSERT(irec->ino_un.ex_data != NULL); pthread_mutex_lock(&irec->lock); + c = &irec->ino_un.ex_data->counted_nlinks; switch (irec->nlink_size) { case sizeof(uint8_t): - if (irec->ino_un.ex_data->counted_nlinks.un8[ino_offset] < 0xff) { - irec->ino_un.ex_data->counted_nlinks.un8[ino_offset]++; + if (c->un8[ino_offset] < 0xff) { + c->un8[ino_offset]++; break; } nlink_grow_8_to_16(irec); /*FALLTHRU*/ case sizeof(uint16_t): - if (irec->ino_un.ex_data->counted_nlinks.un16[ino_offset] < 0xffff) { - irec->ino_un.ex_data->counted_nlinks.un16[ino_offset]++; + if (c->un16[ino_offset] < 0xffff) { + c->un16[ino_offset]++; break; } nlink_grow_16_to_32(irec); /*FALLTHRU*/ case sizeof(uint32_t): - irec->ino_un.ex_data->counted_nlinks.un32[ino_offset]++; + if (c->un32[ino_offset] != XFS_NLINK_PINNED) + c->un32[ino_offset]++; break; default: ASSERT(0);