mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
[vfs2][gofer] Fix file creation flags sent to gofer.
Fixes php runtime test ext/standard/tests/file/readfile_basic.phpt Fixes #3516 fsgofers only want the access mode in the OpenFlags passed to Create(). If more flags are supplied (like O_APPEND in this case), read/write from that fd will fail with EBADF. See runsc/fsgofer/fsgofer.go:WriteAt() VFS2 was providing more than just access modes. So filtering the flags using p9.OpenFlagsModeMask == linux.O_ACCMODE fixes the issue. Gofer in VFS1 also only extracts the access mode flags while making the create RPC. See pkg/sentry/fs/gofer/path.go:Create() Even in VFS2, when we open a handle, we extract out only the access mode flags + O_TRUNC. See third_party/gvisor/pkg/sentry/fsimpl/gofer/handle.go:openHandle() Added a test for this. PiperOrigin-RevId: 326574829
This commit is contained in:
@@ -1082,10 +1082,8 @@ func (d *dentry) createAndOpenChildLocked(ctx context.Context, rp *vfs.Resolving
|
||||
}
|
||||
creds := rp.Credentials()
|
||||
name := rp.Component()
|
||||
// Filter file creation flags and O_LARGEFILE out; the create RPC already
|
||||
// has the semantics of O_CREAT|O_EXCL, while some servers will choke on
|
||||
// O_LARGEFILE.
|
||||
createFlags := p9.OpenFlags(opts.Flags &^ (vfs.FileCreationFlags | linux.O_LARGEFILE))
|
||||
// We only want the access mode for creating the file.
|
||||
createFlags := p9.OpenFlags(opts.Flags) & p9.OpenFlagsModeMask
|
||||
fdobj, openFile, createQID, _, err := dirfile.create(ctx, name, createFlags, (p9.FileMode)(opts.Mode), (p9.UID)(creds.EffectiveKUID), (p9.GID)(creds.EffectiveKGID))
|
||||
if err != nil {
|
||||
dirfile.close(ctx)
|
||||
|
||||
@@ -147,6 +147,26 @@ TEST_F(OpenTest, WriteOnly) {
|
||||
EXPECT_THAT(write(wo_file.get(), &buf, 1), SyscallSucceedsWithValue(1));
|
||||
}
|
||||
|
||||
TEST_F(OpenTest, CreateWithAppend) {
|
||||
std::string data = "text";
|
||||
std::string new_file = NewTempAbsPath();
|
||||
const FileDescriptor file = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
Open(new_file, O_WRONLY | O_APPEND | O_CREAT, 0666));
|
||||
EXPECT_THAT(write(file.get(), data.c_str(), data.size()),
|
||||
SyscallSucceedsWithValue(data.size()));
|
||||
EXPECT_THAT(lseek(file.get(), 0, SEEK_SET), SyscallSucceeds());
|
||||
EXPECT_THAT(write(file.get(), data.c_str(), data.size()),
|
||||
SyscallSucceedsWithValue(data.size()));
|
||||
|
||||
// Check that the size of the file is correct and that the offset has been
|
||||
// incremented to that size.
|
||||
struct stat s0;
|
||||
EXPECT_THAT(fstat(file.get(), &s0), SyscallSucceeds());
|
||||
EXPECT_EQ(s0.st_size, 2 * data.size());
|
||||
EXPECT_THAT(lseek(file.get(), 0, SEEK_CUR),
|
||||
SyscallSucceedsWithValue(2 * data.size()));
|
||||
}
|
||||
|
||||
TEST_F(OpenTest, ReadWrite) {
|
||||
char buf;
|
||||
const FileDescriptor rw_file =
|
||||
|
||||
Reference in New Issue
Block a user