From 3ac87fbf6ac29494dc46134323733551aac1737c Mon Sep 17 00:00:00 2001 From: Mark Tinguely Date: Fri, 16 Aug 2013 18:12:43 +0000 Subject: [PATCH] xfsprogs: fix inode crash in xfs_repair Adding the lost+found in phase 6 could allocate an inode from a new inode chunk. Since this chunk was not around in phase 3 when the inode chunks are verificated and added to the avl tree, the avl tree look up will return a NULL pointer. This results in a NULL defererence and segmentation fault. Add the newly created inode chunk as if found in the chunk verification phase. Signed-off-by: Mark Tinguely Reviewed-by: Rich Johnston Signed-off-by: Rich Johnston --- repair/incore_ino.c | 2 +- repair/phase6.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/repair/incore_ino.c b/repair/incore_ino.c index 2a40727b4..efffe7538 100644 --- a/repair/incore_ino.c +++ b/repair/incore_ino.c @@ -700,7 +700,7 @@ get_inode_parent(ino_tree_node_t *irec, int offset) return(0LL); } -static void +void alloc_ex_data(ino_tree_node_t *irec) { parent_list_t *ptbl; diff --git a/repair/phase6.c b/repair/phase6.c index f94cdaf00..65e630186 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -930,6 +930,22 @@ mk_orphanage(xfs_mount_t *mp) irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ino), XFS_INO_TO_AGINO(mp, ino)); + + if (irec == NULL) { + /* + * This inode is allocated from a newly created inode + * chunk and therefore did not exist when inode chunks + * were processed in phase3. Add this group of inodes to + * the entry avl tree as if they were discovered in phase3. + */ + irec = set_inode_free_alloc(mp, XFS_INO_TO_AGNO(mp, ino), + XFS_INO_TO_AGINO(mp, ino)); + alloc_ex_data(irec); + + for (i = 0; i < XFS_INODES_PER_CHUNK; i++) + set_inode_free(irec, i); + } + ino_offset = get_inode_offset(mp, ino, irec); /* -- 2.39.5