Skip to content

Commit 3769c28

Browse files
committed
force rewrite of attr file if xattr key fixup was applied
1 parent 8cf0a27 commit 3769c28

3 files changed

Lines changed: 48 additions & 18 deletions

File tree

backuppc/backuppc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ typedef struct {
329329
typedef struct {
330330
bpc_digest digest;
331331
ushort compress;
332+
ushort needRewrite;
332333
/*
333334
* hash table of bpc_attrib_file entries, indexed by file name
334335
*/
@@ -354,12 +355,13 @@ int bpc_attrib_fileCount(bpc_attrib_dir *dir);
354355
char *bpc_attrib_fileType2Text(int type);
355356
void bpc_attrib_dirInit(bpc_attrib_dir *dir, int compressLevel);
356357
void bpc_attrib_dirDestroy(bpc_attrib_dir *dir);
358+
int bpc_attrib_dirNeedRewrite(bpc_attrib_dir *dir);
357359
ssize_t bpc_attrib_getEntries(bpc_attrib_dir *dir, char *entries, ssize_t entrySize);
358360
void bpc_attrib_dirRefCount(bpc_deltaCount_info *deltaInfo, bpc_attrib_dir *dir, int incr);
359361
void bpc_attrib_dirRefCountInodeMax(bpc_deltaCount_info *deltaInfo, bpc_attrib_dir *dir, int incr, unsigned int *inodeMax);
360362
void bpc_attrib_attribFilePath(bpc_strBuf *path, char *dir, char *attribFileName);
361363
bpc_digest *bpc_attrib_dirDigestGet(bpc_attrib_dir *dir);
362-
uchar *bpc_attrib_buf2file(bpc_attrib_file *file, uchar *buf, uchar *bufEnd, int xattrNumEntries);
364+
uchar *bpc_attrib_buf2file(bpc_attrib_file *file, uchar *buf, uchar *bufEnd, int xattrNumEntries, int *xattrFixup);
363365
uchar *bpc_attrib_buf2fileFull(bpc_attrib_file *file, uchar *buf, uchar *bufEnd);
364366
uchar *bpc_attrib_file2buf(bpc_attrib_file *file, uchar *buf, uchar *bufEnd);
365367
int bpc_attrib_digestRead(bpc_attrib_dir *dir, bpc_digest *digest, char *attribPath);

backuppc/bpc_attrib.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ void bpc_attrib_dirInit(bpc_attrib_dir *dir, int compressLevel)
411411
{
412412
dir->digest.len = 0;
413413
dir->compress = compressLevel;
414+
dir->needRewrite = 0;
414415
bpc_hashtable_create(&dir->filesHT, 512, sizeof(bpc_attrib_file));
415416
}
416417

@@ -420,6 +421,11 @@ void bpc_attrib_dirDestroy(bpc_attrib_dir *dir)
420421
bpc_hashtable_destroy(&dir->filesHT);
421422
}
422423

424+
int bpc_attrib_dirNeedRewrite(bpc_attrib_dir *dir)
425+
{
426+
return dir->needRewrite;
427+
}
428+
423429
typedef struct {
424430
bpc_deltaCount_info *deltaInfo;
425431
int incr;
@@ -616,7 +622,7 @@ static void setVarInt(uchar **bufPP, uchar *bufEnd, int64 value)
616622
* If there isn't enough data to extract a complete file structure, the return value
617623
* will be greater than bufEnd. You should gather more data and re-call the function.
618624
*/
619-
uchar *bpc_attrib_buf2file(bpc_attrib_file *file, uchar *buf, uchar *bufEnd, int xattrNumEntries)
625+
uchar *bpc_attrib_buf2file(bpc_attrib_file *file, uchar *buf, uchar *bufEnd, int xattrNumEntries, int *xattrFixup)
620626
{
621627
uchar *bufP = buf;
622628
int i;
@@ -643,6 +649,9 @@ uchar *bpc_attrib_buf2file(bpc_attrib_file *file, uchar *buf, uchar *bufEnd, int
643649
uint valueLen = getVarInt(&bufP, bufEnd);
644650

645651
if ( bufP + keyLen + valueLen <= bufEnd ) {
652+
if ( xattrFixup && bufP[keyLen - 1] != 0x0 ) {
653+
*xattrFixup = 1;
654+
}
646655
bpc_attrib_xattrSetValue(file, bufP, keyLen, bufP + keyLen, valueLen);
647656
}
648657
bufP += keyLen + valueLen;
@@ -672,7 +681,7 @@ uchar *bpc_attrib_buf2fileFull(bpc_attrib_file *file, uchar *bufP, uchar *bufEnd
672681
bpc_attrib_xattrDeleteAll(file);
673682
xattrNumEntries = getVarInt(&bufP, bufEnd);
674683
if ( BPC_LogLevel >= 6 ) bpc_logMsgf("bpc_attrib_buf2fileFull: xattrNumEntries = %d\n", xattrNumEntries);
675-
bufP = bpc_attrib_buf2file(file, bufP, bufEnd, xattrNumEntries);
684+
bufP = bpc_attrib_buf2file(file, bufP, bufEnd, xattrNumEntries, NULL);
676685
return bufP;
677686
}
678687

@@ -895,6 +904,7 @@ int bpc_attrib_dirRead(bpc_attrib_dir *dir, char *dirPath, char *attribFilePath,
895904
char *fileName;
896905
bpc_attrib_file *file;
897906
uchar *bufPsave = bufP;
907+
int xattrFixup = 0;
898908

899909
if ( nRead == sizeof(buf) && bufP > buf + nRead - 2 * BPC_MAXPATHLEN
900910
&& read_more_data(&fd, buf, sizeof(buf), &nRead, &bufP, attribPath->s) ) {
@@ -925,7 +935,7 @@ int bpc_attrib_dirRead(bpc_attrib_dir *dir, char *dirPath, char *attribFilePath,
925935
bpc_attrib_fileInit(file, fileName, xattrNumEntries);
926936
file->backupNum = backupNum;
927937

928-
bufP = bpc_attrib_buf2file(file, bufP, buf + nRead, xattrNumEntries);
938+
bufP = bpc_attrib_buf2file(file, bufP, buf + nRead, xattrNumEntries, &xattrFixup);
929939
if ( bufP > buf + nRead ) {
930940
/*
931941
* Need to get more data and try again. We have allocated file->name,

backuppc/bpc_attribCache.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ static bpc_attribCache_dir *bpc_attribCache_loadPath(bpc_attribCache_info *ac, b
239239
for ( i = 0 ; i < ac->bkupMergeCnt ; i++ ) {
240240
bpc_attrib_dir dir;
241241
ssize_t entrySize;
242-
char *entries, *fileName;
242+
char *entries, *entry;
243243

244244
bpc_strBuf_snprintf(topDir, 0, "%s/pc/%s/%d", BPC_TopDir.s, ac->hostName->s, ac->bkupMergeList[i].num);
245245
bpc_strBuf_snprintf(fullAttribPath, 0, "%s/%s", topDir->s, attribPath->s);
@@ -275,27 +275,30 @@ static bpc_attribCache_dir *bpc_attribCache_loadPath(bpc_attribCache_info *ac, b
275275
}
276276
bpc_logErrf("bpc_attribCache_loadPath: bpc_attrib_dirRead(%s/%s) returned %d\n", topDir->s, attribPath->s, status);
277277
}
278+
if ( bpc_attrib_dirNeedRewrite(&dir) ) {
279+
attr->dirty = 1;
280+
}
278281
entrySize = bpc_attrib_getEntries(&dir, NULL, 0);
279282
if ( (entries = malloc(entrySize + 1)) && bpc_attrib_getEntries(&dir, entries, entrySize) == entrySize ) {
280-
for ( fileName = entries ; fileName < entries + entrySize ; fileName += strlen(fileName) + 1 ) {
281-
bpc_attrib_file *file = bpc_attrib_fileGet(&dir, fileName, 0);
283+
for ( entry = entries ; entry < entries + entrySize ; entry += strlen(entry) + 1 ) {
284+
bpc_attrib_file *file = bpc_attrib_fileGet(&dir, entry, 0);
282285
if ( !file ) continue;
283286
if ( file->type == BPC_FTYPE_DELETED ) {
284-
bpc_attrib_fileDeleteName(&attr->dir, fileName);
287+
bpc_attrib_fileDeleteName(&attr->dir, entry);
285288
} else {
286289
bpc_attrib_file *fileDest;
287290

288-
if ( !(fileDest = bpc_attrib_fileGet(&attr->dir, fileName, 1)) ) {
291+
if ( !(fileDest = bpc_attrib_fileGet(&attr->dir, entry, 1)) ) {
289292
bpc_strBuf_free(attribPath);
290293
bpc_strBuf_free(topDir);
291294
bpc_strBuf_free(fullAttribPath);
292295
return NULL;
293296
}
294-
if ( fileDest->key.key == fileName ) {
297+
if ( fileDest->key.key == entry ) {
295298
/*
296299
* new entry - initialize
297300
*/
298-
bpc_attrib_fileInit(fileDest, fileName, 0);
301+
bpc_attrib_fileInit(fileDest, entry, 0);
299302
}
300303
bpc_attrib_fileCopy(fileDest, file);
301304
fileDest->backupNum = ac->bkupMergeList[i].num;
@@ -323,11 +326,17 @@ static bpc_attribCache_dir *bpc_attribCache_loadPath(bpc_attribCache_info *ac, b
323326
if ( (status = bpc_attrib_dirRead(&attr->dir, ac->backupTopDir->s, attribPath->s, ac->backupNum)) ) {
324327
bpc_logErrf("bpc_attribCache_loadPath: bpc_attrib_dirRead(%s, %s) returned %d\n", ac->backupTopDir->s, attribPath->s, status);
325328
}
329+
if ( bpc_attrib_dirNeedRewrite(&attr->dir) ) {
330+
attr->dirty = 1;
331+
}
326332
/*
327333
* remove any extraneous BPC_FTYPE_DELETED file types
328334
*/
329335
bpc_hashtable_iterate(&attr->dir.filesHT, (void*)bpc_attribCache_removeDeletedEntries, attr);
330336
}
337+
if ( attr->dirty ) {
338+
if ( BPC_LogLevel >= 8 ) bpc_logMsgf("bpc_attribCache_loadPath: will rewrite path = %s -> dir = %s, fileName = %s, attribPath = %s\n", path, dirStr->s, fileName, attribPath->s);
339+
}
331340
if ( bpc_hashtable_entryCount(&ac->attrHT) > BPC_ATTRIBCACHE_DIR_COUNT_MAX ) {
332341
bpc_attribCache_flush(ac, 0, NULL);
333342
}
@@ -382,7 +391,7 @@ static bpc_attribCache_dir *bpc_attribCache_loadInode(bpc_attribCache_info *ac,
382391
for ( i = 0 ; i < ac->bkupMergeCnt ; i++ ) {
383392
bpc_attrib_dir dir;
384393
ssize_t entrySize;
385-
char *entries, *fileName;
394+
char *entries, *entry;
386395

387396
bpc_strBuf_snprintf(inodeDir, 0, "%s/pc/%s/%d/%s", BPC_TopDir.s, ac->hostName->s, ac->bkupMergeList[i].num, attribDir->s);
388397
bpc_strBuf_snprintf(fullAttribPath, 0, "%s/%s", inodeDir->s, attribFile->s);
@@ -400,29 +409,32 @@ static bpc_attribCache_dir *bpc_attribCache_loadInode(bpc_attribCache_info *ac,
400409
}
401410
bpc_logErrf("bpc_attribCache_loadInode: bpc_attrib_dirRead(%s/%s) returned %d\n", inodeDir->s, attribFile->s, status);
402411
}
412+
if ( bpc_attrib_dirNeedRewrite(&dir) ) {
413+
attr->dirty = 1;
414+
}
403415
entrySize = bpc_attrib_getEntries(&dir, NULL, 0);
404416
if ( (entries = malloc(entrySize + 1)) && bpc_attrib_getEntries(&dir, entries, entrySize) == entrySize ) {
405-
for ( fileName = entries ; fileName < entries + entrySize ; fileName += strlen(fileName) + 1 ) {
406-
bpc_attrib_file *file = bpc_attrib_fileGet(&dir, fileName, 0);
417+
for ( entry = entries ; entry < entries + entrySize ; entry += strlen(entry) + 1 ) {
418+
bpc_attrib_file *file = bpc_attrib_fileGet(&dir, entry, 0);
407419
if ( !file ) continue;
408420
if ( file->type == BPC_FTYPE_DELETED ) {
409-
bpc_attrib_fileDeleteName(&attr->dir, fileName);
421+
bpc_attrib_fileDeleteName(&attr->dir, entry);
410422
} else {
411423
bpc_attrib_file *fileDest;
412424

413-
if ( !(fileDest = bpc_attrib_fileGet(&attr->dir, fileName, 1)) ) {
425+
if ( !(fileDest = bpc_attrib_fileGet(&attr->dir, entry, 1)) ) {
414426
bpc_strBuf_free(attribPath);
415427
bpc_strBuf_free(attribDir);
416428
bpc_strBuf_free(attribFile);
417429
bpc_strBuf_free(inodeDir);
418430
bpc_strBuf_free(fullAttribPath);
419431
return NULL;
420432
}
421-
if ( fileDest->key.key == fileName ) {
433+
if ( fileDest->key.key == entry ) {
422434
/*
423435
* new entry - initialize
424436
*/
425-
bpc_attrib_fileInit(fileDest, fileName, 0);
437+
bpc_attrib_fileInit(fileDest, entry, 0);
426438
}
427439
bpc_attrib_fileCopy(fileDest, file);
428440
}
@@ -451,6 +463,12 @@ static bpc_attribCache_dir *bpc_attribCache_loadInode(bpc_attribCache_info *ac,
451463
if ( (status = bpc_attrib_dirRead(&attr->dir, inodeDir->s, attribFile->s, ac->backupNum)) ) {
452464
bpc_logErrf("bpc_attribCache_loadInode: bpc_attrib_dirRead(%s/%s) returned %d\n", inodeDir->s, attribFile->s, status);
453465
}
466+
if ( bpc_attrib_dirNeedRewrite(&attr->dir) ) {
467+
attr->dirty = 1;
468+
}
469+
}
470+
if ( attr->dirty ) {
471+
if ( BPC_LogLevel >= 8 ) bpc_logMsgf("bpc_attribCache_loadInode: will rewrite path = %s -> dir = %s, fileName = %s\n", attribPath, attribDir, attribFile);
454472
}
455473
if ( bpc_hashtable_entryCount(&ac->inodeHT) > BPC_ATTRIBCACHE_DIR_COUNT_MAX ) {
456474
bpc_attribCache_flush(ac, 0, NULL);

0 commit comments

Comments
 (0)