summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/dirent.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fs/dirent.go')
-rw-r--r--pkg/sentry/fs/dirent.go21
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))
}