/* again, simple before efficient. We just find the old value and * use _set to make sure that the new value updates both the bitmap * and the tree */ void o2fsck_icount_delta(o2fsck_icount *icount, uint64_t blkno, int delta) { int was_set; uint16_t prev_count; icount_node *in; if (delta == 0) return; ocfs2_bitmap_test(icount->ic_single_bm, blkno, &was_set); if (was_set) { prev_count = 1; } else { in = icount_search(icount, blkno, NULL); if (in == NULL) prev_count = 0; else prev_count = in->in_icount; } if (prev_count + delta < 0) com_err(__FUNCTION__, OCFS2_ET_INTERNAL_FAILURE, "while droping icount from %"PRIu16" bt %d for " "inode %"PRIu64, prev_count, delta, blkno); o2fsck_icount_set(icount, blkno, prev_count + delta); }
static void check_root(o2fsck_state *ost) { struct ocfs2_super_block *sb = OCFS2_RAW_SB(ost->ost_fs->fs_super); errcode_t ret; uint64_t blkno, old_root; int was_set; if (o2fsck_test_inode_allocated(ost, ost->ost_fs->fs_root_blkno)) { ocfs2_bitmap_test(ost->ost_dir_inodes, ost->ost_fs->fs_root_blkno, &was_set); if (!was_set) printf("The root inode exists but isn't a " "directory.\n"); return; } if (!prompt(ost, PY, PR_ROOT_DIR_MISSING, "The super block claims that inode %"PRIu64" is the root " "directory but it isn't allocated. Create a new root " "directory and update the super block?", ost->ost_fs->fs_root_blkno)) return; ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR); if (ret) { com_err(whoami, ret, "while trying to allocate a new inode " "for the root directory\n"); return; } ret = ocfs2_init_dir(ost->ost_fs, blkno, blkno); if (ret) { com_err(whoami, ret, "while trying to expand a new root " "directory"); goto out; } o2fsck_icount_set(ost->ost_icount_in_inodes, blkno, 1); o2fsck_icount_set(ost->ost_icount_refs, blkno, 1); ret = o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, ost->ost_fs->fs_root_blkno, ost->ost_fs->fs_root_blkno, 0); if (ret) { com_err(whoami, ret, "while recording a new root directory"); goto out; } old_root = sb->s_root_blkno; ost->ost_fs->fs_root_blkno = blkno; sb->s_root_blkno = blkno; ret = ocfs2_write_primary_super(ost->ost_fs); if (ret) { com_err(whoami, ret, "while writing the super block with a " "new root directory inode"); ost->ost_fs->fs_root_blkno = old_root; sb->s_root_blkno = old_root; goto out; } blkno = 0; out: if (blkno) { ret = ocfs2_delete_inode(ost->ost_fs, blkno); if (ret) { com_err(whoami, ret, "while trying to clean up an " "an allocated inode after linking /lost+found " "failed"); } } }
static void check_lostfound(o2fsck_state *ost) { char name[] = "lost+found"; int namelen = sizeof(name) - 1; uint64_t blkno; errcode_t ret; ret = ocfs2_lookup(ost->ost_fs, ost->ost_fs->fs_root_blkno, name, namelen, NULL, &ost->ost_lostfound_ino); if (ret == 0) return; if (!prompt(ost, PY, PR_LOSTFOUND_MISSING, "/lost+found does not exist. Create it so " "that we can possibly fill it with orphaned inodes?")) return; ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR); if (ret) { com_err(whoami, ret, "while trying to allocate a new inode " "for /lost+found"); return; } ret = ocfs2_init_dir(ost->ost_fs, blkno, ost->ost_fs->fs_root_blkno); if (ret) { com_err(whoami, ret, "while trying to expand a new " "/lost+found directory"); goto out; } ret = ocfs2_link(ost->ost_fs, ost->ost_fs->fs_root_blkno, name, blkno, OCFS2_FT_DIR); if (ret) { com_err(whoami, ret, "while linking inode %"PRIu64" as " "/lost+found", blkno); goto out; } /* XXX maybe this should be a helper to clean up the dir tracking * for any new dir. "2" for both the l+f dirent pointing to the * inode and the "." dirent in its dirblock */ o2fsck_icount_set(ost->ost_icount_in_inodes, blkno, 2); o2fsck_icount_set(ost->ost_icount_refs, blkno, 2); ret = o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, ost->ost_fs->fs_root_blkno, ost->ost_fs->fs_root_blkno, 0); if (ret) { com_err(whoami, ret, "while recording a new /lost+found " "directory"); goto out; } /* we've already iterated through the dirblocks in pass2 so there * is no need to register l+f's new dir block */ ost->ost_lostfound_ino = blkno; blkno = 0; out: if (blkno) { ret = ocfs2_delete_inode(ost->ost_fs, blkno); if (ret) { com_err(whoami, ret, "while trying to clean up an " "an allocated inode after linking /lost+found " "failed"); } } }