github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/objstorage/objstorageprovider/vfs.go (about) 1 // Copyright 2023 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package objstorageprovider 6 7 import ( 8 "context" 9 10 "github.com/cockroachdb/errors" 11 "github.com/cockroachdb/pebble/internal/base" 12 "github.com/cockroachdb/pebble/objstorage" 13 "github.com/cockroachdb/pebble/vfs" 14 ) 15 16 func (p *provider) vfsPath(fileType base.FileType, fileNum base.DiskFileNum) string { 17 return base.MakeFilepath(p.st.FS, p.st.FSDirName, fileType, fileNum) 18 } 19 20 func (p *provider) vfsOpenForReading( 21 ctx context.Context, 22 fileType base.FileType, 23 fileNum base.DiskFileNum, 24 opts objstorage.OpenOptions, 25 ) (objstorage.Readable, error) { 26 filename := p.vfsPath(fileType, fileNum) 27 file, err := p.st.FS.Open(filename, vfs.RandomReadsOption) 28 if err != nil { 29 if opts.MustExist { 30 base.MustExist(p.st.FS, filename, p.st.Logger, err) 31 } 32 return nil, err 33 } 34 return newFileReadable(file, p.st.FS, filename) 35 } 36 37 func (p *provider) vfsCreate( 38 _ context.Context, fileType base.FileType, fileNum base.DiskFileNum, 39 ) (objstorage.Writable, objstorage.ObjectMetadata, error) { 40 filename := p.vfsPath(fileType, fileNum) 41 file, err := p.st.FS.Create(filename) 42 if err != nil { 43 return nil, objstorage.ObjectMetadata{}, err 44 } 45 file = vfs.NewSyncingFile(file, vfs.SyncingFileOptions{ 46 NoSyncOnClose: p.st.NoSyncOnClose, 47 BytesPerSync: p.st.BytesPerSync, 48 }) 49 meta := objstorage.ObjectMetadata{ 50 DiskFileNum: fileNum, 51 FileType: fileType, 52 } 53 return newFileBufferedWritable(file), meta, nil 54 } 55 56 func (p *provider) vfsRemove(fileType base.FileType, fileNum base.DiskFileNum) error { 57 return p.st.FSCleaner.Clean(p.st.FS, fileType, p.vfsPath(fileType, fileNum)) 58 } 59 60 // vfsInit finds any local FS objects. 61 func (p *provider) vfsInit() error { 62 listing := p.st.FSDirInitialListing 63 if listing == nil { 64 var err error 65 listing, err = p.st.FS.List(p.st.FSDirName) 66 if err != nil { 67 return errors.Wrapf(err, "pebble: could not list store directory") 68 } 69 } 70 71 for _, filename := range listing { 72 fileType, fileNum, ok := base.ParseFilename(p.st.FS, filename) 73 if ok && fileType == base.FileTypeTable { 74 o := objstorage.ObjectMetadata{ 75 FileType: fileType, 76 DiskFileNum: fileNum, 77 } 78 p.mu.knownObjects[o.DiskFileNum] = o 79 } 80 } 81 return nil 82 } 83 84 func (p *provider) vfsSync() error { 85 p.mu.Lock() 86 shouldSync := p.mu.localObjectsChanged 87 p.mu.localObjectsChanged = false 88 p.mu.Unlock() 89 90 if !shouldSync { 91 return nil 92 } 93 if err := p.fsDir.Sync(); err != nil { 94 p.mu.Lock() 95 defer p.mu.Unlock() 96 p.mu.localObjectsChanged = true 97 return err 98 } 99 return nil 100 } 101 102 func (p *provider) vfsSize(fileType base.FileType, fileNum base.DiskFileNum) (int64, error) { 103 filename := p.vfsPath(fileType, fileNum) 104 stat, err := p.st.FS.Stat(filename) 105 if err != nil { 106 return 0, err 107 } 108 return stat.Size(), nil 109 }