Beispiel #1
0
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);
}
Beispiel #2
0
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);
}