Exemple #1
0
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;
}
Exemple #2
0
/*
 * 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;
}