mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add equivalents to FMODE_PREAD/PWRITE to VFS2.
This is mostly required for PipeTest_OffsetCalls. The options are DenyPRead/PWrite rather than AllowPRead/PWrite since, in Linux terms, fs/open.c:do_dentry_open sets FMODE_PREAD|FMODE_PWRITE unconditionally (although it allows filesystem implementations of open to unset these flags), so they're set for most FDs; it's usually FDs created outside of open(2) that don't get them, e.g.: - Syscall-created pipes (fs/pipe.c:create_pipe_files => fs/file_table.c:alloc_file_pseudo) - Epoll instances (fs/eventpoll.c:do_epoll_create => fs/anon_inodes.c:anon_inode_getfile => alloc_file_pseudo) - Sockets (net/socket.c:sock_alloc_file => alloc_file_pseudo) This CL adds the flags to epoll instances; a subsequent CL reworks the VFS2 implementation of pipe FDs to be filesystem-independent and adds the flags there, and sockets aren't implemented yet. Updates #1035 PiperOrigin-RevId: 304506434
This commit is contained in:
@@ -99,6 +99,8 @@ func (vfs *VirtualFilesystem) NewEpollInstanceFD() (*FileDescription, error) {
|
||||
interest: make(map[epollInterestKey]*epollInterest),
|
||||
}
|
||||
if err := ep.vfsfd.Init(ep, linux.O_RDWR, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{
|
||||
DenyPRead: true,
|
||||
DenyPWrite: true,
|
||||
UseDentryMetadata: true,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -84,6 +84,13 @@ type FileDescriptionOptions struct {
|
||||
// usually only the case if O_DIRECT would actually have an effect.
|
||||
AllowDirectIO bool
|
||||
|
||||
// If DenyPRead is true, calls to FileDescription.PRead() return ESPIPE.
|
||||
DenyPRead bool
|
||||
|
||||
// If DenyPWrite is true, calls to FileDescription.PWrite() return
|
||||
// ESPIPE.
|
||||
DenyPWrite bool
|
||||
|
||||
// If UseDentryMetadata is true, calls to FileDescription methods that
|
||||
// interact with file and filesystem metadata (Stat, SetStat, StatFS,
|
||||
// Listxattr, Getxattr, Setxattr, Removexattr) are implemented by calling
|
||||
@@ -306,6 +313,7 @@ type FileDescriptionImpl interface {
|
||||
// - If opts.Flags specifies unsupported options, PRead returns EOPNOTSUPP.
|
||||
//
|
||||
// Preconditions: The FileDescription was opened for reading.
|
||||
// FileDescriptionOptions.DenyPRead == false.
|
||||
PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts ReadOptions) (int64, error)
|
||||
|
||||
// Read is similar to PRead, but does not specify an offset.
|
||||
@@ -337,6 +345,7 @@ type FileDescriptionImpl interface {
|
||||
// EOPNOTSUPP.
|
||||
//
|
||||
// Preconditions: The FileDescription was opened for writing.
|
||||
// FileDescriptionOptions.DenyPWrite == false.
|
||||
PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts WriteOptions) (int64, error)
|
||||
|
||||
// Write is similar to PWrite, but does not specify an offset, which is
|
||||
@@ -515,6 +524,9 @@ func (fd *FileDescription) EventUnregister(e *waiter.Entry) {
|
||||
// offset, and returns the number of bytes read. PRead is permitted to return
|
||||
// partial reads with a nil error.
|
||||
func (fd *FileDescription) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts ReadOptions) (int64, error) {
|
||||
if fd.opts.DenyPRead {
|
||||
return 0, syserror.ESPIPE
|
||||
}
|
||||
if !fd.readable {
|
||||
return 0, syserror.EBADF
|
||||
}
|
||||
@@ -533,6 +545,9 @@ func (fd *FileDescription) Read(ctx context.Context, dst usermem.IOSequence, opt
|
||||
// offset, and returns the number of bytes written. PWrite is permitted to
|
||||
// return partial writes with a nil error.
|
||||
func (fd *FileDescription) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts WriteOptions) (int64, error) {
|
||||
if fd.opts.DenyPWrite {
|
||||
return 0, syserror.ESPIPE
|
||||
}
|
||||
if !fd.writable {
|
||||
return 0, syserror.EBADF
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user