@@ -48,7 +48,7 @@ func NewFS(c *params.InstanceParams) (FS, error) {
48
48
return nil , fmt .Errorf ("creating base dir: %s - %w" , fsLocalBaseDir , err )
49
49
}
50
50
51
- tierFS := & TierFS {
51
+ tfs := & TierFS {
52
52
adapter : c .Adapter ,
53
53
fsName : c .FSName ,
54
54
logger : c .Logger ,
@@ -59,44 +59,43 @@ func NewFS(c *params.InstanceParams) (FS, error) {
59
59
}
60
60
if c .Eviction == nil {
61
61
var err error
62
- c .Eviction , err = newRistrettoEviction (c .AllocatedBytes (), tierFS .removeFromLocal )
62
+ c .Eviction , err = newRistrettoEviction (c .AllocatedBytes (), tfs .removeFromLocal )
63
63
if err != nil {
64
64
return nil , fmt .Errorf ("creating eviction control: %w" , err )
65
65
}
66
66
}
67
67
68
- tierFS .eviction = c .Eviction
69
- if err := handleExistingFiles (tierFS . eviction , fsLocalBaseDir ); err != nil {
68
+ tfs .eviction = c .Eviction
69
+ if err := tfs . handleExistingFiles (); err != nil {
70
70
return nil , fmt .Errorf ("handling existing files: %w" , err )
71
71
}
72
72
73
- return tierFS , nil
73
+ return tfs , nil
74
74
}
75
75
76
76
// handleExistingFiles should only be called during init of the TierFS.
77
77
// It does 2 things:
78
78
// 1. Adds stored files to the eviction control
79
79
// 2. Remove workspace directories and all its content if it
80
80
// exist under the namespace dir.
81
- func handleExistingFiles ( eviction params. Eviction , fsLocalBaseDir string ) error {
82
- if err := filepath .Walk (fsLocalBaseDir , func (rPath string , info os.FileInfo , err error ) error {
81
+ func ( tfs * TierFS ) handleExistingFiles ( ) error {
82
+ if err := filepath .Walk (tfs . fsLocalBaseDir , func (p string , info os.FileInfo , err error ) error {
83
83
if err != nil {
84
84
return err
85
85
}
86
86
if info .IsDir () {
87
87
if info .Name () == workspaceDir {
88
88
// skipping workspaces and saving them for later delete
89
- if err := os .RemoveAll (rPath ); err != nil {
89
+ if err := os .RemoveAll (p ); err != nil {
90
90
return fmt .Errorf ("removing dir: %w" , err )
91
91
}
92
92
return filepath .SkipDir
93
93
}
94
94
return nil
95
95
}
96
96
97
- if err := storeLocalFile (rPath , info .Size (), eviction ); err != nil {
98
- return err
99
- }
97
+ rPath := strings .TrimPrefix (p , tfs .fsLocalBaseDir )
98
+ tfs .storeLocalFile (params .RelativePath (rPath ), info .Size ())
100
99
return nil
101
100
}); err != nil {
102
101
return fmt .Errorf ("walking the fs dir: %w" , err )
@@ -121,7 +120,7 @@ func (tfs *TierFS) removeFromLocalInternal(rPath params.RelativePath) {
121
120
return
122
121
}
123
122
124
- if err := tfs .syncDir .deleteDirRecIfEmpty (path .Dir (p )); err != nil {
123
+ if err := tfs .syncDir .deleteDirRecIfEmpty (path .Dir (string ( rPath ) )); err != nil {
125
124
tfs .logger .WithError (err ).Error ("Failed deleting empty dir" )
126
125
errorsTotal .WithLabelValues (tfs .fsName , "DirRemoval" )
127
126
}
@@ -240,10 +239,16 @@ func (tfs *TierFS) openFile(fileRef localFileRef, fh *os.File) (*ROFile, error)
240
239
}
241
240
242
241
if ! tfs .eviction .Store (fileRef .fsRelativePath , stat .Size ()) {
243
- // This is where we get less strict.
244
- // Ideally, newly fetched file will never be rejected by the cache.
245
- // But if it did, we prefer to serve the file and delete it.
246
- // When the user will close the file, the file will be deleted from the disk too.
242
+ tfs .logger .WithFields (logging.Fields {
243
+ "namespace" : fileRef .namespace ,
244
+ "file" : fileRef .filename ,
245
+ "full_path" : fileRef .fullPath ,
246
+ }).Info ("stored file immediately rejected from cache (delete but continue)" )
247
+
248
+ // A rare occurrence, (currently) happens when Ristretto cache is not set up
249
+ // to perform any caching. So be less strict: prefer to serve the file and
250
+ // delete it from the cache. It will be removed from disk when the last
251
+ // surviving file descriptor -- returned from this function -- is closed.
247
252
if err := os .Remove (fileRef .fullPath ); err != nil {
248
253
return nil , err
249
254
}
@@ -334,17 +339,6 @@ func (tfs *TierFS) openWithLock(ctx context.Context, fileRef localFileRef) (*os.
334
339
return fh , nil
335
340
}
336
341
337
- func storeLocalFile (rPath string , size int64 , eviction params.Eviction ) error {
338
- relativePath := params .RelativePath (rPath )
339
- if ! eviction .Store (relativePath , size ) {
340
- err := os .Remove (rPath )
341
- if err != nil {
342
- return fmt .Errorf ("removing file: %w" , err )
343
- }
344
- }
345
- return nil
346
- }
347
-
348
342
func validateFilename (filename string ) error {
349
343
if strings .HasPrefix (filename , workspaceDir + string (os .PathSeparator )) {
350
344
return errPathInWorkspace
@@ -363,13 +357,36 @@ type localFileRef struct {
363
357
fsRelativePath params.RelativePath
364
358
}
365
359
360
+ func (tfs * TierFS ) storeLocalFile (rPath params.RelativePath , size int64 ) {
361
+ if ! tfs .eviction .Store (rPath , size ) {
362
+ // Rejected from cache, so deleted. This is safe, but can only happen when
363
+ // the cache size was lowered -- so warn.
364
+ tfs .logger .WithFields (logging.Fields {
365
+ "path" : rPath ,
366
+ "size" : size ,
367
+ }).Warn ("existing file immediately rejected from cache on startup (safe if cache size changed; continue)" )
368
+
369
+ // A rare occurrence, (currently) happens when Ristretto cache is not set up
370
+ // to perform any caching. So be less strict: prefer to serve the file and
371
+ // delete it from the cache. It will be removed from disk when the last
372
+ // surviving file descriptor -- returned from this function -- is closed.
373
+ if err := os .Remove (string (rPath )); err != nil {
374
+ tfs .logger .WithFields (logging.Fields {
375
+ "path" : rPath ,
376
+ "size" : size ,
377
+ }).Error ("failed to delete immediately-rejected existing file from cache on startup" )
378
+ return
379
+ }
380
+ }
381
+ }
382
+
366
383
func (tfs * TierFS ) newLocalFileRef (namespace , nsPath , filename string ) localFileRef {
367
- relative := path .Join (nsPath , filename )
384
+ rPath := path .Join (nsPath , filename )
368
385
return localFileRef {
369
386
namespace : namespace ,
370
387
filename : filename ,
371
- fsRelativePath : params .RelativePath (relative ),
372
- fullPath : path .Join (tfs .fsLocalBaseDir , relative ),
388
+ fsRelativePath : params .RelativePath (rPath ),
389
+ fullPath : path .Join (tfs .fsLocalBaseDir , rPath ),
373
390
}
374
391
}
375
392
0 commit comments