diff options
author | Jamie Liu <jamieliu@google.com> | 2020-07-30 15:00:42 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-07-30 15:02:22 -0700 |
commit | 1b11326ecdd788fccc8e396b7467bbbb591d563f (patch) | |
tree | 45337adf1d16ed9028567aac1ed2f6d5b560d791 /runsc/fsgofer/fsgofer.go | |
parent | f15d5a8d0fe4ad7d072909e7957977756f7be118 (diff) |
Call lseek(0, SEEK_CUR) unconditionally in runsc fsgofer's Readdir(offset=0).
9P2000.L is silent as to how readdir RPCs interact with directory mutation. The
most performant option is for Treaddir with offset=0 to restart iteration,
avoiding needing to walk+open+clunk a new directory fid between invocations of
getdents64(2), and the VFS2 gofer client assumes this is the case. Make this
actually true for the runsc fsgofer.
Fixes #3344, #3345, #3355
PiperOrigin-RevId: 324090384
Diffstat (limited to 'runsc/fsgofer/fsgofer.go')
-rw-r--r-- | runsc/fsgofer/fsgofer.go | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index ebefeacf2..c6694c278 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -979,9 +979,12 @@ func (l *localFile) Readdir(offset uint64, count uint32) ([]p9.Dirent, error) { skip := uint64(0) - // Check if the file is at the correct position already. If not, seek to the - // beginning and read the entire directory again. - if l.lastDirentOffset != offset { + // Check if the file is at the correct position already. If not, seek to + // the beginning and read the entire directory again. We always seek if + // offset is 0, since this is side-effectual (equivalent to rewinddir(3), + // which causes the directory stream to resynchronize with the directory's + // current contents). + if l.lastDirentOffset != offset || offset == 0 { if _, err := syscall.Seek(l.file.FD(), 0, 0); err != nil { return nil, extractErrno(err) } |