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