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, §ions); 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, §ions[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); }
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, §ions); 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, §ions[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); }
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); }