Skip to content

Instantly share code, notes, and snippets.

@craigds
Created March 16, 2011 22:16
Show Gist options
  • Save craigds/873438 to your computer and use it in GitHub Desktop.
Save craigds/873438 to your computer and use it in GitHub Desktop.
backport gdal [20189] to 1.7.3. ticket: http://trac.osgeo.org/gdal/ticket/3708
Index: gdal/apps/gdal_translate.cpp
===================================================================
--- gdal/apps/gdal_translate.cpp (revision 21963)
+++ gdal/apps/gdal_translate.cpp (working copy)
@@ -991,7 +991,14 @@
pfnProgress, NULL );
if( hOutDS != NULL )
{
+ int bHasGotErr = FALSE;
+ CPLErrorReset();
+ GDALFlushCache( hOutDS );
+ if (CPLGetLastErrorType() != CE_None)
+ bHasGotErr = TRUE;
GDALClose( hOutDS );
+ if (bHasGotErr)
+ hOutDS = NULL;
}
GDALClose( (GDALDatasetH) poVDS );
Index: gdal/apps/gdalwarp.cpp
===================================================================
--- gdal/apps/gdalwarp.cpp (revision 21963)
+++ gdal/apps/gdalwarp.cpp (working copy)
@@ -283,6 +283,7 @@
char *pszCutlineDSName = NULL;
char *pszCLayer = NULL, *pszCWHERE = NULL, *pszCSQL = NULL;
void *hCutline = NULL;
+ int bHasGotErr = FALSE;
/* Check that we are running against at least GDAL 1.6 */
/* Note to developers : if we use newer API, please change the requirement */
@@ -1023,14 +1024,17 @@
if( oWO.Initialize( psWO ) == CE_None )
{
+ CPLErr eErr;
if( bMulti )
- oWO.ChunkAndWarpMulti( 0, 0,
+ eErr = oWO.ChunkAndWarpMulti( 0, 0,
GDALGetRasterXSize( hDstDS ),
GDALGetRasterYSize( hDstDS ) );
else
- oWO.ChunkAndWarpImage( 0, 0,
+ eErr = oWO.ChunkAndWarpImage( 0, 0,
GDALGetRasterXSize( hDstDS ),
GDALGetRasterYSize( hDstDS ) );
+ if (eErr != CE_None)
+ bHasGotErr = TRUE;
}
/* -------------------------------------------------------------------- */
@@ -1050,6 +1054,10 @@
/* -------------------------------------------------------------------- */
/* Final Cleanup. */
/* -------------------------------------------------------------------- */
+ CPLErrorReset();
+ GDALFlushCache( hDstDS );
+ if( CPLGetLastErrorType() != CE_None )
+ bHasGotErr = TRUE;
GDALClose( hDstDS );
CPLFree( pszDstFilename );
@@ -1068,7 +1076,7 @@
OGRCleanupAll();
#endif
- return 0;
+ return (bHasGotErr) ? 1 : 0;
}
/************************************************************************/
Index: gdal/frmts/gtiff/geotiff.cpp
===================================================================
--- gdal/frmts/gtiff/geotiff.cpp (revision 21963)
+++ gdal/frmts/gtiff/geotiff.cpp (working copy)
@@ -115,6 +115,7 @@
CPLErr LoadBlockBuf( int nBlockId, int bReadFromDisk = TRUE );
CPLErr FlushBlockBuf();
+ int bWriteErrorInFlushBlockBuf;
char *pszProjection;
int bLookedForProjection;
@@ -751,6 +752,14 @@
int nBlockId;
CPLErr eErr = CE_None;
+ if (poGDS->bWriteErrorInFlushBlockBuf)
+ {
+ /* Report as an error if a previously loaded block couldn't be */
+ /* written correctly */
+ poGDS->bWriteErrorInFlushBlockBuf = FALSE;
+ return CE_Failure;
+ }
+
if (!poGDS->SetDirectory())
return CE_Failure;
@@ -1632,6 +1641,14 @@
int nBlockId;
CPLErr eErr = CE_None;
+ if (poGDS->bWriteErrorInFlushBlockBuf)
+ {
+ /* Report as an error if a previously loaded block couldn't be */
+ /* written correctly */
+ poGDS->bWriteErrorInFlushBlockBuf = FALSE;
+ return CE_Failure;
+ }
+
if (!poGDS->SetDirectory())
return CE_Failure;
@@ -2351,6 +2368,7 @@
nLoadedBlock = -1;
bLoadedBlockDirty = FALSE;
pabyBlockBuf = NULL;
+ bWriteErrorInFlushBlockBuf = FALSE;
hTIFF = NULL;
bNeedsRewrite = FALSE;
bMetadataChanged = FALSE;
@@ -2660,6 +2678,7 @@
{
CPLError( CE_Failure, CPLE_AppDefined,
"WriteEncodedTile/Strip() failed." );
+ bWriteErrorInFlushBlockBuf = TRUE;
}
return eErr;
Index: gdal/gcore/gdalrasterblock.cpp
===================================================================
--- gdal/gcore/gdalrasterblock.cpp (revision 21963)
+++ gdal/gcore/gdalrasterblock.cpp (working copy)
@@ -217,7 +217,12 @@
poBand = poTarget->GetBand();
}
- poBand->FlushBlock( nXOff, nYOff );
+ CPLErr eErr = poBand->FlushBlock( nXOff, nYOff );
+ if (eErr != CE_None)
+ {
+ /* Save the error for later reporting */
+ poBand->SetFlushBlockErr(eErr);
+ }
return TRUE;
}
Index: gdal/gcore/GNUmakefile
===================================================================
--- gdal/gcore/GNUmakefile (revision 21963)
+++ gdal/gcore/GNUmakefile (working copy)
@@ -21,7 +21,7 @@
default: $(OBJ:.o=.$(OBJ_EXT))
clean:
- $(RM) *.o
+ $(RM) *.o $(O_OBJ)
docs:
(cd ..; $(MAKE) docs)
Index: gdal/gcore/gdal_priv.h
===================================================================
--- gdal/gcore/gdal_priv.h (revision 21963)
+++ gdal/gcore/gdal_priv.h (working copy)
@@ -401,6 +401,13 @@
class CPL_DLL GDALRasterBand : public GDALMajorObject
{
+ private:
+ CPLErr eFlushBlockErr;
+
+ void SetFlushBlockErr( CPLErr eErr );
+
+ friend class GDALRasterBlock;
+
protected:
GDALDataset *poDS;
int nBand; /* 1 based */
@@ -430,7 +437,6 @@
int nMaskFlags;
friend class GDALDataset;
- friend class GDALRasterBlock;
friend class GDALProxyRasterBand;
protected:
Index: gdal/gcore/gdalrasterband.cpp
===================================================================
--- gdal/gcore/gdalrasterband.cpp (revision 21963)
+++ gdal/gcore/gdalrasterband.cpp (working copy)
@@ -78,6 +78,8 @@
nBlockReads = 0;
bForceCachedIO = CSLTestBoolean(
CPLGetConfigOption( "GDAL_FORCE_CACHING", "NO") );
+
+ eFlushBlockErr = CE_None;
}
/************************************************************************/
@@ -212,6 +214,15 @@
return CE_None;
}
+ if( eRWFlag == GF_Write && eFlushBlockErr != CE_None )
+ {
+ CPLError(eFlushBlockErr, CPLE_AppDefined,
+ "An error occured while writing a dirty block");
+ CPLErr eErr = eFlushBlockErr;
+ eFlushBlockErr = CE_None;
+ return eErr;
+ }
+
/* -------------------------------------------------------------------- */
/* If pixel and line spaceing are defaulted assign reasonable */
/* value assuming a packed buffer. */
@@ -522,6 +533,15 @@
return( CE_Failure );
}
+ if( eFlushBlockErr != CE_None )
+ {
+ CPLError(eFlushBlockErr, CPLE_AppDefined,
+ "An error occured while writing a dirty block");
+ CPLErr eErr = eFlushBlockErr;
+ eFlushBlockErr = CE_None;
+ return eErr;
+ }
+
/* -------------------------------------------------------------------- */
/* Invoke underlying implementation method. */
/* -------------------------------------------------------------------- */
@@ -873,8 +893,16 @@
CPLErr GDALRasterBand::FlushCache()
{
+ CPLErr eGlobalErr = eFlushBlockErr;
+ if (eFlushBlockErr != CE_None)
+ {
+ CPLError(eFlushBlockErr, CPLE_AppDefined,
+ "An error occured while writing a dirty block");
+ eFlushBlockErr = CE_None;
+ }
+
if (papoBlocks == NULL)
- return CE_None;
+ return eGlobalErr;
/* -------------------------------------------------------------------- */
/* Flush all blocks in memory ... this case is without subblocking.*/
@@ -4811,3 +4839,24 @@
}
return NULL;
}
+
+/************************************************************************/
+/* SetFlushBlockErr() */
+/************************************************************************/
+
+/**
+ * \brief Store that an error occured while writing a dirty block.
+ *
+ * This function stores the fact that an error occured while writing a dirty
+ * block from GDALRasterBlock::FlushCacheBlock(). Indeed when dirty blocks are
+ * flushed when the block cache get full, it is not convenient/possible to
+ * report that a dirty block could not be written correctly. This function
+ * remembers the error and re-issue it from GDALRasterBand::FlushCache(),
+ * GDALRasterBand::WriteBlock() and GDALRasterBand::RasterIO(), which are
+ * places where the user can easily match the error with the relevant dataset.
+ */
+
+void GDALRasterBand::SetFlushBlockErr( CPLErr eErr )
+{
+ eFlushBlockErr = eErr;
+}
Index: gdal/alg/gdalwarpoperation.cpp
===================================================================
--- gdal/alg/gdalwarpoperation.cpp (revision 21963)
+++ gdal/alg/gdalwarpoperation.cpp (working copy)
@@ -1264,10 +1264,16 @@
psOptions->nBandCount,
psOptions->panDstBands,
0, 0, 0 );
- if( CSLFetchBoolean( psOptions->papszWarpOptions, "WRITE_FLUSH",
+ if( eErr == CE_None &&
+ CSLFetchBoolean( psOptions->papszWarpOptions, "WRITE_FLUSH",
FALSE ) )
{
+ CPLErr eOldErr = CPLGetLastErrorType();
+ CPLString osLastErrMsg = CPLGetLastErrorMsg();
GDALFlushCache( psOptions->hDstDS );
+ CPLErr eNewErr = CPLGetLastErrorType();
+ if (eNewErr != eOldErr || osLastErrMsg.compare(CPLGetLastErrorMsg()) != 0)
+ eErr = CE_Failure;
}
ReportTiming( "Output buffer write" );
}
Index: gdal/alg/GNUmakefile
===================================================================
--- gdal/alg/GNUmakefile (revision 21963)
+++ gdal/alg/GNUmakefile (working copy)
@@ -21,7 +21,7 @@
default: $(OBJ:.o=.$(OBJ_EXT))
clean:
- $(RM) *.o
+ $(RM) *.o $(O_OBJ)
docs:
(cd ..; $(MAKE) docs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment