xfs_repair: phase7.c:148: phase7: Assertion `no_modify || nrefs > 0' failed.
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 317xfs_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
Quoted 4 lines · Arkadiusz Mi??kiewicz
xfs_repairfrom xfsprogs-dev git.kernel.org repositoryon 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
@@ -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
Quoted 5 lines · Christoph Hellwig
Quoted 3 lines · Arkadiusz Mi??kiewicz
xfs_repairfrom xfsprogs-dev git.kernel.org repositoryon 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