Added the O_LARGEFILE flag.
This flag will always be true for gVisor files. PiperOrigin-RevId: 206355963 Change-Id: I2f03d2412e2609042df43b06d1318cba674574d0
This commit is contained in:
parent
be7fcbc558
commit
2793f7ac5f
|
@ -27,3 +27,8 @@ const (
|
|||
F_SETLKW = 7
|
||||
F_SETOWN = 8
|
||||
)
|
||||
|
||||
// Flags for fcntl.
|
||||
const (
|
||||
FD_CLOEXEC = 00000001
|
||||
)
|
||||
|
|
|
@ -23,9 +23,19 @@ import (
|
|||
|
||||
// Constants for open(2).
|
||||
const (
|
||||
O_NONBLOCK = 00004000
|
||||
O_CLOEXEC = 02000000
|
||||
O_PATH = 010000000
|
||||
O_ACCMODE = 00000003
|
||||
O_RDONLY = 00000000
|
||||
O_WRONLY = 00000001
|
||||
O_RDWR = 00000002
|
||||
O_APPEND = 00002000
|
||||
O_NONBLOCK = 00004000
|
||||
O_ASYNC = 00020000
|
||||
O_DIRECT = 00040000
|
||||
O_LARGEFILE = 00100000
|
||||
O_DIRECTORY = 00200000
|
||||
O_CLOEXEC = 02000000
|
||||
O_SYNC = 04010000
|
||||
O_PATH = 010000000
|
||||
)
|
||||
|
||||
// Constants for fstatat(2).
|
||||
|
|
|
@ -45,6 +45,12 @@ type FileFlags struct {
|
|||
|
||||
// Async indicates that this file sends signals on IO events.
|
||||
Async bool
|
||||
|
||||
// LargeFile indicates that this file should be opened even if it has
|
||||
// size greater than linux's off_t. When running in 64-bit mode,
|
||||
// Linux sets this flag for all files. Since gVisor is only compatible
|
||||
// with 64-bit Linux, it also sets this flag for all files.
|
||||
LargeFile bool
|
||||
}
|
||||
|
||||
// SettableFileFlags is a subset of FileFlags above that can be changed
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
package linux
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"gvisor.googlesource.com/gvisor/pkg/abi/linux"
|
||||
"gvisor.googlesource.com/gvisor/pkg/sentry/fs"
|
||||
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel"
|
||||
)
|
||||
|
@ -24,13 +23,13 @@ import (
|
|||
// flagsToPermissions returns a Permissions object from Linux flags.
|
||||
// This includes truncate permission if O_TRUNC is set in the mask.
|
||||
func flagsToPermissions(mask uint) (p fs.PermMask) {
|
||||
switch mask & syscall.O_ACCMODE {
|
||||
case syscall.O_WRONLY:
|
||||
switch mask & linux.O_ACCMODE {
|
||||
case linux.O_WRONLY:
|
||||
p.Write = true
|
||||
case syscall.O_RDWR:
|
||||
case linux.O_RDWR:
|
||||
p.Write = true
|
||||
p.Read = true
|
||||
case syscall.O_RDONLY:
|
||||
case linux.O_RDONLY:
|
||||
p.Read = true
|
||||
}
|
||||
return
|
||||
|
@ -39,7 +38,7 @@ func flagsToPermissions(mask uint) (p fs.PermMask) {
|
|||
// fdFlagsToLinux converts a kernel.FDFlags object to a Linux representation.
|
||||
func fdFlagsToLinux(flags kernel.FDFlags) (mask uint) {
|
||||
if flags.CloseOnExec {
|
||||
mask |= syscall.FD_CLOEXEC
|
||||
mask |= linux.FD_CLOEXEC
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -47,30 +46,33 @@ func fdFlagsToLinux(flags kernel.FDFlags) (mask uint) {
|
|||
// flagsToLinux converts a FileFlags object to a Linux representation.
|
||||
func flagsToLinux(flags fs.FileFlags) (mask uint) {
|
||||
if flags.Direct {
|
||||
mask |= syscall.O_DIRECT
|
||||
mask |= linux.O_DIRECT
|
||||
}
|
||||
if flags.NonBlocking {
|
||||
mask |= syscall.O_NONBLOCK
|
||||
mask |= linux.O_NONBLOCK
|
||||
}
|
||||
if flags.Sync {
|
||||
mask |= syscall.O_SYNC
|
||||
mask |= linux.O_SYNC
|
||||
}
|
||||
if flags.Append {
|
||||
mask |= syscall.O_APPEND
|
||||
mask |= linux.O_APPEND
|
||||
}
|
||||
if flags.Directory {
|
||||
mask |= syscall.O_DIRECTORY
|
||||
mask |= linux.O_DIRECTORY
|
||||
}
|
||||
if flags.Async {
|
||||
mask |= syscall.O_ASYNC
|
||||
mask |= linux.O_ASYNC
|
||||
}
|
||||
if flags.LargeFile {
|
||||
mask |= linux.O_LARGEFILE
|
||||
}
|
||||
switch {
|
||||
case flags.Read && flags.Write:
|
||||
mask |= syscall.O_RDWR
|
||||
mask |= linux.O_RDWR
|
||||
case flags.Write:
|
||||
mask |= syscall.O_WRONLY
|
||||
mask |= linux.O_WRONLY
|
||||
case flags.Read:
|
||||
mask |= syscall.O_RDONLY
|
||||
mask |= linux.O_RDONLY
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -78,23 +80,24 @@ func flagsToLinux(flags fs.FileFlags) (mask uint) {
|
|||
// linuxToFlags converts linux file flags to a FileFlags object.
|
||||
func linuxToFlags(mask uint) (flags fs.FileFlags) {
|
||||
return fs.FileFlags{
|
||||
Direct: mask&syscall.O_DIRECT != 0,
|
||||
Sync: mask&syscall.O_SYNC != 0,
|
||||
NonBlocking: mask&syscall.O_NONBLOCK != 0,
|
||||
Read: (mask & syscall.O_ACCMODE) != syscall.O_WRONLY,
|
||||
Write: (mask & syscall.O_ACCMODE) != syscall.O_RDONLY,
|
||||
Append: mask&syscall.O_APPEND != 0,
|
||||
Directory: mask&syscall.O_DIRECTORY != 0,
|
||||
Async: mask&syscall.O_ASYNC != 0,
|
||||
Direct: mask&linux.O_DIRECT != 0,
|
||||
Sync: mask&linux.O_SYNC != 0,
|
||||
NonBlocking: mask&linux.O_NONBLOCK != 0,
|
||||
Read: (mask & linux.O_ACCMODE) != linux.O_WRONLY,
|
||||
Write: (mask & linux.O_ACCMODE) != linux.O_RDONLY,
|
||||
Append: mask&linux.O_APPEND != 0,
|
||||
Directory: mask&linux.O_DIRECTORY != 0,
|
||||
Async: mask&linux.O_ASYNC != 0,
|
||||
LargeFile: mask&linux.O_LARGEFILE != 0,
|
||||
}
|
||||
}
|
||||
|
||||
// linuxToSettableFlags converts linux file flags to a SettableFileFlags object.
|
||||
func linuxToSettableFlags(mask uint) fs.SettableFileFlags {
|
||||
return fs.SettableFileFlags{
|
||||
Direct: mask&syscall.O_DIRECT != 0,
|
||||
NonBlocking: mask&syscall.O_NONBLOCK != 0,
|
||||
Append: mask&syscall.O_APPEND != 0,
|
||||
Async: mask&syscall.O_ASYNC != 0,
|
||||
Direct: mask&linux.O_DIRECT != 0,
|
||||
NonBlocking: mask&linux.O_NONBLOCK != 0,
|
||||
Append: mask&linux.O_APPEND != 0,
|
||||
Async: mask&linux.O_ASYNC != 0,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,6 +148,8 @@ func openAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint) (fd u
|
|||
}
|
||||
|
||||
fileFlags := linuxToFlags(flags)
|
||||
// Linux always adds the O_LARGEFILE flag when running in 64-bit mode.
|
||||
fileFlags.LargeFile = true
|
||||
if fs.IsDir(d.Inode.StableAttr) {
|
||||
// Don't allow directories to be opened writable.
|
||||
if fileFlags.Write {
|
||||
|
|
Loading…
Reference in New Issue