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:
Justine Olshan 2018-07-27 12:26:42 -07:00 committed by Shentubot
parent be7fcbc558
commit 2793f7ac5f
5 changed files with 57 additions and 31 deletions

View File

@ -27,3 +27,8 @@ const (
F_SETLKW = 7
F_SETOWN = 8
)
// Flags for fcntl.
const (
FD_CLOEXEC = 00000001
)

View File

@ -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).

View File

@ -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

View File

@ -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,
}
}

View File

@ -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 {