From 6e000d3424c0eed685483f54348c6b0a752a0435 Mon Sep 17 00:00:00 2001 From: Dean Deng Date: Wed, 24 Feb 2021 01:46:44 -0800 Subject: Use async task context for async IO. PiperOrigin-RevId: 359235699 --- pkg/sentry/syscalls/linux/error.go | 19 ++++++++++++------- pkg/sentry/syscalls/linux/vfs2/aio.go | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'pkg/sentry/syscalls/linux') diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index d1778d029..5bd526b73 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -18,6 +18,7 @@ import ( "io" "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/metric" "gvisor.dev/gvisor/pkg/sentry/fs" @@ -36,16 +37,16 @@ var ( // errors, we may consume the error and return only the partial read/write. // // op and f are used only for panics. -func HandleIOErrorVFS2(t *kernel.Task, partialResult bool, ioerr, intr error, op string, f *vfs.FileDescription) error { - known, err := handleIOErrorImpl(t, partialResult, ioerr, intr, op) +func HandleIOErrorVFS2(ctx context.Context, partialResult bool, ioerr, intr error, op string, f *vfs.FileDescription) error { + known, err := handleIOErrorImpl(ctx, partialResult, ioerr, intr, op) if err != nil { return err } if !known { // An unknown error is encountered with a partial read/write. fs := f.Mount().Filesystem().VirtualFilesystem() - root := vfs.RootFromContext(t) - name, _ := fs.PathnameWithDeleted(t, root, f.VirtualDentry()) + root := vfs.RootFromContext(ctx) + name, _ := fs.PathnameWithDeleted(ctx, root, f.VirtualDentry()) log.Traceback("Invalid request partialResult %v and err (type %T) %v for %s operation on %q", partialResult, ioerr, ioerr, op, name) partialResultOnce.Do(partialResultMetric.Increment) } @@ -56,8 +57,8 @@ func HandleIOErrorVFS2(t *kernel.Task, partialResult bool, ioerr, intr error, op // errors, we may consume the error and return only the partial read/write. // // op and f are used only for panics. -func handleIOError(t *kernel.Task, partialResult bool, ioerr, intr error, op string, f *fs.File) error { - known, err := handleIOErrorImpl(t, partialResult, ioerr, intr, op) +func handleIOError(ctx context.Context, partialResult bool, ioerr, intr error, op string, f *fs.File) error { + known, err := handleIOErrorImpl(ctx, partialResult, ioerr, intr, op) if err != nil { return err } @@ -74,7 +75,7 @@ func handleIOError(t *kernel.Task, partialResult bool, ioerr, intr error, op str // errors, we may consume the error and return only the partial read/write. // // Returns false if error is unknown. -func handleIOErrorImpl(t *kernel.Task, partialResult bool, err, intr error, op string) (bool, error) { +func handleIOErrorImpl(ctx context.Context, partialResult bool, err, intr error, op string) (bool, error) { switch err { case nil: // Typical successful syscall. @@ -85,6 +86,10 @@ func handleIOErrorImpl(t *kernel.Task, partialResult bool, err, intr error, op s // they will see 0. return true, nil case syserror.ErrExceedsFileSizeLimit: + t := kernel.TaskFromContext(ctx) + if t == nil { + panic("I/O error should only occur from a context associated with a Task") + } // Ignore partialResult because this error only applies to // normal files, and for those files we cannot accumulate // write results. diff --git a/pkg/sentry/syscalls/linux/vfs2/aio.go b/pkg/sentry/syscalls/linux/vfs2/aio.go index 1365a5a62..de6789a65 100644 --- a/pkg/sentry/syscalls/linux/vfs2/aio.go +++ b/pkg/sentry/syscalls/linux/vfs2/aio.go @@ -177,7 +177,7 @@ func getAIOCallback(t *kernel.Task, fd, eventFD *vfs.FileDescription, cbAddr use // Update the result. if err != nil { - err = slinux.HandleIOErrorVFS2(t, ev.Result != 0 /* partial */, err, nil /* never interrupted */, "aio", fd) + err = slinux.HandleIOErrorVFS2(ctx, ev.Result != 0 /* partial */, err, nil /* never interrupted */, "aio", fd) ev.Result = -int64(kernel.ExtractErrno(err, 0)) } -- cgit v1.2.3