[PATCH 2/2] mkfs/repair: pin inodes that would otherwise overflow link count

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Darrick J. Wong <djwong@xxxxxxxxxx>

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 <djwong@xxxxxxxxxx>
Reviewed-by: Christoph Hellwig <hch@xxxxxx>
---
 libxfs/util.c       |    3 ++-
 repair/incore_ino.c |   14 +++++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)


diff --git a/libxfs/util.c b/libxfs/util.c
index dc54e3ee6..74eea0fcb 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 0dd7a2f06..6618e534a 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);





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux