if (S_ISBLK(ff_pkt->statp.st_mode))
rsize = (rsize/512) * 512;
#endif
+
+#ifdef HAVE_LIBZ
+ /*
+ * instead of using compress2 for every block (with 256KB alloc + free per block)
+ * we init the zlib once per file which leads to less pagefaults on large files (>64K)
+ */
+
+ z_stream zstream;
+ zstream.zalloc = Z_NULL;
+ zstream.zfree = Z_NULL;
+ zstream.opaque = Z_NULL;
+ zstream.state = Z_NULL;
+
+ BOOL blibzInited = deflateInit(&zstream, ff_pkt->GZIP_level) == Z_OK;
+#endif
/*
* Read the file data
#ifdef HAVE_LIBZ
/* Do compression if turned on */
- if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
+ if (!sparseBlock && (ff_pkt->flags & FO_GZIP) && blibzInited) {
int zstat;
compress_len = max_compress_len;
Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
rbuf, sd->msglen);
- /* NOTE! This call modifies compress_len !!! */
- if ((zstat=compress2((Bytef *)cbuf, &compress_len,
- (const Bytef *)rbuf, (uLong)sd->msglen,
- ff_pkt->GZIP_level)) != Z_OK) {
+
+ zstream.next_in = (Bytef *)rbuf;
+ zstream.avail_in = sd->msglen;
+ zstream.next_out = (Bytef *)cbuf;
+ zstream.avail_out = compress_len;
+
+ if ((zstat=deflate(&zstream, Z_FINISH)) != Z_STREAM_END) {
Jmsg(jcr, M_FATAL, 0, _("Compression error: %d\n"), zstat);
set_jcr_job_status(jcr, JS_ErrorTerminated);
goto err;
}
+ compress_len = zstream.total_out;
+ blibzInited = deflateReset (&zstream) == Z_OK;
+
Dmsg2(400, "compressed len=%d uncompressed len=%d\n",
compress_len, sd->msglen);
if (cipher_ctx) {
crypto_cipher_free(cipher_ctx);
}
+#ifdef HAVE_LIBZ
+ /* Free the zlib stream */
+ deflateEnd(&zstream);
+#endif
return 1;
err:
+ /* Free the cipher context */
if (cipher_ctx) {
crypto_cipher_free(cipher_ctx);
}
+#ifdef HAVE_LIBZ
+ /* Free the zlib stream */
+ deflateEnd(&zstream);
+#endif
+
sd->msg = msgsave; /* restore bnet buffer */
sd->msglen = 0;
return 0;
#define b_errno_win32 (1<<29)
+/* UTF-8 to UCS2 path conversion is expensive,
+ so we cache the conversion. During backup the
+ conversion is called 3 times (lstat, attribs, open),
+ by using the cache this is reduced to 1 time */
+
+POOLMEM* g_pWin32ConvUTF8Cache = get_pool_memory (PM_FNAME);
+POOLMEM* g_pWin32ConvUCS2Cache = get_pool_memory (PM_FNAME);
+static pthread_mutex_t Win32Convmutex = PTHREAD_MUTEX_INITIALIZER;
+
+void Win32ConvCleanupCache()
+{
+ if (g_pWin32ConvUTF8Cache) {
+ free_pool_memory (g_pWin32ConvUTF8Cache);
+ g_pWin32ConvUTF8Cache = NULL;
+ }
+
+ if (g_pWin32ConvUCS2Cache) {
+ free_pool_memory (g_pWin32ConvUCS2Cache);
+ g_pWin32ConvUCS2Cache = NULL;
+ }
+}
+
+
/* to allow the usage of the original version in this file here */
#undef fputs
int
make_win32_path_UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF, BOOL* pBIsRawPath /*= NULL*/)
{
+ P(Win32Convmutex);
+ /* if we find the utf8 string in cache, we use the cached ucs2 version */
+ if (bstrcmp (pszUTF, g_pWin32ConvUTF8Cache)) {
+ int32_t nBufSize = sizeof_pool_memory(g_pWin32ConvUCS2Cache);
+ *pszUCS = check_pool_memory_size(*pszUCS, nBufSize);
+ wcscpy ((LPWSTR) *pszUCS, (LPWSTR) g_pWin32ConvUCS2Cache);
+ V(Win32Convmutex);
+ return nBufSize / sizeof (WCHAR);
+ }
+
/* helper to convert from utf-8 to UCS-2 and to complete a path for 32K path syntax */
int nRet = UTF8_2_wchar(pszUCS, pszUTF);
*pBIsRawPath = FALSE;
#endif
+ /* populate cache */
+ int32_t nBufSize = sizeof_pool_memory(*pszUCS);
+ g_pWin32ConvUCS2Cache = check_pool_memory_size(g_pWin32ConvUCS2Cache, nBufSize);
+ wcscpy ((LPWSTR) g_pWin32ConvUCS2Cache, (LPWSTR) *pszUCS);
+ nBufSize = strlen (pszUTF)+1;
+ g_pWin32ConvUTF8Cache = check_pool_memory_size(g_pWin32ConvUTF8Cache, nBufSize);
+ bstrncpy (g_pWin32ConvUTF8Cache, pszUTF, nBufSize);
+ V(Win32Convmutex);
+
return nRet;
}