Exemple #1
0
// 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;
    }
}