static void create_named_directory(ocfs2_filesys *fs, char *dirname, uint64_t *blkno) { errcode_t ret; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); ret = ocfs2_lookup(fs, sb->s_root_blkno, dirname, strlen(dirname), NULL, blkno); if (!ret) return; else if (ret != OCFS2_ET_FILE_NOT_FOUND) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_new_inode(fs, blkno, S_IFDIR | 0755); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_init_dir(fs, *blkno, fs->fs_root_blkno); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_link(fs, fs->fs_root_blkno, dirname, *blkno, OCFS2_FT_DIR); if (ret) FSWRK_COM_FATAL(progname, ret); return; }
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"); } } }
static errcode_t add_slots(ocfs2_filesys *fs, int num_slots) { errcode_t ret; uint16_t old_num = OCFS2_RAW_SB(fs->fs_super)->s_max_slots; char fname[OCFS2_MAX_FILENAME_LEN]; uint64_t blkno; int i, j, max_slots; int ftype; struct tools_progress *prog = NULL; if (ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super))) { ret = TUNEFS_ET_TOO_MANY_SLOTS_EXTENDED; max_slots = INT16_MAX; } else { ret = TUNEFS_ET_TOO_MANY_SLOTS_OLD; max_slots = OCFS2_MAX_SLOTS; } if (num_slots > max_slots) goto bail; prog = tools_progress_start("Adding slots", "addslots", (NUM_SYSTEM_INODES - OCFS2_LAST_GLOBAL_SYSTEM_INODE - 1) * (num_slots - old_num)); if (!prog) { ret = TUNEFS_ET_NO_MEMORY; goto bail; } ret = 0; for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1; i < NUM_SYSTEM_INODES; ++i) { for (j = old_num; j < num_slots; ++j) { ocfs2_sprintf_system_inode_name(fname, OCFS2_MAX_FILENAME_LEN, i, j); verbosef(VL_APP, "Creating system file \"%s\"\n", fname); /* Goto next if file already exists */ ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno, fname, strlen(fname), NULL, &blkno); if (!ret) { verbosef(VL_APP, "System file \"%s\" already exists\n", fname); tools_progress_step(prog, 1); continue; } /* create inode for system file */ ret = ocfs2_new_system_inode(fs, &blkno, ocfs2_system_inodes[i].si_mode, ocfs2_system_inodes[i].si_iflags); if (ret) { verbosef(VL_APP, "%s while creating inode for " "system file \"%s\"\n", error_message(ret), fname); goto bail; } ftype = (S_ISDIR(ocfs2_system_inodes[i].si_mode) ? OCFS2_FT_DIR : OCFS2_FT_REG_FILE); /* if dir, alloc space to it */ if (ftype == OCFS2_FT_DIR) { ret = ocfs2_init_dir(fs, blkno, fs->fs_sysdir_blkno); if (ret) { verbosef(VL_APP, "%s while initializing " "directory \"%s\"\n", error_message(ret), fname); goto bail; } } /* Add the inode to the system dir */ ret = ocfs2_link(fs, fs->fs_sysdir_blkno, fname, blkno, ftype); if (ret) { verbosef(VL_APP, "%s while linking inode %"PRIu64" " "as \"%s\" in the system " "directory\n", error_message(ret), blkno, fname); goto bail; } verbosef(VL_APP, "System file \"%s\" created\n", fname); tools_progress_step(prog, 1); } } bail: if (prog) tools_progress_stop(prog); return ret; }