Skip to contentSkip to conversation

xfs_repair: phase7.c:148: phase7: Assertion `no_modify || nrefs > 0' failed.

DISCUSSION Arkadiusz Miśkiewicz 2 participants 3 messages Feb 20, 2012 – Mar 1, 2012

lore
Share & tools
lore
#0 lore raw

xfs_repair from xfsprogs-dev git.kernel.org repository

on http://routing.com.pl/xfs-metadump-2012-02-20.bz2 fails with:

resetting inode 268740837 nlinks from 6 to 5
resetting inode 268742728 nlinks from 178 to 172
resetting inode 268861622 nlinks from 45 to 44
resetting inode 268902438 nlinks from 4 to 3
resetting inode 268920918 nlinks from 10500 to 10483
resetting inode 269133820 nlinks from 14501 to 9527
resetting inode 269496340 nlinks from 61 to 55
resetting inode 269768793 nlinks from 4 to 3
resetting inode 270532626 nlinks from 9 to 8
resetting inode 339630321 nlinks from 5 to 4
resetting inode 339630322 nlinks from 45 to 39
resetting inode 339630327 nlinks from 25 to 20
resetting inode 536872960 nlinks from 2 to -4276
nlinks -4276 will overflow v1 ino, ino 536872960 will be converted to version 2 resetting inode 536872961 nlinks from 2 to 317
xfs_repair: phase7.c:148: phase7: Assertion `no_modify || nrefs > 0' failed.

whole log: http://ixion.pld-linux.org/~arekm/xfs-log.gz

Patches to test welcome :-)

Signature · 7 lines
Arkadiusz Miśkiewicz        PLD/Linux Team
arekm / maven.pl            http://ftp.pld-linux.org/

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
#1 lore raw
Quoted 4 lines · Arkadiusz Mi??kiewicz

xfs_repair from xfsprogs-dev git.kernel.org repository

on http://routing.com.pl/xfs-metadump-2012-02-20.bz2 fails with:

The patch below fixes it:

From: Christoph Hellwig <[email protected]>
Subject: repair: fix the variable-width nlink array

It looks like we currently never grow the variable-width nlink array if only the on-disk nlink size overflows 8 bits. This leads to a major mess in nlink counting, and eventually an assert in phase7.

Replace the indirect all mess with a union that allows doing proper array arithmetics while we're at it.

repair/incore.h +14 -47
index fdb7742..8a578b5 100644
@@ -268,11 +268,17 @@ typedef struct parent_list  {
 #endif
 } parent_list_t;
 
+union ino_nlink {
+	__uint8_t	*un8;
+	__uint16_t	*un16;
+	__uint32_t	*un32;
+};
+
 typedef struct ino_ex_data  {
 	__uint64_t		ino_reached;	/* bit == 1 if reached */
 	__uint64_t		ino_processed;	/* reference checked bit mask */
 	parent_list_t		*parents;
-	__uint8_t		*counted_nlinks;/* counted nlinks in P6 */
+	union ino_nlink		counted_nlinks;/* counted nlinks in P6 */
 } ino_ex_data_t;
 
 typedef struct ino_tree_node  {
@@ -281,8 +287,8 @@ typedef struct ino_tree_node  {
 	xfs_inofree_t		ir_free;	/* inode free bit mask */
 	__uint64_t		ino_confirmed;	/* confirmed bitmask */
 	__uint64_t		ino_isa_dir;	/* bit == 1 if a directory */
-	struct nlink_ops	*nlinkops;	/* pointer to current nlink ops */
-	__uint8_t		*disk_nlinks;	/* on-disk nlinks, set in P3 */
+	__uint8_t		nlink_size;
+	union ino_nlink		disk_nlinks;	/* on-disk nlinks, set in P3 */
 	union  {
 		ino_ex_data_t	*ex_data;	/* phases 6,7 */
 		parent_list_t	*plist;		/* phases 2-5 */
@@ -292,16 +298,6 @@ typedef struct ino_tree_node  {
 #define INOS_PER_IREC	(sizeof(__uint64_t) * NBBY)
 #define	IREC_MASK(i)	((__uint64_t)1 << (i))
 
-typedef struct nlink_ops {
-	const int	nlink_size;
-	void		(*disk_nlink_set)(ino_tree_node_t *, int, __uint32_t);
-	__uint32_t	(*disk_nlink_get)(ino_tree_node_t *, int);
-	__uint32_t	(*counted_nlink_get)(ino_tree_node_t *, int);
-	__uint32_t	(*counted_nlink_inc)(ino_tree_node_t *, int);
-	__uint32_t	(*counted_nlink_dec)(ino_tree_node_t *, int);
-} nlink_ops_t;
-
-
 void		add_ino_ex_data(xfs_mount_t *mp);
 
 /*
@@ -460,29 +456,12 @@ static inline int is_inode_free(struct ino_tree_node *irec, int offset)
  * detected and drop_inode_ref() is called every time a link to
  * an inode that we've counted is removed.
  */
+void add_inode_ref(struct ino_tree_node *irec, int offset);
+void drop_inode_ref(struct ino_tree_node *irec, int offset);
+__uint32_t num_inode_references(struct ino_tree_node *irec, int offset);
 
-static inline void add_inode_ref(struct ino_tree_node *irec, int offset)
-{
-	ASSERT(irec->ino_un.ex_data != NULL);
-
-	irec->nlinkops->counted_nlink_inc(irec, offset);
-}
-
-static inline void drop_inode_ref(struct ino_tree_node *irec, int offset)
-{
-	ASSERT(irec->ino_un.ex_data != NULL);
-
-	if (irec->nlinkops->counted_nlink_dec(irec, offset) == 0)
-		irec->ino_un.ex_data->ino_reached &= ~IREC_MASK(offset);
-}
-
-static inline __uint32_t num_inode_references(struct ino_tree_node *irec,
-		int offset)
-{
-	ASSERT(irec->ino_un.ex_data != NULL);
-
-	return irec->nlinkops->counted_nlink_get(irec, offset);
-}
+void set_inode_disk_nlinks(struct ino_tree_node *irec, int offset, __uint32_t nlinks);
+__uint32_t get_inode_disk_nlinks(struct ino_tree_node *irec, int offset);
 
 static inline int is_inode_reached(struct ino_tree_node *irec, int offset)
 {
@@ -496,18 +475,6 @@ static inline void add_inode_reached(struct ino_tree_node *irec, int offset)
 	irec->ino_un.ex_data->ino_reached |= IREC_MASK(offset);
 }
 
-static inline void set_inode_disk_nlinks(struct ino_tree_node *irec, int offset,
-		__uint32_t nlinks)
-{
-	irec->nlinkops->disk_nlink_set(irec, offset, nlinks);
-}
-
-static inline __uint32_t get_inode_disk_nlinks(struct ino_tree_node *irec,
-		int offset)
-{
-	return irec->nlinkops->disk_nlink_get(irec, offset);
-}
-
 /*
  * set/get inode number of parent -- works for directory inodes only
  */
repair/incore_ino.c +170 -153

394 lines not on this page · raw message

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#2 lore raw
Quoted 5 lines · Christoph Hellwig
Quoted 3 lines · Arkadiusz Mi??kiewicz

xfs_repair from xfsprogs-dev git.kernel.org repository

on http://routing.com.pl/xfs-metadump-2012-02-20.bz2 fails with:

The patch below fixes it:

Worked fine (repair finished successfully) on a real fs. Thanks!

Signature · 7 lines
Arkadiusz Miśkiewicz        PLD/Linux Team
arekm / maven.pl            http://ftp.pld-linux.org/

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs