mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Avoid calling sync on each write in writethrough mode.
PiperOrigin-RevId: 364370595
This commit is contained in:
committed by
gVisor bot
parent
cbac2d9f97
commit
b428fd02e6
@@ -380,16 +380,17 @@ func (c *CachingInodeOperations) Allocate(ctx context.Context, offset, length in
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteOut implements fs.InodeOperations.WriteOut.
|
||||
func (c *CachingInodeOperations) WriteOut(ctx context.Context, inode *fs.Inode) error {
|
||||
// WriteDirtyPagesAndAttrs will write the dirty pages and attributes to the
|
||||
// gofer without calling Fsync on the remote file.
|
||||
func (c *CachingInodeOperations) WriteDirtyPagesAndAttrs(ctx context.Context, inode *fs.Inode) error {
|
||||
c.attrMu.Lock()
|
||||
defer c.attrMu.Unlock()
|
||||
c.dataMu.Lock()
|
||||
defer c.dataMu.Unlock()
|
||||
|
||||
// Write dirty pages back.
|
||||
c.dataMu.Lock()
|
||||
err := SyncDirtyAll(ctx, &c.cache, &c.dirty, uint64(c.attr.Size), c.mfp.MemoryFile(), c.backingFile.WriteFromBlocksAt)
|
||||
c.dataMu.Unlock()
|
||||
if err != nil {
|
||||
c.attrMu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -399,12 +400,18 @@ func (c *CachingInodeOperations) WriteOut(ctx context.Context, inode *fs.Inode)
|
||||
|
||||
// Write out cached attributes.
|
||||
if err := c.backingFile.SetMaskedAttributes(ctx, c.dirtyAttr, c.attr, false); err != nil {
|
||||
c.attrMu.Unlock()
|
||||
return err
|
||||
}
|
||||
c.dirtyAttr = fs.AttrMask{}
|
||||
|
||||
c.attrMu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteOut implements fs.InodeOperations.WriteOut.
|
||||
func (c *CachingInodeOperations) WriteOut(ctx context.Context, inode *fs.Inode) error {
|
||||
if err := c.WriteDirtyPagesAndAttrs(ctx, inode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Fsync the remote file.
|
||||
return c.backingFile.Sync(ctx)
|
||||
|
||||
+14
-13
@@ -204,20 +204,8 @@ func (f *fileOperations) readdirAll(ctx context.Context) (map[string]fs.DentAttr
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
// maybeSync will call FSync on the file if either the cache policy or file
|
||||
// flags require it.
|
||||
// maybeSync will call FSync on the file if the file flags require it.
|
||||
func (f *fileOperations) maybeSync(ctx context.Context, file *fs.File, offset, n int64) error {
|
||||
if n == 0 {
|
||||
// Nothing to sync.
|
||||
return nil
|
||||
}
|
||||
|
||||
if f.inodeOperations.session().cachePolicy.writeThrough(file.Dirent.Inode) {
|
||||
// Call WriteOut directly, as some "writethrough" filesystems
|
||||
// do not support sync.
|
||||
return f.inodeOperations.cachingInodeOps.WriteOut(ctx, file.Dirent.Inode)
|
||||
}
|
||||
|
||||
flags := file.Flags()
|
||||
var syncType fs.SyncType
|
||||
switch {
|
||||
@@ -254,6 +242,19 @@ func (f *fileOperations) Write(ctx context.Context, file *fs.File, src usermem.I
|
||||
n, err = src.CopyInTo(ctx, f.handles.readWriterAt(ctx, offset))
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
// Nothing written. We are done.
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Write the dirty pages and attributes if cache policy tells us to.
|
||||
if f.inodeOperations.session().cachePolicy.writeThrough(file.Dirent.Inode) {
|
||||
if werr := f.inodeOperations.cachingInodeOps.WriteDirtyPagesAndAttrs(ctx, file.Dirent.Inode); werr != nil {
|
||||
// Report no bytes written since the write faild.
|
||||
return 0, werr
|
||||
}
|
||||
}
|
||||
|
||||
// We may need to sync the written bytes.
|
||||
if syncErr := f.maybeSync(ctx, file, offset, n); syncErr != nil {
|
||||
// Sync failed. Report 0 bytes written, since none of them are
|
||||
|
||||
Reference in New Issue
Block a user