コード例 #1
0
ファイル: gfs_pio_global.c プロジェクト: krichter722/gfarm
static char *
gfs_pio_view_global_fsync(GFS_File gf, int operation)
{
	struct gfs_file_global_context *gc = gf->view_context;
	char *e = NULL;
	int i;

	for (i = 0; i < gf->pi.status.st_nsections; i++) {
		e = gfs_pio_view_global_move_to(gf, i);
		if (e != NULL)
			return (e);

		switch (operation) {
		case GFS_PROTO_FSYNC_WITHOUT_METADATA:
			e = gfs_pio_datasync(gc->fragment_gf);
			break;
		case GFS_PROTO_FSYNC_WITH_METADATA:
			e = gfs_pio_sync(gc->fragment_gf);
			break;
		default:	
			e = GFARM_ERR_INVALID_ARGUMENT;
			break;
		}	
		if (e != NULL)
			return (e);
	}
	return (e);
}
コード例 #2
0
ファイル: gfs_pio_global.c プロジェクト: eterps/pwrake
static gfarm_error_t
gfs_pio_view_global_ftruncate(GFS_File gf, gfarm_off_t length)
{
	struct gfs_file_global_context *gc = gf->view_context;
	gfarm_error_t e;
	int i, fragment, nsections;
	gfarm_off_t section_length;
	struct gfarm_file_section_info *sections;
	char section_string[GFARM_INT32STRLEN + 1];

	if (length < 0)
		return (GFARM_ERR_INVALID_ARGUMENT);
	if (length >= gc->offsets[gf->pi.status.st_nsections - 1])
		fragment = gf->pi.status.st_nsections - 1;
	else
		fragment = gfs_pio_view_global_bsearch(
		    length, gc->offsets, gf->pi.status.st_nsections - 1);

	section_length = length - gc->offsets[fragment];

	e = gfs_pio_view_global_move_to(gf, fragment);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	e = gfs_pio_truncate(gc->fragment_gf, section_length);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	/*
	 * Before updating path_info, try to update most recent information,
	 * because the file mode may be updated by e.g. gfs_chmod().
	 */
	if (gfarm_path_info_get(gf->pi.pathname, &pi) == NULL) {
		gfarm_path_info_free(&gf->pi);
		gf->pi = pi;
	}

#if 0 /* We don't store file size in gfarm_path_info, this is just ignored */
	gf->pi.status.st_size = length;
#endif
	gf->pi.status.st_nsections = fragment + 1;
	e = gfarm_path_info_replace(gf->pi.pathname, &gf->pi);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	
	e = gfarm_file_section_info_get_sorted_all_serial_by_file(
		gf->pi.pathname, &nsections, &sections);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	sections[fragment].filesize = section_length;
	sprintf(section_string, "%d", fragment);
	e = gfarm_file_section_info_replace(gf->pi.pathname, section_string,
					    &sections[fragment]);
	for (i = fragment + 1; i < nsections; i++)
		(void)gfs_unlink_section_internal(gf->pi.pathname,
						  sections[i].section);
	gfarm_file_section_info_free_all(nsections, sections);
	
	return (e);
}
コード例 #3
0
ファイル: gfs_pio_global.c プロジェクト: krichter722/gfarm
static char *
gfs_pio_view_global_ftruncate(GFS_File gf, file_offset_t length)
{
	struct gfs_file_global_context *gc = gf->view_context;
	char *e;
	int i, fragment, nsections;
	file_offset_t section_length;
	struct gfarm_file_section_info *sections;
	char section_string[GFARM_INT32STRLEN + 1];

	if (length < 0)
		return (GFARM_ERR_INVALID_ARGUMENT);
	if (length >= gc->offsets[gf->pi.status.st_nsections - 1])
		fragment = gf->pi.status.st_nsections - 1;
	else
		fragment = gfs_pio_view_global_bsearch(
		    length, gc->offsets, gf->pi.status.st_nsections - 1);

	section_length = length - gc->offsets[fragment];

	e = gfs_pio_view_global_move_to(gf, fragment);
	if (e != NULL)
		return (e);
	e = gfs_pio_truncate(gc->fragment_gf, section_length);
	if (e != NULL)
		return (e);

	gf->pi.status.st_size = length;
	gf->pi.status.st_nsections = fragment + 1;
	e = gfarm_path_info_replace(gf->pi.pathname, &gf->pi);
	if (e != NULL)
		return (e);
	
	e = gfarm_file_section_info_get_sorted_all_serial_by_file(
		gf->pi.pathname, &nsections, &sections);
	if (e != NULL)
		return (e);
	sections[fragment].filesize = section_length;
	sprintf(section_string, "%d", fragment);
	e = gfarm_file_section_info_replace(gf->pi.pathname, section_string,
					    &sections[fragment]);
	for (i = fragment + 1; i < nsections; i++)
		(void)gfs_unlink_section_internal(gf->pi.pathname,
						  sections[i].section);
	gfarm_file_section_info_free_all(nsections, sections);
	
	return (e);
}
コード例 #4
0
ファイル: gfs_pio_global.c プロジェクト: krichter722/gfarm
static char *
gfs_pio_view_global_seek(GFS_File gf, file_offset_t offset, int whence,
			  file_offset_t *resultp)
{
	struct gfs_file_global_context *gc = gf->view_context;
	char *e;
	int fragment;

	switch (whence) {
	case SEEK_SET:
		break;
	case SEEK_CUR:
		offset += gf->io_offset + gf->p;
		break;
	case SEEK_END:
		offset += gc->offsets[gf->pi.status.st_nsections];
		break;
	}

	if (gc->offsets[gc->fragment_index] <= offset &&
	    offset <= gc->offsets[gc->fragment_index + 1]) {
		/* same file fragment */
		if (offset == gf->io_offset)
			return (NULL);
	} else {
		if (offset < 0)
			return (GFARM_ERR_INVALID_ARGUMENT);
		if (offset >= gc->offsets[gf->pi.status.st_nsections - 1])
			fragment  = gf->pi.status.st_nsections - 1;
		else
			fragment = gfs_pio_view_global_bsearch(
			    offset, gc->offsets, gf->pi.status.st_nsections-1);

		e = gfs_pio_view_global_move_to(gf, fragment);
		if (e != NULL)
			return (e);
	}
	offset -= gc->offsets[gc->fragment_index];
	e = gfs_pio_seek(gc->fragment_gf, offset, SEEK_SET, &offset);
	if (e != NULL)
		return (e);
	if (resultp != NULL)
		*resultp = gc->offsets[gc->fragment_index] + offset;
	return (NULL);
}
コード例 #5
0
ファイル: gfs_pio_global.c プロジェクト: krichter722/gfarm
static char *
gfs_pio_view_global_adjust(GFS_File gf, const char *buffer, size_t *sizep)
{
	struct gfs_file_global_context *gc = gf->view_context;
	size_t size = *sizep;
	char *e = NULL;

	while (gc->fragment_index < gf->pi.status.st_nsections - 1 &&
	    gf->io_offset >= gc->offsets[gc->fragment_index + 1]) {
		e = gfs_pio_view_global_move_to(gf, gc->fragment_index + 1);
		if (e != NULL)
			return (e);
	}
	if (gc->fragment_index < gf->pi.status.st_nsections - 1 &&
	    gf->io_offset + size > gc->offsets[gc->fragment_index + 1])
		size = gc->offsets[gc->fragment_index + 1] - gf->io_offset;

	*sizep = size;
	return (e);
}
コード例 #6
0
ファイル: gfs_pio_global.c プロジェクト: krichter722/gfarm
char *
gfs_pio_set_view_global(GFS_File gf, int flags)
{
	struct gfs_file_global_context *gc;
	char *e, *arch;
	int i, n;
	struct gfarm_file_section_info *infos;
	static char gfarm_url_prefix[] = "gfarm:/";

	e = gfs_pio_set_view_default(gf);
	if (e != NULL)
		return (e);

	if (GFS_FILE_IS_PROGRAM(gf)) {
		e = gfarm_host_get_self_architecture(&arch);
		if (e != NULL)
			return (gf->error = e);
		return (gfs_pio_set_view_section(gf, arch, NULL, flags));
	}

	if ((gf->mode & GFS_FILE_MODE_FILE_CREATED) != 0)
		return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags));

	if (gf->open_flags & GFARM_FILE_TRUNC) {
		int nsections;
		struct gfarm_file_section_info *sections;

		/* XXX this may not be OK, if a parallel process does this */
		/* remove all sections except section "0" */
		e = gfarm_file_section_info_get_all_by_file(gf->pi.pathname,
		    &nsections, &sections);
		if (e != NULL)
			return (e);
		for (i = 0; i < nsections; i++) {
			if (strcmp(sections[i].section, "0") == 0)
				continue;
			(void)gfs_unlink_section_internal(gf->pi.pathname,
			    sections[i].section);
		}
		gfarm_file_section_info_free_all(nsections, sections);

		gf->pi.status.st_nsections = 1;
		return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags));
	}

	/* XXX - GFARM_FILE_APPEND is not supported */
	if (gf->open_flags & GFARM_FILE_APPEND) {
		gf->error = GFARM_ERR_OPERATION_NOT_SUPPORTED;
		return (gf->error);
	}

	gc = malloc(sizeof(struct gfs_file_global_context));
	if (gc == NULL) {
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	e = gfarm_file_section_info_get_sorted_all_serial_by_file(
		gf->pi.pathname, &n, &infos);
	if (e != NULL) {
		free(gc);
		gf->error = e;
		return (e);
	}

	if (n != gf->pi.status.st_nsections) {
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = "metainfo inconsitency, fragment number mismatch";
		return (gf->error);
	}

	gc->offsets = malloc(sizeof(file_offset_t) * (n + 1));
	gc->url = malloc(sizeof(gfarm_url_prefix) + strlen(gf->pi.pathname));
	if (gc->offsets == NULL || gc->url == NULL) {
		if (gc->offsets != NULL)
			free(gc->offsets);
		if (gc->url != NULL)
			free(gc->url);
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	gc->offsets[0] = 0;
	for (i = 0; i < n; i++)
		gc->offsets[i + 1] = gc->offsets[i] + infos[i].filesize;
	gfarm_file_section_info_free_all(n, infos);

	sprintf(gc->url, "%s%s", gfarm_url_prefix, gf->pi.pathname);

	gf->view_context = gc;
	gf->view_flags = flags;
	gc->fragment_gf = NULL;
	e = gfs_pio_view_global_move_to(gf, 0);
	if (e != NULL) {
		free(gc->url);
		free(gc->offsets);
		free(gc);
		gf->view_context = NULL;
		gfs_pio_set_view_default(gf);
		gf->error = e;
		return (e);
	}

	gf->ops = &gfs_pio_view_global_ops;
	gf->p = gf->length = 0;
	gf->io_offset = gf->offset = 0;
	gf->error = NULL;
	return (NULL);
}
コード例 #7
0
ファイル: gfs_pio_global.c プロジェクト: krichter722/gfarm
char *
gfs_pio_set_view_global(GFS_File gf, int flags)
{
	struct gfs_file_global_context *gc;
	char *e;
	int i, n;
	struct gfarm_file_section_info *infos;
	static char gfarm_url_prefix[] = "gfarm:/";

	e = gfs_pio_set_view_default(gf);
	if (e != NULL)
		return (e);

	if (GFS_FILE_IS_PROGRAM(gf)) {
		gf->error = GFARM_ERR_OPERATION_NOT_PERMITTED;
		return (gf->error);
	}

	if ((gf->open_flags & GFARM_FILE_CREATE) != 0)
		return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags));

	gc = malloc(sizeof(struct gfs_file_global_context));
	if (gc == NULL) {
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	e = gfarm_file_section_info_get_all_by_file(gf->pi.pathname,
	    &n, &infos);
	if (e != NULL) {
		free(gc);
		gf->error = e;
		return (e);
	}

	if (n != gf->pi.status.st_nsections) {
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = "metainfo inconsitency, fragment number mismatch";
		return (gf->error);
	}

	gc->offsets = malloc(sizeof(file_offset_t) * (n + 1));
	gc->url = malloc(sizeof(gfarm_url_prefix) + strlen(gf->pi.pathname));
	if (gc->offsets == NULL || gc->url == NULL) {
		if (gc->offsets != NULL)
			free(gc->offsets);
		if (gc->url != NULL)
			free(gc->url);
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	gc->offsets[0] = 0;
	for (i = 0; i < n; i++)
		gc->offsets[i + 1] = gc->offsets[i] + infos[i].filesize;
	gfarm_file_section_info_free_all(n, infos);

	sprintf(gc->url, "%s%s", gfarm_url_prefix, gf->pi.pathname);

	gf->view_context = gc;
	gf->view_flags = flags;
	gc->fragment_gf = NULL;
	e = gfs_pio_view_global_move_to(gf, 0);
	if (e != NULL) {
		free(gc->url);
		free(gc->offsets);
		free(gc);
		gf->view_context = NULL;
		gfs_pio_set_view_default(gf);
		gf->error = e;
		return (e);
	}

	gf->ops = &gfs_pio_view_global_ops;
	gf->p = gf->length = 0;
	gf->io_offset = gf->offset = 0;
	gf->error = NULL;
	return (NULL);
}