BackupPC-XS
view release on metacpan or search on metacpan
bpc_attribCache.c view on Meta::CPAN
bpc_hashtable_nodeDelete(&attr->dir.filesHT, file);
}
static bpc_attribCache_dir *bpc_attribCache_loadPath(bpc_attribCache_info *ac, char *fileName, char *path)
{
char dir[BPC_MAXPATHLEN], attribPath[BPC_MAXPATHLEN];
bpc_attribCache_dir *attr;
int attribPathLen, status;
splitPath(ac, dir, fileName, attribPath, path);
attribPathLen = strlen(attribPath);
if ( BPC_LogLevel >= 9 ) bpc_logMsgf("bpc_attribCache_loadPath: path = %s -> dir = %s, fileName = %s, attribPath = %s\n", path, dir, fileName, attribPath);
attr = bpc_hashtable_find(&ac->attrHT, (uchar*)attribPath, attribPathLen, 1);
if ( !attr || attr->key.key != attribPath ) {
/*
* cache hit - return the existing attributes
*/
if ( attr ) attr->lruCnt = ac->cacheLruCnt++;
return attr;
}
if ( !(attr->key.key = malloc(attribPathLen + 1)) ) {
bpc_logErrf("bpc_attribCache_loadPath: can't allocate %d bytes\n", attribPathLen + 1);
return NULL;
}
strcpy(attr->key.key, attribPath);
bpc_attrib_dirInit(&attr->dir, ac->compress);
attr->dirty = 0;
attr->dirOk = 0;
attr->lruCnt = ac->cacheLruCnt++;
if ( ac->bkupMergeCnt > 0 ) {
int i;
char topDir[2*BPC_MAXPATHLEN], fullAttribPath[2*BPC_MAXPATHLEN];
/*
* Merge multiple attrib files to create the "view" for this backup.
* There are two cases: merging forward for v3, or merging in reverse
* for v4+. bkupMergeList is already in the order we need.
*/
for ( i = 0 ; i < ac->bkupMergeCnt ; i++ ) {
bpc_attrib_dir dir;
ssize_t entrySize;
char *entries, *entry;
snprintf(topDir, sizeof(topDir), "%s/pc/%s/%d", BPC_TopDir, ac->hostName, ac->bkupMergeList[i].num);
snprintf(fullAttribPath, sizeof(fullAttribPath), "%s/%s", topDir, attribPath);
bpc_attrib_dirInit(&dir, ac->bkupMergeList[i].compress);
if ( (status = bpc_attrib_dirRead(&dir, topDir, attribPath, ac->bkupMergeList[i].num)) ) {
if ( ac->bkupMergeList[i].version < 4 ) {
char *p;
int attribDirExists = 1;
STRUCT_STAT st;
if ( (p = strrchr(fullAttribPath, '/')) ) {
*p = '\0';
attribDirExists = !stat(fullAttribPath, &st) && S_ISDIR(st.st_mode);
*p = '/';
}
if ( i == ac->bkupMergeCnt - 1 && !attribDirExists ) {
/*
* For V3, if the last backup doesn't have a directory, then the merged view is empty
*/
bpc_attrib_dirDestroy(&dir);
bpc_attrib_dirDestroy(&attr->dir);
bpc_attrib_dirInit(&attr->dir, ac->compress);
break;
}
if ( !attribDirExists ) {
/*
* nothing to update here - keep going
*/
bpc_attrib_dirDestroy(&dir);
continue;
}
}
bpc_logErrf("bpc_attribCache_loadPath: bpc_attrib_dirRead(%s/%s) returned %d\n", topDir, attribPath, status);
}
if ( bpc_attrib_dirNeedRewrite(&dir) ) {
attr->dirty = 1;
}
entrySize = bpc_attrib_getEntries(&dir, NULL, 0);
if ( (entries = malloc(entrySize + 1)) && bpc_attrib_getEntries(&dir, entries, entrySize) == entrySize ) {
for ( entry = entries ; entry < entries + entrySize ; entry += strlen(entry) + 1 ) {
bpc_attrib_file *file = bpc_attrib_fileGet(&dir, entry, 0);
if ( !file ) continue;
if ( file->type == BPC_FTYPE_DELETED ) {
bpc_attrib_fileDeleteName(&attr->dir, entry);
} else {
bpc_attrib_file *fileDest;
if ( !(fileDest = bpc_attrib_fileGet(&attr->dir, entry, 1)) ) return NULL;
if ( fileDest->key.key == entry ) {
/*
* new entry - initialize
*/
bpc_attrib_fileInit(fileDest, entry, 0);
}
bpc_attrib_fileCopy(fileDest, file);
fileDest->backupNum = ac->bkupMergeList[i].num;
}
}
} else {
bpc_logErrf("bpc_attribCache_loadPath(%s/%s): can't malloc %lu bytes for entries\n",
topDir, attribPath, (unsigned long)entrySize);
if ( entries ) free(entries);
bpc_attrib_dirDestroy(&dir);
return NULL;
}
free(entries);
bpc_attrib_dirDestroy(&dir);
}
} else {
/*
* non-merge case - read the single attrib file
*/
if ( (status = bpc_attrib_dirRead(&attr->dir, ac->backupTopDir, attribPath, ac->backupNum)) ) {
bpc_attribCache.c view on Meta::CPAN
* remove any extraneous BPC_FTYPE_DELETED file types
*/
bpc_hashtable_iterate(&attr->dir.filesHT, (void*)bpc_attribCache_removeDeletedEntries, attr);
}
if ( attr->dirty ) {
if ( BPC_LogLevel >= 8 ) bpc_logMsgf("bpc_attribCache_loadPath: will rewrite path = %s -> dir = %s, fileName = %s, attribPath = %s\n", path, dir, fileName, attribPath);
}
if ( bpc_hashtable_entryCount(&ac->attrHT) > BPC_ATTRIBCACHE_DIR_COUNT_MAX ) {
bpc_attribCache_flush(ac, 0, NULL);
}
return attr;
}
static bpc_attribCache_dir *bpc_attribCache_loadInode(bpc_attribCache_info *ac, char *indexStr, ino_t inode)
{
char attribPath[BPC_MAXPATHLEN], attribDir[BPC_MAXPATHLEN], attribFile[BPC_MAXPATHLEN];
bpc_attribCache_dir *attr;
int attribPathLen, status;
inodePath(ac, indexStr, attribDir, attribFile, inode);
attribPathLen = snprintf(attribPath, sizeof(attribPath), "%s/%s", attribDir, attribFile);
attr = bpc_hashtable_find(&ac->inodeHT, (uchar*)attribPath, attribPathLen, 1);
if ( !attr || attr->key.key != attribPath ) {
if ( attr ) attr->lruCnt = ac->cacheLruCnt++;
return attr;
}
/*
* new entry - read the attrib file
*/
if ( !(attr->key.key = malloc(attribPathLen + 1)) ) {
bpc_logErrf("bpc_attribCache_loadInode: can't allocate %d bytes\n", attribPathLen + 1);
return NULL;
}
strcpy(attr->key.key, attribPath);
bpc_attrib_dirInit(&attr->dir, ac->compress);
attr->dirty = 0;
attr->dirOk = 1;
attr->lruCnt = ac->cacheLruCnt++;
if ( ac->bkupMergeCnt > 0 ) {
int i;
char inodeDir[2*BPC_MAXPATHLEN], fullAttribPath[2*BPC_MAXPATHLEN];
/*
* Merge multiple attrib files to create the "view" for this backup.
* There is only one case here, v4, since v3 didn't have inodes.
*/
for ( i = 0 ; i < ac->bkupMergeCnt ; i++ ) {
bpc_attrib_dir dir;
ssize_t entrySize;
char *entries, *entry;
snprintf(inodeDir, sizeof(inodeDir), "%s/pc/%s/%d/%s", BPC_TopDir, ac->hostName, ac->bkupMergeList[i].num, attribDir);
snprintf(fullAttribPath, sizeof(fullAttribPath), "%s/%s", inodeDir, attribFile);
bpc_attrib_dirInit(&dir, ac->bkupMergeList[i].compress);
if ( (status = bpc_attrib_dirRead(&dir, inodeDir, attribFile, ac->bkupMergeList[i].num)) ) {
STRUCT_STAT st;
int attribDirExists = !stat(inodeDir, &st) && S_ISDIR(st.st_mode);
if ( ac->bkupMergeList[i].version < 4 || !attribDirExists ) {
/*
* nothing to update here - keep going
*/
bpc_attrib_dirDestroy(&dir);
continue;
}
bpc_logErrf("bpc_attribCache_loadInode: bpc_attrib_dirRead(%s/%s) returned %d\n", inodeDir, attribFile, status);
}
if ( bpc_attrib_dirNeedRewrite(&dir) ) {
attr->dirty = 1;
}
entrySize = bpc_attrib_getEntries(&dir, NULL, 0);
if ( (entries = malloc(entrySize + 1)) && bpc_attrib_getEntries(&dir, entries, entrySize) == entrySize ) {
for ( entry = entries ; entry < entries + entrySize ; entry += strlen(entry) + 1 ) {
bpc_attrib_file *file = bpc_attrib_fileGet(&dir, entry, 0);
if ( !file ) continue;
if ( file->type == BPC_FTYPE_DELETED ) {
bpc_attrib_fileDeleteName(&attr->dir, entry);
} else {
bpc_attrib_file *fileDest;
if ( !(fileDest = bpc_attrib_fileGet(&attr->dir, entry, 1)) ) return NULL;
if ( fileDest->key.key == entry ) {
/*
* new entry - initialize
*/
bpc_attrib_fileInit(fileDest, entry, 0);
}
bpc_attrib_fileCopy(fileDest, file);
}
}
} else {
bpc_logErrf("bpc_attribCache_loadInode(%s): can't malloc %lu bytes for entries\n",
fullAttribPath, (unsigned long)entrySize);
if ( entries ) free(entries);
bpc_attrib_dirDestroy(&dir);
return NULL;
}
free(entries);
bpc_attrib_dirDestroy(&dir);
}
} else {
/*
* non-merge case - read the single attrib file
*/
char inodeDir[2*BPC_MAXPATHLEN];
snprintf(inodeDir, sizeof(inodeDir), "%s/%s", ac->backupTopDir, attribDir);
if ( (status = bpc_attrib_dirRead(&attr->dir, inodeDir, attribFile, ac->backupNum)) ) {
bpc_logErrf("bpc_attribCache_loadInode: bpc_attrib_dirRead(%s/%s) returned %d\n", inodeDir, attribFile, status);
}
if ( bpc_attrib_dirNeedRewrite(&attr->dir) ) {
attr->dirty = 1;
}
}
if ( attr->dirty ) {
if ( BPC_LogLevel >= 8 ) bpc_logMsgf("bpc_attribCache_loadInode: will rewrite path = %s -> dir = %s, fileName = %s\n", attribPath, attribDir, attribFile);
}
if ( bpc_hashtable_entryCount(&ac->inodeHT) > BPC_ATTRIBCACHE_DIR_COUNT_MAX ) {
( run in 0.547 second using v1.01-cache-2.11-cpan-39bf76dae61 )