int ocfs2_init_slot_info(struct ocfs2_super *osb) { int status; struct inode *inode = NULL; struct ocfs2_slot_info *si; si = kzalloc(sizeof(struct ocfs2_slot_info) + (sizeof(struct ocfs2_slot) * osb->max_slots), GFP_KERNEL); if (!si) { status = -ENOMEM; mlog_errno(status); return status; } si->si_extended = ocfs2_uses_extended_slot_map(osb); si->si_num_slots = osb->max_slots; si->si_slots = (struct ocfs2_slot *)((char *)si + sizeof(struct ocfs2_slot_info)); inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE, OCFS2_INVALID_SLOT); if (!inode) { status = -EINVAL; mlog_errno(status); goto bail; } si->si_inode = inode; status = ocfs2_map_slot_buffers(osb, si); if (status < 0) { mlog_errno(status); goto bail; } osb->slot_info = (struct ocfs2_slot_info *)si; bail: if (status < 0) __ocfs2_free_slot_info(si); return status; }
/* * Calculate how many bytes are needed by the slot map. Returns * an error if the slot map file is too small. */ static int ocfs2_slot_map_physical_size(struct ocfs2_super *osb, struct inode *inode, unsigned long long *bytes) { unsigned long long bytes_needed; if (ocfs2_uses_extended_slot_map(osb)) { bytes_needed = osb->max_slots * sizeof(struct ocfs2_extended_slot); } else { bytes_needed = osb->max_slots * sizeof(__le16); } if (bytes_needed > i_size_read(inode)) { mlog(ML_ERROR, "Slot map file is too small! (size %llu, needed %llu)\n", i_size_read(inode), bytes_needed); return -ENOSPC; } *bytes = bytes_needed; return 0; }
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; }