github.com/cockroachdb/pebble@v1.1.2/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 readaheadConfig := DefaultReadaheadConfig 35 if f := p.st.Local.ReadaheadConfigFn; f != nil { 36 readaheadConfig = f() 37 } 38 return newFileReadable(file, p.st.FS, readaheadConfig, filename) 39 } 40 41 func (p *provider) vfsCreate( 42 _ context.Context, fileType base.FileType, fileNum base.DiskFileNum, 43 ) (objstorage.Writable, objstorage.ObjectMetadata, error) { 44 filename := p.vfsPath(fileType, fileNum) 45 file, err := p.st.FS.Create(filename) 46 if err != nil { 47 return nil, objstorage.ObjectMetadata{}, err 48 } 49 file = vfs.NewSyncingFile(file, vfs.SyncingFileOptions{ 50 NoSyncOnClose: p.st.NoSyncOnClose, 51 BytesPerSync: p.st.BytesPerSync, 52 }) 53 meta := objstorage.ObjectMetadata{ 54 DiskFileNum: fileNum, 55 FileType: fileType, 56 } 57 return newFileBufferedWritable(file), meta, nil 58 } 59 60 func (p *provider) vfsRemove(fileType base.FileType, fileNum base.DiskFileNum) error { 61 return p.st.FSCleaner.Clean(p.st.FS, fileType, p.vfsPath(fileType, fileNum)) 62 } 63 64 // vfsInit finds any local FS objects. 65 func (p *provider) vfsInit() error { 66 listing := p.st.FSDirInitialListing 67 if listing == nil { 68 var err error 69 listing, err = p.st.FS.List(p.st.FSDirName) 70 if err != nil { 71 return errors.Wrapf(err, "pebble: could not list store directory") 72 } 73 } 74 75 for _, filename := range listing { 76 fileType, fileNum, ok := base.ParseFilename(p.st.FS, filename) 77 if ok && fileType == base.FileTypeTable { 78 o := objstorage.ObjectMetadata{ 79 FileType: fileType, 80 DiskFileNum: fileNum, 81 } 82 p.mu.knownObjects[o.DiskFileNum] = o 83 } 84 } 85 return nil 86 } 87 88 func (p *provider) vfsSync() error { 89 p.mu.Lock() 90 shouldSync := p.mu.localObjectsChanged 91 p.mu.localObjectsChanged = false 92 p.mu.Unlock() 93 94 if !shouldSync { 95 return nil 96 } 97 if err := p.fsDir.Sync(); err != nil { 98 p.mu.Lock() 99 defer p.mu.Unlock() 100 p.mu.localObjectsChanged = true 101 return err 102 } 103 return nil 104 } 105 106 func (p *provider) vfsSize(fileType base.FileType, fileNum base.DiskFileNum) (int64, error) { 107 filename := p.vfsPath(fileType, fileNum) 108 stat, err := p.st.FS.Stat(filename) 109 if err != nil { 110 return 0, err 111 } 112 return stat.Size(), nil 113 }