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 )