static int nffs_restore_should_sweep_inode_entry(struct nffs_inode_entry *inode_entry, int *out_should_sweep) { struct nffs_inode inode; int rc; /* Determine if the inode is a dummy. Dummy inodes have a reference count * of 0. If it is a dummy, increment its reference count back to 1 so that * it can be properly deleted. The presence of a dummy inode during the * final sweep step indicates file system corruption. If the inode is a * directory, all its children should have been migrated to the /lost+found * directory prior to this. */ if (inode_entry->nie_refcnt == 0) { *out_should_sweep = 1; inode_entry->nie_refcnt++; return 0; } /* Determine if the inode has been deleted. If an inode has no parent (and * it isn't the root directory), it has been deleted from the disk and * should be swept from the RAM representation. */ if (inode_entry->nie_hash_entry.nhe_id != NFFS_ID_ROOT_DIR) { rc = nffs_inode_from_entry(&inode, inode_entry); if (rc != 0) { *out_should_sweep = 0; return rc; } if (inode.ni_parent == NULL) { *out_should_sweep = 1; return 0; } } /* If this is a file inode, verify that all of its constituent blocks are * present. */ if (nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id)) { rc = nffs_restore_validate_block_chain( inode_entry->nie_last_block_entry); if (rc == FS_ECORRUPT) { *out_should_sweep = 1; return 0; } else if (rc != 0) { *out_should_sweep = 0; return rc; } } /* This is a valid inode; don't sweep it. */ *out_should_sweep = 0; return 0; }
static int nffs_restore_should_sweep_inode_entry(struct nffs_inode_entry *inode_entry, int *out_should_sweep) { struct nffs_inode inode; int rc; /* * if this inode was tagged to have a dummy block entry and the * flag is still set, that means we didn't find the block and so * should remove this inode and all associated blocks. */ if (nffs_inode_getflags(inode_entry, NFFS_INODE_FLAG_DUMMYLSTBLK)) { *out_should_sweep = 1; /*nffs_inode_inc_refcnt(inode_entry);*/ inode_entry->nie_refcnt = 1; assert(inode_entry->nie_refcnt >= 1); return 0; } /* * This inode was originally created to hold a block that was restored * before the owning inode. If the flag is still set, it means we never * restored the inode from disk and so this entry should be deleted. */ if (nffs_inode_getflags(inode_entry, NFFS_INODE_FLAG_DUMMYINOBLK)) { *out_should_sweep = 2; inode_entry->nie_refcnt = 1; assert(inode_entry->nie_refcnt >= 1); return 0; } /* * Determine if the inode is a dummy. Dummy inodes have a flash * location set to LOC_NONE and should have a flag set for the reason. * The presence of a dummy inode during the final sweep step indicates * file system corruption. It's assumed that directories have * previously migrated all children to /lost+found. */ if (nffs_inode_is_dummy(inode_entry)) { *out_should_sweep = 3; nffs_inode_inc_refcnt(inode_entry); assert(inode_entry->nie_refcnt >= 1); return 0; } /* Determine if the inode has been deleted. If an inode has no parent (and * it isn't the root directory), it has been deleted from the disk and * should be swept from the RAM representation. */ if (inode_entry->nie_hash_entry.nhe_id != NFFS_ID_ROOT_DIR) { rc = nffs_inode_from_entry(&inode, inode_entry); if (rc != 0 && rc != FS_ENOENT) { *out_should_sweep = 0; return rc; } if (inode.ni_parent == NULL) { *out_should_sweep = 4; return 0; } } /* * If this inode has been marked as deleted, we can unlink it here. * * XXX Note that the record of a deletion could be lost if garbage * collection erases the delete but leaves inode updates on other * partitions which can then be restored. */ if (nffs_inode_getflags(inode_entry, NFFS_INODE_FLAG_DELETED)) { rc = nffs_inode_from_entry(&inode, inode_entry); if (rc != 0) { *out_should_sweep = 0; return rc; } *out_should_sweep = 5; } /* If this is a file inode, verify that all of its constituent blocks are * present. */ if (nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id)) { rc = nffs_restore_validate_block_chain( inode_entry->nie_last_block_entry); if (rc == FS_ECORRUPT) { *out_should_sweep = 6; return 0; } else if (rc == FS_ENOENT) { *out_should_sweep = 7; return 0; } else if (rc != 0) { *out_should_sweep = 0; return rc; } } /* This is a valid inode; don't sweep it. */ *out_should_sweep = 0; return 0; }