diff options
Diffstat (limited to 'pkg/sentry/fs/dirent.go')
-rw-r--r-- | pkg/sentry/fs/dirent.go | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index ca417d2bc..fbca06761 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -229,11 +229,13 @@ func newDirent(inode *Inode, name string) *Dirent { if inode != nil { inode.MountSource.IncDirentRefs() } - return &Dirent{ + d := Dirent{ Inode: inode, name: name, children: make(map[string]*refs.WeakRef), } + d.EnableLeakCheck("fs.Dirent") + return &d } // NewNegativeDirent returns a new root negative Dirent. Otherwise same as NewDirent. @@ -918,7 +920,7 @@ type DirIterator interface { // calls, and must start with the given offset. // // The caller must ensure that this operation is permitted. - IterateDir(ctx context.Context, dirCtx *DirCtx, offset int) (int, error) + IterateDir(ctx context.Context, d *Dirent, dirCtx *DirCtx, offset int) (int, error) } // DirentReaddir serializes the directory entries of d including "." and "..". @@ -948,9 +950,6 @@ func direntReaddir(ctx context.Context, d *Dirent, it DirIterator, root *Dirent, if dirCtx.Serializer == nil { panic("Dirent.Readdir: serializer must not be nil") } - if d.frozen { - return d.readdirFrozen(root, offset, dirCtx) - } // Check that this is actually a directory before emitting anything. // Once we have written entries for "." and "..", future errors from @@ -959,6 +958,16 @@ func direntReaddir(ctx context.Context, d *Dirent, it DirIterator, root *Dirent, return 0, syserror.ENOTDIR } + // This is a special case for lseek(fd, 0, SEEK_END). + // See SeekWithDirCursor for more details. + if offset == FileMaxOffset { + return offset, nil + } + + if d.frozen { + return d.readdirFrozen(root, offset, dirCtx) + } + // Collect attrs for "." and "..". dot, dotdot := d.GetDotAttrs(root) @@ -981,7 +990,7 @@ func direntReaddir(ctx context.Context, d *Dirent, it DirIterator, root *Dirent, // it.IterateDir should be passed an offset that does not include the // initial dot elements. We will add them back later. offset -= 2 - newOffset, err := it.IterateDir(ctx, dirCtx, int(offset)) + newOffset, err := it.IterateDir(ctx, d, dirCtx, int(offset)) if int64(newOffset) < offset { panic(fmt.Sprintf("node.Readdir returned offset %v less than input offset %v", newOffset, offset)) } |