daemon: Account for deleted store files when deduplication is on.
Previously, a store item that is a regular file would not be accounted for in the 'bytesFreed' value computed by 'deletePath' because its 'st_nlink' count would always be >= 2. This commit fixes that. * nix/libutil/util.hh (deletePath): Add optional 'linkThreshold' argument. * nix/libutil/util.cc (_deletePath): Add 'linkThreshold' argument and honor it. Pass it down in recursive call. (deletePath): Add 'linkThreshold' and honor it. * nix/libstore/gc.cc (LocalStore::deleteGarbage): Pass 'linkThreshold' argument to 'deletePath', with a value of 2 when PATH is a store item and deduplication is on.
This commit is contained in:
		
							parent
							
								
									79154f0a09
								
							
						
					
					
						commit
						7033c7692c
					
				
					 3 changed files with 17 additions and 8 deletions
				
			
		|  | @ -392,7 +392,14 @@ bool LocalStore::isActiveTempFile(const GCState & state, | |||
| void LocalStore::deleteGarbage(GCState & state, const Path & path) | ||||
| { | ||||
|     unsigned long long bytesFreed; | ||||
|     deletePath(path, bytesFreed); | ||||
| 
 | ||||
|     /* When deduplication is on, store items always have at least two links:
 | ||||
|        the one at PATH, and one in /gnu/store/.links.  In that case, increase | ||||
|        bytesFreed when PATH has two or fewer links.  */ | ||||
|     size_t linkThreshold = | ||||
| 	(settings.autoOptimiseStore && isStorePath(path)) ? 2 : 1; | ||||
| 
 | ||||
|     deletePath(path, bytesFreed, linkThreshold); | ||||
|     state.results.bytesFreed += bytesFreed; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -305,7 +305,7 @@ void writeLine(int fd, string s) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void _deletePath(const Path & path, unsigned long long & bytesFreed) | ||||
| static void _deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold) | ||||
| { | ||||
|     checkInterrupt(); | ||||
| 
 | ||||
|  | @ -324,7 +324,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed) | |||
|     struct stat st = lstat(path); | ||||
| #endif | ||||
| 
 | ||||
|     if (!S_ISDIR(st.st_mode) && st.st_nlink == 1) | ||||
|     if (!S_ISDIR(st.st_mode) && st.st_nlink <= linkThreshold) | ||||
| 	bytesFreed += st.st_size; | ||||
| 
 | ||||
|     if (S_ISDIR(st.st_mode)) { | ||||
|  | @ -335,7 +335,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed) | |||
|         } | ||||
| 
 | ||||
|         for (auto & i : readDirectory(path)) | ||||
|             _deletePath(path + "/" + i.name, bytesFreed); | ||||
|             _deletePath(path + "/" + i.name, bytesFreed, linkThreshold); | ||||
|     } | ||||
| #undef st_mode | ||||
| #undef st_size | ||||
|  | @ -353,12 +353,12 @@ void deletePath(const Path & path) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| void deletePath(const Path & path, unsigned long long & bytesFreed) | ||||
| void deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold) | ||||
| { | ||||
|     startNest(nest, lvlDebug, | ||||
|         format("recursively deleting path `%1%'") % path); | ||||
|     bytesFreed = 0; | ||||
|     _deletePath(path, bytesFreed); | ||||
|     _deletePath(path, bytesFreed, linkThreshold); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -94,10 +94,12 @@ void writeLine(int fd, string s); | |||
| 
 | ||||
| /* Delete a path; i.e., in the case of a directory, it is deleted
 | ||||
|    recursively.  Don't use this at home, kids.  The second variant | ||||
|    returns the number of bytes and blocks freed. */ | ||||
|    returns the number of bytes and blocks freed, and 'linkThreshold' denotes | ||||
|    the number of links under which a file is accounted for in 'bytesFreed'.  */ | ||||
| void deletePath(const Path & path); | ||||
| 
 | ||||
| void deletePath(const Path & path, unsigned long long & bytesFreed); | ||||
| void deletePath(const Path & path, unsigned long long & bytesFreed, | ||||
|     size_t linkThreshold = 1); | ||||
| 
 | ||||
| /* Create a temporary directory. */ | ||||
| Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", | ||||
|  |  | |||
		Reference in a new issue