diff --git a/src/os/dir_plan9.go b/src/os/dir_plan9.go
index 5e6376282caf952b69c826d816ad888590ad792e..8f6b0d61098e4e4f65bcc22387d378dcd934d688 100644
--- a/src/os/dir_plan9.go
+++ b/src/os/dir_plan9.go
@@ -32,10 +32,10 @@ func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []Di
 				if err == io.EOF {
 					break
 				}
-				return names, dirents, infos, &PathError{"readdir", file.name, err}
+				return names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: err}
 			}
 			if nb < syscall.STATFIXLEN {
-				return names, dirents, infos, &PathError{"readdir", file.name, syscall.ErrShortStat}
+				return names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: syscall.ErrShortStat}
 			}
 		}
 
@@ -43,12 +43,12 @@ func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []Di
 		b := d.buf[d.bufp:]
 		m := int(uint16(b[0])|uint16(b[1])<<8) + 2
 		if m < syscall.STATFIXLEN {
-			return names, dirents, infos, &PathError{"readdir", file.name, syscall.ErrShortStat}
+			return names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: syscall.ErrShortStat}
 		}
 
 		dir, err := syscall.UnmarshalDir(b[:m])
 		if err != nil {
-			return names, dirents, infos, &PathError{"readdir", file.name, err}
+			return names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: err}
 		}
 
 		if mode == readdirName {
diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go
index 22a4e715fe64c5e4813d187a08f157a39c5dbd63..3e5a6983501ee91a5dca1de9abfc223b1e0eb0ec 100644
--- a/src/os/dir_unix.go
+++ b/src/os/dir_unix.go
@@ -50,7 +50,7 @@ func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEn
 			d.nbuf, errno = f.pfd.ReadDirent(d.buf)
 			runtime.KeepAlive(f)
 			if errno != nil {
-				return names, dirents, infos, &PathError{"readdirent", f.name, errno}
+				return names, dirents, infos, &PathError{Op: "readdirent", Path: f.name, Err: errno}
 			}
 			if d.nbuf <= 0 {
 				break // EOF
diff --git a/src/os/dir_windows.go b/src/os/dir_windows.go
index 1c3f2f0d574abe0772e9702af59cf268e01e9909..253adad0b90e503b8c0a1756bacf687dcfabbbe1 100644
--- a/src/os/dir_windows.go
+++ b/src/os/dir_windows.go
@@ -12,7 +12,7 @@ import (
 
 func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
 	if !file.isdir() {
-		return nil, nil, nil, &PathError{"readdir", file.name, syscall.ENOTDIR}
+		return nil, nil, nil, &PathError{Op: "readdir", Path: file.name, Err: syscall.ENOTDIR}
 	}
 	wantAll := n <= 0
 	if wantAll {
@@ -27,7 +27,7 @@ func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []Di
 				if e == syscall.ERROR_NO_MORE_FILES {
 					break
 				} else {
-					err = &PathError{"FindNextFile", file.name, e}
+					err = &PathError{Op: "FindNextFile", Path: file.name, Err: e}
 					return
 				}
 			}
diff --git a/src/os/exec_plan9.go b/src/os/exec_plan9.go
index b0abf743ddb90f5b59607326ee3cba70807728ed..ef8dad11b61385a14066d2fdb5e6252b210a0799 100644
--- a/src/os/exec_plan9.go
+++ b/src/os/exec_plan9.go
@@ -34,7 +34,7 @@ func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
 
 	pid, h, e := syscall.StartProcess(name, argv, sysattr)
 	if e != nil {
-		return nil, &PathError{"fork/exec", name, e}
+		return nil, &PathError{Op: "fork/exec", Path: name, Err: e}
 	}
 
 	return newProcess(pid, h), nil
diff --git a/src/os/exec_posix.go b/src/os/exec_posix.go
index 45b47a542d6a9bf886c41dfd0e7eb4d87dfbe2ae..7ecddaed374d8a31699b5a75ddc67bda31221c1d 100644
--- a/src/os/exec_posix.go
+++ b/src/os/exec_posix.go
@@ -56,7 +56,7 @@ func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
 	runtime.KeepAlive(attr)
 
 	if e != nil {
-		return nil, &PathError{"fork/exec", name, e}
+		return nil, &PathError{Op: "fork/exec", Path: name, Err: e}
 	}
 
 	return newProcess(pid, h), nil
diff --git a/src/os/file.go b/src/os/file.go
index 05d2f8328311b166f3ff14d3f667bce93c07ffd2..5f16fc28eeada55cb0193ea3c0d7802c499ebce8 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -127,7 +127,7 @@ func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
 	}
 
 	if off < 0 {
-		return 0, &PathError{"readat", f.name, errors.New("negative offset")}
+		return 0, &PathError{Op: "readat", Path: f.name, Err: errors.New("negative offset")}
 	}
 
 	for len(b) > 0 {
@@ -203,7 +203,7 @@ func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
 	}
 
 	if off < 0 {
-		return 0, &PathError{"writeat", f.name, errors.New("negative offset")}
+		return 0, &PathError{Op: "writeat", Path: f.name, Err: errors.New("negative offset")}
 	}
 
 	for len(b) > 0 {
@@ -253,7 +253,7 @@ func (f *File) WriteString(s string) (n int, err error) {
 // If there is an error, it will be of type *PathError.
 func Mkdir(name string, perm FileMode) error {
 	if runtime.GOOS == "windows" && isWindowsNulName(name) {
-		return &PathError{"mkdir", name, syscall.ENOTDIR}
+		return &PathError{Op: "mkdir", Path: name, Err: syscall.ENOTDIR}
 	}
 	longName := fixLongPath(name)
 	e := ignoringEINTR(func() error {
@@ -261,7 +261,7 @@ func Mkdir(name string, perm FileMode) error {
 	})
 
 	if e != nil {
-		return &PathError{"mkdir", name, e}
+		return &PathError{Op: "mkdir", Path: name, Err: e}
 	}
 
 	// mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
@@ -291,7 +291,7 @@ func setStickyBit(name string) error {
 func Chdir(dir string) error {
 	if e := syscall.Chdir(dir); e != nil {
 		testlog.Open(dir) // observe likely non-existent directory
-		return &PathError{"chdir", dir, e}
+		return &PathError{Op: "chdir", Path: dir, Err: e}
 	}
 	if log := testlog.Logger(); log != nil {
 		wd, err := Getwd()
@@ -366,7 +366,7 @@ func (f *File) wrapErr(op string, err error) error {
 	if err == poll.ErrFileClosing {
 		err = ErrClosed
 	}
-	return &PathError{op, f.name, err}
+	return &PathError{Op: op, Path: f.name, Err: err}
 }
 
 // TempDir returns the default directory to use for temporary files.
diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go
index a1a51a1c06f1139eb738c6f80064552a84885717..bbc732838a5f7c91b8247a2540da404acbfba633 100644
--- a/src/os/file_plan9.go
+++ b/src/os/file_plan9.go
@@ -119,18 +119,18 @@ func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
 		if IsNotExist(e) && create {
 			fd, e = syscall.Create(name, flag, syscallMode(perm))
 			if e != nil {
-				return nil, &PathError{"create", name, e}
+				return nil, &PathError{Op: "create", Path: name, Err: e}
 			}
 		}
 	}
 
 	if e != nil {
-		return nil, &PathError{"open", name, e}
+		return nil, &PathError{Op: "open", Path: name, Err: e}
 	}
 
 	if append {
 		if _, e = syscall.Seek(fd, 0, io.SeekEnd); e != nil {
-			return nil, &PathError{"seek", name, e}
+			return nil, &PathError{Op: "seek", Path: name, Err: e}
 		}
 	}
 
@@ -154,7 +154,7 @@ func (file *file) close() error {
 	}
 	var err error
 	if e := syscall.Close(file.fd); e != nil {
-		err = &PathError{"close", file.name, e}
+		err = &PathError{Op: "close", Path: file.name, Err: e}
 	}
 	file.fd = badFd // so it can't be closed again
 
@@ -191,10 +191,10 @@ func (f *File) Truncate(size int64) error {
 	var buf [syscall.STATFIXLEN]byte
 	n, err := d.Marshal(buf[:])
 	if err != nil {
-		return &PathError{"truncate", f.name, err}
+		return &PathError{Op: "truncate", Path: f.name, Err: err}
 	}
 	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
-		return &PathError{"truncate", f.name, err}
+		return &PathError{Op: "truncate", Path: f.name, Err: err}
 	}
 	return nil
 }
@@ -209,7 +209,7 @@ func (f *File) chmod(mode FileMode) error {
 
 	odir, e := dirstat(f)
 	if e != nil {
-		return &PathError{"chmod", f.name, e}
+		return &PathError{Op: "chmod", Path: f.name, Err: e}
 	}
 	d.Null()
 	d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
@@ -217,10 +217,10 @@ func (f *File) chmod(mode FileMode) error {
 	var buf [syscall.STATFIXLEN]byte
 	n, err := d.Marshal(buf[:])
 	if err != nil {
-		return &PathError{"chmod", f.name, err}
+		return &PathError{Op: "chmod", Path: f.name, Err: err}
 	}
 	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
-		return &PathError{"chmod", f.name, err}
+		return &PathError{Op: "chmod", Path: f.name, Err: err}
 	}
 	return nil
 }
@@ -238,10 +238,10 @@ func (f *File) Sync() error {
 	var buf [syscall.STATFIXLEN]byte
 	n, err := d.Marshal(buf[:])
 	if err != nil {
-		return &PathError{"sync", f.name, err}
+		return &PathError{Op: "sync", Path: f.name, Err: err}
 	}
 	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
-		return &PathError{"sync", f.name, err}
+		return &PathError{Op: "sync", Path: f.name, Err: err}
 	}
 	return nil
 }
@@ -314,10 +314,10 @@ func Truncate(name string, size int64) error {
 	var buf [syscall.STATFIXLEN]byte
 	n, err := d.Marshal(buf[:])
 	if err != nil {
-		return &PathError{"truncate", name, err}
+		return &PathError{Op: "truncate", Path: name, Err: err}
 	}
 	if err = syscall.Wstat(name, buf[:n]); err != nil {
-		return &PathError{"truncate", name, err}
+		return &PathError{Op: "truncate", Path: name, Err: err}
 	}
 	return nil
 }
@@ -326,7 +326,7 @@ func Truncate(name string, size int64) error {
 // If there is an error, it will be of type *PathError.
 func Remove(name string) error {
 	if e := syscall.Remove(name); e != nil {
-		return &PathError{"remove", name, e}
+		return &PathError{Op: "remove", Path: name, Err: e}
 	}
 	return nil
 }
@@ -389,7 +389,7 @@ func chmod(name string, mode FileMode) error {
 
 	odir, e := dirstat(name)
 	if e != nil {
-		return &PathError{"chmod", name, e}
+		return &PathError{Op: "chmod", Path: name, Err: e}
 	}
 	d.Null()
 	d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
@@ -397,10 +397,10 @@ func chmod(name string, mode FileMode) error {
 	var buf [syscall.STATFIXLEN]byte
 	n, err := d.Marshal(buf[:])
 	if err != nil {
-		return &PathError{"chmod", name, err}
+		return &PathError{Op: "chmod", Path: name, Err: err}
 	}
 	if err = syscall.Wstat(name, buf[:n]); err != nil {
-		return &PathError{"chmod", name, err}
+		return &PathError{Op: "chmod", Path: name, Err: err}
 	}
 	return nil
 }
@@ -421,10 +421,10 @@ func Chtimes(name string, atime time.Time, mtime time.Time) error {
 	var buf [syscall.STATFIXLEN]byte
 	n, err := d.Marshal(buf[:])
 	if err != nil {
-		return &PathError{"chtimes", name, err}
+		return &PathError{Op: "chtimes", Path: name, Err: err}
 	}
 	if err = syscall.Wstat(name, buf[:n]); err != nil {
-		return &PathError{"chtimes", name, err}
+		return &PathError{Op: "chtimes", Path: name, Err: err}
 	}
 	return nil
 }
@@ -458,7 +458,7 @@ func Symlink(oldname, newname string) error {
 // Readlink returns the destination of the named symbolic link.
 // If there is an error, it will be of type *PathError.
 func Readlink(name string) (string, error) {
-	return "", &PathError{"readlink", name, syscall.EPLAN9}
+	return "", &PathError{Op: "readlink", Path: name, Err: syscall.EPLAN9}
 }
 
 // Chown changes the numeric uid and gid of the named file.
@@ -469,14 +469,14 @@ func Readlink(name string) (string, error) {
 // On Windows or Plan 9, Chown always returns the syscall.EWINDOWS or
 // EPLAN9 error, wrapped in *PathError.
 func Chown(name string, uid, gid int) error {
-	return &PathError{"chown", name, syscall.EPLAN9}
+	return &PathError{Op: "chown", Path: name, Err: syscall.EPLAN9}
 }
 
 // Lchown changes the numeric uid and gid of the named file.
 // If the file is a symbolic link, it changes the uid and gid of the link itself.
 // If there is an error, it will be of type *PathError.
 func Lchown(name string, uid, gid int) error {
-	return &PathError{"lchown", name, syscall.EPLAN9}
+	return &PathError{Op: "lchown", Path: name, Err: syscall.EPLAN9}
 }
 
 // Chown changes the numeric uid and gid of the named file.
@@ -485,7 +485,7 @@ func (f *File) Chown(uid, gid int) error {
 	if f == nil {
 		return ErrInvalid
 	}
-	return &PathError{"chown", f.name, syscall.EPLAN9}
+	return &PathError{Op: "chown", Path: f.name, Err: syscall.EPLAN9}
 }
 
 func tempDir() string {
@@ -505,7 +505,7 @@ func (f *File) Chdir() error {
 		return err
 	}
 	if e := syscall.Fchdir(f.fd); e != nil {
-		return &PathError{"chdir", f.name, e}
+		return &PathError{Op: "chdir", Path: f.name, Err: e}
 	}
 	return nil
 }
@@ -541,7 +541,7 @@ func (f *File) checkValid(op string) error {
 		return ErrInvalid
 	}
 	if f.fd == badFd {
-		return &PathError{op, f.name, ErrClosed}
+		return &PathError{Op: op, Path: f.name, Err: ErrClosed}
 	}
 	return nil
 }
diff --git a/src/os/file_posix.go b/src/os/file_posix.go
index ae23d22d0a74c19ddbad896f0cd922afe3c1082f..795c547856adb9e3e8215f0175fbaf2ce59abdca 100644
--- a/src/os/file_posix.go
+++ b/src/os/file_posix.go
@@ -81,7 +81,7 @@ func chmod(name string, mode FileMode) error {
 		return syscall.Chmod(longName, syscallMode(mode))
 	})
 	if e != nil {
-		return &PathError{"chmod", name, e}
+		return &PathError{Op: "chmod", Path: name, Err: e}
 	}
 	return nil
 }
@@ -109,7 +109,7 @@ func Chown(name string, uid, gid int) error {
 		return syscall.Chown(name, uid, gid)
 	})
 	if e != nil {
-		return &PathError{"chown", name, e}
+		return &PathError{Op: "chown", Path: name, Err: e}
 	}
 	return nil
 }
@@ -125,7 +125,7 @@ func Lchown(name string, uid, gid int) error {
 		return syscall.Lchown(name, uid, gid)
 	})
 	if e != nil {
-		return &PathError{"lchown", name, e}
+		return &PathError{Op: "lchown", Path: name, Err: e}
 	}
 	return nil
 }
@@ -182,7 +182,7 @@ func Chtimes(name string, atime time.Time, mtime time.Time) error {
 	utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
 	utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
 	if e := syscall.UtimesNano(fixLongPath(name), utimes[0:]); e != nil {
-		return &PathError{"chtimes", name, e}
+		return &PathError{Op: "chtimes", Path: name, Err: e}
 	}
 	return nil
 }
diff --git a/src/os/file_unix.go b/src/os/file_unix.go
index 3cb4ffbf33edcc14af0ef82b5dfb14e2b87bdc7b..0dc7a5a0a295c6e0fcbac619054f3647b05d5cd4 100644
--- a/src/os/file_unix.go
+++ b/src/os/file_unix.go
@@ -215,7 +215,7 @@ func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
 			continue
 		}
 
-		return nil, &PathError{"open", name, e}
+		return nil, &PathError{Op: "open", Path: name, Err: e}
 	}
 
 	// open(2) itself won't handle the sticky bit on *BSD and Solaris
@@ -244,7 +244,7 @@ func (file *file) close() error {
 		if e == poll.ErrFileClosing {
 			e = ErrClosed
 		}
-		err = &PathError{"close", file.name, e}
+		err = &PathError{Op: "close", Path: file.name, Err: e}
 	}
 
 	// no need for a finalizer anymore
@@ -276,7 +276,7 @@ func Truncate(name string, size int64) error {
 		return syscall.Truncate(name, size)
 	})
 	if e != nil {
-		return &PathError{"truncate", name, e}
+		return &PathError{Op: "truncate", Path: name, Err: e}
 	}
 	return nil
 }
