static char * gfs_dircache_modify_parent(const char *pathname) { char *e = NULL; char *parent = strdup(pathname), *b; struct gfarm_path_info pi; struct timeval now; if (parent == NULL) return (GFARM_ERR_NO_MEMORY); /* create parent directory canonic path */ for (b = (char *)gfarm_path_dir_skip(parent); b > parent && b[-1] == '/'; --b) ; *b = '\0'; /* NOTE: We don't have path_info for the root directory */ if (b > parent && (e = gfarm_metadb_path_info_get(parent, &pi)) == NULL) { gettimeofday(&now, NULL); pi.status.st_mtimespec.tv_sec = now.tv_sec; pi.status.st_mtimespec.tv_nsec = now.tv_usec * GFARM_MILLISEC_BY_MICROSEC; /* the following calls gfs_dircache_enter_path() internally */ e = gfarm_path_info_replace(parent, &pi); gfarm_path_info_free(&pi); } free(parent); return (e); }
static char * change_path_info_mode(struct gfarm_path_info *p, gfarm_mode_t mode) { p->status.st_mode &= ~GFARM_S_ALLPERM; p->status.st_mode |= (mode & GFARM_S_ALLPERM); return (gfarm_path_info_replace(p->pathname, p)); }
char * gfs_utimes(const char *gfarm_url, const struct gfarm_timespec *tsp) { char *e, *gfarm_file; struct gfarm_path_info pi; struct timeval now; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); e = gfarm_path_info_get(gfarm_file, &pi); free(gfarm_file); if (e != NULL) return (e); e = gfarm_path_info_access(&pi, GFS_W_OK); if (e != NULL) return (e); gettimeofday(&now, NULL); if (tsp == NULL) { pi.status.st_atimespec.tv_sec = pi.status.st_mtimespec.tv_sec = now.tv_sec; pi.status.st_atimespec.tv_nsec = pi.status.st_mtimespec.tv_nsec = now.tv_usec * 1000; } else { pi.status.st_atimespec = tsp[0]; pi.status.st_mtimespec = tsp[1]; } pi.status.st_ctimespec.tv_sec = now.tv_sec; pi.status.st_ctimespec.tv_nsec = now.tv_usec * 1000; e = gfarm_path_info_replace(pi.pathname, &pi); gfarm_path_info_free(&pi); return (e); }
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); }
/* XXX this must be done only if the file was really read or written */ static char * gfs_pio_update_times(GFS_File gf) { struct timeval now; gettimeofday(&now, NULL); if (gf->mode & GFS_FILE_MODE_WRITE) { gf->pi.status.st_mtimespec.tv_sec = now.tv_sec; gf->pi.status.st_mtimespec.tv_nsec = now.tv_usec * 1000; } if (gf->mode & GFS_FILE_MODE_READ) { gf->pi.status.st_atimespec.tv_sec = now.tv_sec; gf->pi.status.st_atimespec.tv_nsec = now.tv_usec * 1000; } return (gfarm_path_info_replace(gf->pi.pathname, &gf->pi)); }