// internal pwrite, do a write query with offset on a different descriptor, do not change the position of the current one. ssize_t gridftp_rw_internal_pwrite(GridFTPFactory * factory, GridFTPFileDesc* desc, const void* buffer, size_t s_buff, off_t offset) { // throw Gfal::CoreException gfal_log(GFAL_VERBOSE_TRACE, " -> [GridFTPModule::internal_pwrite]"); GridFTPSessionHandler handler(factory, desc->url); GridFTPRequestState request_state(&handler); GridFTPStreamState stream(&handler); globus_result_t res = globus_ftp_client_partial_put( stream.handler->get_ftp_client_handle(), desc->url.c_str(), stream.handler->get_ftp_client_operationattr(), NULL, offset, offset + s_buff, globus_ftp_client_done_callback, &request_state); gfal_globus_check_result(GFAL_GRIDFTP_SCOPE_INTERNAL_PWRITE, res); ssize_t r_size = gridftp_write_stream(GFAL_GRIDFTP_SCOPE_INTERNAL_PWRITE, &stream, buffer, s_buff, false); // write block request_state.wait(GFAL_GRIDFTP_SCOPE_INTERNAL_PWRITE); gfal_log(GFAL_VERBOSE_TRACE, "[GridFTPModule::internal_pwrite] <-"); return r_size; }
void ADIOI_GRIDFTP_WriteDiscontig(ADIO_File fd, void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Status *status, int *error_code) { char myname[]="ADIOI_GRIDFTP_WriteDiscontig"; int myrank,nprocs; MPI_Aint btype_size,btype_extent; MPI_Aint ftype_size,ftype_extent; MPI_Aint etype_size; MPI_Aint extent; ADIOI_Flatlist_node *flat_file; int buf_contig,boff,i,nblks; globus_off_t start,end,goff; globus_size_t bytes_written; globus_result_t result; MPI_Comm_rank(fd->comm,&myrank); MPI_Comm_size(fd->comm,&nprocs); etype_size=fd->etype_size; MPI_Type_size(fd->filetype,&ftype_size); MPI_Type_extent(fd->filetype,&ftype_extent); /* This is arguably unnecessary, as this routine assumes that the buffer in memory is contiguous */ MPI_Type_size(datatype,&btype_size); MPI_Type_extent(datatype,&btype_extent); ADIOI_Datatype_iscontig(datatype,&buf_contig); if ( ( btype_extent!=btype_size ) || ( ! buf_contig ) ) { FPRINTF(stderr,"[%d/%d] %s called with discontigous memory buffer\n", myrank,nprocs,myname); fflush(stderr); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(globus_error_get(result))); return; } /* from here we can assume btype_extent==btype_size */ /* Flatten out fd->filetype so we know which blocks to skip */ ADIOI_Flatten_datatype(fd->filetype); flat_file = ADIOI_Flatlist; while (flat_file->type != fd->filetype && flat_file->next!=NULL) flat_file = flat_file->next; /* Figure out how big the area to write is */ /* ASSUMPTION: ftype_size is an integer multiple of btype_size or vice versa. */ start=(globus_off_t)(offset*etype_size); goff=start; boff=0; extent=0; nblks=0; while ( boff < (count*btype_size) ) { int blklen; for (i=0;i<flat_file->count;i++) { if ( (boff+flat_file->blocklens[i]) < (count*btype_size) ) blklen=flat_file->blocklens[i]; else blklen=(count*btype_size)-boff; boff+=blklen; extent=MAX(extent,nblks*ftype_extent+flat_file->indices[i]+blklen); if ( boff>=(count*btype_size) ) break; } nblks++; } if ( extent < count*btype_size ) { FPRINTF(stderr,"[%d/%d] %s error in computing extent -- extent %d is smaller than total bytes requested %d!\n", myrank,nprocs,myname,extent,count*btype_size); fflush(stderr); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(globus_error_get(result))); return; } end=start+(globus_off_t)extent; FPRINTF(stderr,"[%d/%d] %s writing %d bytes into extent of %d bytes starting at offset %Ld\n", myrank,nprocs,myname,count*btype_size,extent,(long long)start); fflush(stderr); /* start up the globus partial write */ globus_mutex_init(&writediscontig_ctl_lock, GLOBUS_NULL); globus_cond_init(&writediscontig_ctl_cond, GLOBUS_NULL); writediscontig_ctl_done=GLOBUS_FALSE; if ( (result=globus_ftp_client_partial_put(&(gridftp_fh[fd->fd_sys]), fd->filename, &(oattr[fd->fd_sys]), GLOBUS_NULL, start, end, writediscontig_ctl_cb, GLOBUS_NULL))!=GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_partial_get",myname,result); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(globus_error_get(result))); return; } /* Do all the actual I/Os */ boff=0; nblks=0; while ( boff < (count*btype_size) ) { int i,blklen; for (i=0;i<flat_file->count;i++) { if ( (boff+flat_file->blocklens[i]) < (count*btype_size) ) blklen=flat_file->blocklens[i]; else blklen=(count*btype_size)-boff; if ( blklen > 0 ) { goff=start+nblks*ftype_extent+((globus_off_t)flat_file->indices[i]); /* FPRINTF(stderr,"[%d/%d] %s writing %d bytes from boff=%d at goff=%Ld\n",myrank,nprocs,myname,blklen,boff,goff); */ if ( (result=globus_ftp_client_register_write(&(gridftp_fh[fd->fd_sys]), ((globus_byte_t *)buf)+boff, (globus_size_t)blklen, goff, GLOBUS_TRUE, writediscontig_data_cb, (void *)(&bytes_written)))!=GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_register_write",myname,result); *error_code=MPI_ERR_IO; ADIOI_Error(fd,*error_code,myname); return; } boff+=blklen; if ( boff>=(count*btype_size) ) break; } } nblks++; } /* The ctl callback won't start till the data callbacks complete, so it's safe to wait on just the ctl callback */ globus_mutex_lock(&writediscontig_ctl_lock); while ( writediscontig_ctl_done!=GLOBUS_TRUE ) globus_cond_wait(&writediscontig_ctl_cond,&writediscontig_ctl_lock); globus_mutex_unlock(&writediscontig_ctl_lock); globus_mutex_destroy(&writediscontig_ctl_lock); globus_cond_destroy(&writediscontig_ctl_cond); #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, bytes_written); #endif if (file_ptr_type != ADIO_EXPLICIT_OFFSET) { fd->fp_ind += extent; fd->fp_sys_posn = fd->fp_ind; } else { fd->fp_sys_posn = offset + extent; } }
void ADIOI_GRIDFTP_WriteContig(ADIO_File fd, void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Status *status, int *error_code) { char myname[]="ADIOI_GRIDFTP_WriteContig"; int myrank, nprocs, datatype_size; globus_size_t len,bytes_written=0; globus_off_t goff; globus_result_t result; if ( fd->access_mode&ADIO_RDONLY ) { *error_code=MPI_ERR_AMODE; return; } *error_code = MPI_SUCCESS; MPI_Comm_size(fd->comm, &nprocs); MPI_Comm_rank(fd->comm, &myrank); MPI_Type_size(datatype, &datatype_size); if (file_ptr_type != ADIO_EXPLICIT_OFFSET) { offset = fd->fp_ind; } /* Do the gridftp I/O transfer */ goff = (globus_off_t)offset; len = ((globus_size_t)datatype_size)*((globus_size_t)count); globus_mutex_init(&writecontig_ctl_lock, GLOBUS_NULL); globus_cond_init(&writecontig_ctl_cond, GLOBUS_NULL); writecontig_ctl_done=GLOBUS_FALSE; if ( (result=globus_ftp_client_partial_put(&(gridftp_fh[fd->fd_sys]), fd->filename, &(oattr[fd->fd_sys]), GLOBUS_NULL, goff, goff+(globus_off_t)len, writecontig_ctl_cb, GLOBUS_NULL))!=GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_partial_put",myname,result); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(globus_error_get(result))); return; } if ( (result=globus_ftp_client_register_write(&(gridftp_fh[fd->fd_sys]), (globus_byte_t *)buf, len, goff, GLOBUS_TRUE, writecontig_data_cb, (void *)(&bytes_written)))!=GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_register_write",myname,result); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(globus_error_get(result))); return; } /* The ctl callback won't start till the data callbacks complete, so it's safe to wait on just the ctl callback */ globus_mutex_lock(&writecontig_ctl_lock); while ( writecontig_ctl_done!=GLOBUS_TRUE ) globus_cond_wait(&writecontig_ctl_cond,&writecontig_ctl_lock); globus_mutex_unlock(&writecontig_ctl_lock); globus_mutex_destroy(&writecontig_ctl_lock); globus_cond_destroy(&writecontig_ctl_cond); #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, bytes_written); #endif if (file_ptr_type != ADIO_EXPLICIT_OFFSET) { offset = fd->fp_ind; fd->fp_ind += bytes_written; fd->fp_sys_posn = fd->fp_ind; } else { fd->fp_sys_posn = offset + bytes_written; } }