@@ -313,7 +313,7 @@ func Remove(name string) error {
 	if e1 != syscall.ENOTDIR {
 		e = e1
 	}
-	return &PathError{"remove", name, e}
+	return &PathError{Op: "remove", Path: name, Err: e}
 }
 
 func tempDir() string {
@@ -372,7 +372,7 @@ func Readlink(name string) (string, error) {
 			continue
 		}
 		if e != nil {
-			return "", &PathError{"readlink", name, e}
+			return "", &PathError{Op: "readlink", Path: name, Err: e}
 		}
 		if n < len {
 			return string(b[0:n]), nil
diff --git a/src/os/file_windows.go b/src/os/file_windows.go
index f744a35023132c2f84e5b4774823bf674220ea43..dfc5fc6ce68656492ba4cf861e6cfffed31c6c54 100644
--- a/src/os/file_windows.go
+++ b/src/os/file_windows.go
@@ -168,7 +168,7 @@ func openDir(name string) (file *File, err error) {
 // openFileNolog is the Windows implementation of OpenFile.
 func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
 	if name == "" {
-		return nil, &PathError{"open", name, syscall.ENOENT}
+		return nil, &PathError{Op: "open", Path: name, Err: syscall.ENOENT}
 	}
 	r, errf := openFile(name, flag, perm)
 	if errf == nil {
@@ -178,11 +178,11 @@ func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
 	if errd == nil {
 		if flag&O_WRONLY != 0 || flag&O_RDWR != 0 {
 			r.Close()
-			return nil, &PathError{"open", name, syscall.EISDIR}
+			return nil, &PathError{Op: "open", Path: name, Err: syscall.EISDIR}
 		}
 		return r, nil
 	}
-	return nil, &PathError{"open", name, errf}
+	return nil, &PathError{Op: "open", Path: name, Err: errf}
 }
 
 func (file *file) close() error {
@@ -198,7 +198,7 @@ func (file *file) close() error {
 		if e == poll.ErrFileClosing {
 			e = ErrClosed
 		}
-		err = &PathError{"close", file.name, e}
+		err = &PathError{Op: "close", Path: file.name, Err: e}
 	}
 
 	// no need for a finalizer anymore
@@ -236,7 +236,7 @@ func Truncate(name string, size int64) error {
 func Remove(name string) error {
 	p, e := syscall.UTF16PtrFromString(fixLongPath(name))
 	if e != nil {
-		return &PathError{"remove", name, e}
+		return &PathError{Op: "remove", Path: name, Err: e}
 	}
 
 	// Go file interface forces us to know whether
@@ -267,7 +267,7 @@ func Remove(name string) error {
 			}
 		}
 	}
-	return &PathError{"remove", name, e}
+	return &PathError{Op: "remove", Path: name, Err: e}
 }
 
 func rename(oldname, newname string) error {
@@ -493,7 +493,7 @@ func readlink(path string) (string, error) {
 func Readlink(name string) (string, error) {
 	s, err := readlink(fixLongPath(name))
 	if err != nil {
-		return "", &PathError{"readlink", name, err}
+		return "", &PathError{Op: "readlink", Path: name, Err: err}
 	}
 	return s, nil
 }
diff --git a/src/os/path.go b/src/os/path.go
index ba43ea352547b9e4018df73c55b2b8d9a6f9bc90..df87887b9be1aa1301cbc5765f5d2e91ae5337f9 100644
--- a/src/os/path.go
+++ b/src/os/path.go
@@ -22,7 +22,7 @@ func MkdirAll(path string, perm FileMode) error {
 		if dir.IsDir() {
 			return nil
 		}
-		return &PathError{"mkdir", path, syscall.ENOTDIR}
+		return &PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR}
 	}
 
 	// Slow path: make sure parent exists and then call Mkdir for path.
diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go
index 37bf1b8f2f6f6114507e4d6f74fde0690dd240a8..c1a1b726aff5d992612d9cb09e61a1c47205c8d8 100644
--- a/src/os/removeall_at.go
+++ b/src/os/removeall_at.go
@@ -22,7 +22,7 @@ func removeAll(path string) error {
 	// The rmdir system call does not permit removing ".",
 	// so we don't permit it either.
 	if endsWithDot(path) {
-		return &PathError{"RemoveAll", path, syscall.EINVAL}
+		return &PathError{Op: "RemoveAll", Path: path, Err: syscall.EINVAL}
 	}
 
 	// Simple case: if Remove works, we're done.
@@ -70,7 +70,7 @@ func removeAllFrom(parent *File, base string) error {
 	// whose contents need to be removed.
 	// Otherwise just return the error.
 	if err != syscall.EISDIR && err != syscall.EPERM && err != syscall.EACCES {
-		return &PathError{"unlinkat", base, err}
+		return &PathError{Op: "unlinkat", Path: base, Err: err}
 	}
 
 	// Is this a directory we need to recurse into?
@@ -80,11 +80,11 @@ func removeAllFrom(parent *File, base string) error {
 		if IsNotExist(statErr) {
 			return nil
 		}
-		return &PathError{"fstatat", base, statErr}
+		return &PathError{Op: "fstatat", Path: base, Err: statErr}
 	}
 	if statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR {
 		// Not a directory; return the error from the unix.Unlinkat.
-		return &PathError{"unlinkat", base, err}
+		return &PathError{Op: "unlinkat", Path: base, Err: err}
 	}
 
 	// Remove the directory's entries.
@@ -99,7 +99,7 @@ func removeAllFrom(parent *File, base string) error {
 			if IsNotExist(err) {
 				return nil
 			}
-			recurseErr = &PathError{"openfdat", base, err}
+			recurseErr = &PathError{Op: "openfdat", Path: base, Err: err}
 			break
 		}
 
@@ -113,7 +113,7 @@ func removeAllFrom(parent *File, base string) error {
 				if IsNotExist(readErr) {
 					return nil
 				}
-				return &PathError{"readdirnames", base, readErr}
+				return &PathError{Op: "readdirnames", Path: base, Err: readErr}
 			}
 
 			respSize = len(names)
@@ -159,7 +159,7 @@ func removeAllFrom(parent *File, base string) error {
 	if recurseErr != nil {
 		return recurseErr
 	}
-	return &PathError{"unlinkat", base, unlinkError}
+	return &PathError{Op: "unlinkat", Path: base, Err: unlinkError}
 }
 
 // openFdAt opens path relative to the directory in fd.
diff --git a/src/os/removeall_noat.go b/src/os/removeall_noat.go
index c1b43e380753e6ea748ade2803fb346688d0f2f8..7c888baaa99049ad75efda35749aaba36b4c27df 100644
--- a/src/os/removeall_noat.go
+++ b/src/os/removeall_noat.go
@@ -23,7 +23,7 @@ func removeAll(path string) error {
 	// so we don't permit it to remain consistent with the
 	// "at" implementation of RemoveAll.
 	if endsWithDot(path) {
-		return &PathError{"RemoveAll", path, syscall.EINVAL}
+		return &PathError{Op: "RemoveAll", Path: path, Err: syscall.EINVAL}
 	}
 
 	// Simple case: if Remove works, we're done.
diff --git a/src/os/stat_plan9.go b/src/os/stat_plan9.go
index 7ac2695df878a03f32ec331372fbd208083a8bb4..57ae6fb0bbdf67c1ca4c49126b1af2b8a45a097e 100644
--- a/src/os/stat_plan9.go
+++ b/src/os/stat_plan9.go
@@ -65,7 +65,7 @@ func dirstat(arg interface{}) (*syscall.Dir, error) {
 		}
 
 		if n < bitSize16 {
-			return nil, &PathError{"stat", name, err}
+			return nil, &PathError{Op: "stat", Path: name, Err: err}
 		}
 
 		// Pull the real size out of the stat message.
@@ -76,7 +76,7 @@ func dirstat(arg interface{}) (*syscall.Dir, error) {
 		if size <= n {
 			d, err := syscall.UnmarshalDir(buf[:n])
 			if err != nil {
-				return nil, &PathError{"stat", name, err}
+				return nil, &PathError{Op: "stat", Path: name, Err: err}
 			}
 			return d, nil
 		}
@@ -87,7 +87,7 @@ func dirstat(arg interface{}) (*syscall.Dir, error) {
 		err = syscall.ErrBadStat
 	}
 
-	return nil, &PathError{"stat", name, err}
+	return nil, &PathError{Op: "stat", Path: name, Err: err}
 }
 
 // statNolog implements Stat for Plan 9.
diff --git a/src/os/stat_unix.go b/src/os/stat_unix.go
index ef74a43758cfa522cad11bb0573b936ee73ddc29..66c356fc620c108738eeb6020207af4149d5202e 100644
--- a/src/os/stat_unix.go
+++ b/src/os/stat_unix.go
@@ -19,7 +19,7 @@ func (f *File) Stat() (FileInfo, error) {
 	var fs fileStat
 	err := f.pfd.Fstat(&fs.sys)
 	if err != nil {
-		return nil, &PathError{"stat", f.name, err}
+		return nil, &PathError{Op: "stat", Path: f.name, Err: err}
 	}
 	fillFileStatFromSys(&fs, f.name)
 	return &fs, nil
@@ -32,7 +32,7 @@ func statNolog(name string) (FileInfo, error) {
 		return syscall.Stat(name, &fs.sys)
 	})
 	if err != nil {
-		return nil, &PathError{"stat", name, err}
+		return nil, &PathError{Op: "stat", Path: name, Err: err}
 	}
 	fillFileStatFromSys(&fs, name)
 	return &fs, nil
@@ -45,7 +45,7 @@ func lstatNolog(name string) (FileInfo, error) {
 		return syscall.Lstat(name, &fs.sys)
 	})
 	if err != nil {
-		return nil, &PathError{"lstat", name, err}
+		return nil, &PathError{Op: "lstat", Path: name, Err: err}
 	}
 	fillFileStatFromSys(&fs, name)
 	return &fs, nil
diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go
index 3e0e0a59ede90e3f002a9b877b535da7cc4da25f..da4c49090e2dce889973143a77ba6507aaddbba0 100644
--- a/src/os/stat_windows.go
+++ b/src/os/stat_windows.go
@@ -27,7 +27,7 @@ func (file *File) Stat() (FileInfo, error) {
 
 	ft, err := file.pfd.GetFileType()
 	if err != nil {
-		return nil, &PathError{"GetFileType", file.name, err}
+		return nil, &PathError{Op: "GetFileType", Path: file.name, Err: err}
 	}
 	switch ft {
 	case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
@@ -45,14 +45,14 @@ func (file *File) Stat() (FileInfo, error) {
 // stat implements both Stat and Lstat of a file.
 func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
 	if len(name) == 0 {
-		return nil, &PathError{funcname, name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
+		return nil, &PathError{Op: funcname, Path: name, Err: syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
 	}
 	if isWindowsNulName(name) {
 		return &devNullStat, nil
 	}
 	namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
 	if err != nil {
-		return nil, &PathError{funcname, name, err}
+		return nil, &PathError{Op: funcname, Path: name, Err: err}
 	}
 
 	// Try GetFileAttributesEx first, because it is faster than CreateFile.
@@ -80,7 +80,7 @@ func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
 		var fd syscall.Win32finddata
 		sh, err := syscall.FindFirstFile(namep, &fd)
 		if err != nil {
-			return nil, &PathError{"FindFirstFile", name, err}
+			return nil, &PathError{Op: "FindFirstFile", Path: name, Err: err}
 		}
 		syscall.FindClose(sh)
 		fs := newFileStatFromWin32finddata(&fd)
@@ -94,7 +94,7 @@ func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
 	h, err := syscall.CreateFile(namep, 0, 0, nil,
 		syscall.OPEN_EXISTING, createFileAttrs, 0)
 	if err != nil {
-		return nil, &PathError{"CreateFile", name, err}
+		return nil, &PathError{Op: "CreateFile", Path: name, Err: err}
 	}
 	defer syscall.CloseHandle(h)
 
diff --git a/src/os/types_windows.go b/src/os/types_windows.go
index 3d1a6674b145881014d1b7a07cb41fe9935a3ea7..59bf5ca38143dca2480b779a39c8a82530a74996 100644
--- a/src/os/types_windows.go
+++ b/src/os/types_windows.go
@@ -45,7 +45,7 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f
 	var d syscall.ByHandleFileInformation
 	err = syscall.GetFileInformationByHandle(h, &d)
 	if err != nil {
-		return nil, &PathError{"GetFileInformationByHandle", path, err}
+		return nil, &PathError{Op: "GetFileInformationByHandle", Path: path, Err: err}
 	}
 
 	var ti windows.FILE_ATTRIBUTE_TAG_INFO
@@ -58,7 +58,7 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f
 			// instance to indicate no symlinks are possible.
 			ti.ReparseTag = 0
 		} else {
-			return nil, &PathError{"GetFileInformationByHandleEx", path, err}
+			return nil, &PathError{Op: "GetFileInformationByHandleEx", Path: path, Err: err}
 		}
 	}
 
@@ -197,7 +197,7 @@ func (fs *fileStat) saveInfoFromPath(path string) error {
 		var err error
 		fs.path, err = syscall.FullPath(fs.path)
 		if err != nil {
-			return &PathError{"FullPath", path, err}
+			return &PathError{Op: "FullPath", Path: path, Err: err}
 		}
 	}
 	fs.name = basename(path)