switch fsimpl/ from sync/atomic to atomicbitops for 32 bit values

PiperOrigin-RevId: 443535714
This commit is contained in:
Kevin Krakauer
2022-04-21 18:32:04 -07:00
committed by gVisor bot
parent 3b917921d7
commit 9050184c20
49 changed files with 523 additions and 556 deletions
+1 -1
View File
@@ -75,7 +75,7 @@ type connection struct {
// initialized after receiving FUSE_INIT reply.
// Until it's set, suspend sending FUSE requests.
// Use SetInitialized() and IsInitialized() for atomic access.
initialized int32
initialized atomicbitops.Int32
// initializedChan is used to block requests before initialization.
initializedChan chan struct{} `state:".(bool)"`
+4 -6
View File
@@ -15,8 +15,6 @@
package fuse
import (
"sync/atomic"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
@@ -65,13 +63,13 @@ func (conn *connection) SetInitialized() {
// And it prevents the newer tasks from gaining
// unnecessary higher chance to be issued before the blocked one.
atomic.StoreInt32(&(conn.initialized), int32(1))
conn.initialized.Store(1)
}
// IsInitialized atomically check if the connection is initialized.
// pairs with SetInitialized().
// Initialized atomically check if the connection is initialized. pairs with
// SetInitialized().
func (conn *connection) Initialized() bool {
return atomic.LoadInt32(&(conn.initialized)) != 0
return conn.initialized.Load() != 0
}
// InitSend sends a FUSE_INIT request.
+10 -11
View File
@@ -16,7 +16,6 @@ package gofer
import (
"fmt"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
@@ -116,18 +115,18 @@ func (d *dentry) createSyntheticChildLocked(opts *createSyntheticOpts) {
refs: atomicbitops.FromInt64(1), // held by d
fs: d.fs,
ino: d.fs.nextIno(),
mode: uint32(opts.mode),
uid: uint32(opts.kuid),
gid: uint32(opts.kgid),
blockSize: hostarch.PageSize, // arbitrary
mode: atomicbitops.FromUint32(uint32(opts.mode)),
uid: atomicbitops.FromUint32(uint32(opts.kuid)),
gid: atomicbitops.FromUint32(uint32(opts.kgid)),
blockSize: atomicbitops.FromUint32(hostarch.PageSize), // arbitrary
atime: atomicbitops.FromInt64(now),
mtime: atomicbitops.FromInt64(now),
ctime: atomicbitops.FromInt64(now),
btime: atomicbitops.FromInt64(now),
readFD: -1,
writeFD: -1,
mmapFD: -1,
nlink: uint32(2),
readFD: atomicbitops.FromInt32(-1),
writeFD: atomicbitops.FromInt32(-1),
mmapFD: atomicbitops.FromInt32(-1),
nlink: atomicbitops.FromUint32(2),
}
refsvfs2.Register(child)
switch opts.mode.FileType() {
@@ -228,7 +227,7 @@ func (d *dentry) getDirents(ctx context.Context) ([]vfs.Dirent, error) {
},
{
Name: "..",
Type: uint8(atomic.LoadUint32(&parent.mode) >> 12),
Type: uint8(parent.mode.Load() >> 12),
Ino: uint64(parent.ino),
NextOff: 2,
},
@@ -338,7 +337,7 @@ func (d *dentry) getDirents(ctx context.Context) ([]vfs.Dirent, error) {
}
dirents = append(dirents, vfs.Dirent{
Name: child.name,
Type: uint8(atomic.LoadUint32(&child.mode) >> 12),
Type: uint8(child.mode.Load() >> 12),
Ino: uint64(child.ino),
NextOff: int64(len(dirents) + 1),
})
+15 -15
View File
@@ -19,10 +19,10 @@ import (
"math"
"strings"
"sync"
"sync/atomic"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fspath"
@@ -625,7 +625,7 @@ func (fs *filesystem) unlinkAt(ctx context.Context, rp *vfs.ResolvingPath, dir b
// Load child if sticky bit is set because we need to determine whether
// deletion is allowed.
var child *dentry
if atomic.LoadUint32(&parent.mode)&linux.ModeSticky == 0 {
if parent.mode.Load()&linux.ModeSticky == 0 {
var ok bool
child, ok = parent.children[name]
if ok && child == nil {
@@ -821,16 +821,16 @@ func (fs *filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs.
if d.isDir() {
return linuxerr.EPERM
}
gid := auth.KGID(atomic.LoadUint32(&d.gid))
uid := auth.KUID(atomic.LoadUint32(&d.uid))
mode := linux.FileMode(atomic.LoadUint32(&d.mode))
gid := auth.KGID(d.gid.Load())
uid := auth.KUID(d.uid.Load())
mode := linux.FileMode(d.mode.Load())
if err := vfs.MayLink(rp.Credentials(), mode, uid, gid); err != nil {
return err
}
if d.nlink == 0 {
if d.nlink.Load() == 0 {
return linuxerr.ENOENT
}
if d.nlink == math.MaxUint32 {
if d.nlink.Load() == math.MaxUint32 {
return linuxerr.EMLINK
}
if fs.opts.lisaEnabled {
@@ -858,8 +858,8 @@ func (fs *filesystem) MkdirAt(ctx context.Context, rp *vfs.ResolvingPath, opts v
// rather than the caller's and enable setgid.
kgid := creds.EffectiveKGID
mode := opts.Mode
if atomic.LoadUint32(&parent.mode)&linux.S_ISGID != 0 {
kgid = auth.KGID(atomic.LoadUint32(&parent.gid))
if parent.mode.Load()&linux.S_ISGID != 0 {
kgid = auth.KGID(parent.gid.Load())
mode |= linux.S_ISGID
}
var err error
@@ -1130,7 +1130,7 @@ func (d *dentry) open(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.Open
if err := fd.vfsfd.Init(fd, opts.Flags, mnt, &d.vfsd, &vfs.FileDescriptionOptions{}); err != nil {
return nil, err
}
if atomic.LoadInt32(&d.readFD) >= 0 {
if d.readFD.Load() >= 0 {
fsmetric.GoferOpensHost.Increment()
} else {
fsmetric.GoferOpens9P.Increment()
@@ -1280,8 +1280,8 @@ func (d *dentry) createAndOpenChildLocked(ctx context.Context, rp *vfs.Resolving
// If the parent is a setgid directory, use the parent's GID rather
// than the caller's.
kgid := creds.EffectiveKGID
if atomic.LoadUint32(&d.mode)&linux.S_ISGID != 0 {
kgid = auth.KGID(atomic.LoadUint32(&d.gid))
if d.mode.Load()&linux.S_ISGID != 0 {
kgid = auth.KGID(d.gid.Load())
}
var child *dentry
@@ -1357,14 +1357,14 @@ func (d *dentry) createAndOpenChildLocked(ctx context.Context, rp *vfs.Resolving
child.readFile = openP9File
child.readFDLisa = d.fs.clientLisa.NewFD(openLisaFD)
if openHostFD != -1 {
child.readFD = openHostFD
child.mmapFD = openHostFD
child.readFD = atomicbitops.FromInt32(openHostFD)
child.mmapFD = atomicbitops.FromInt32(openHostFD)
}
}
if vfs.MayWriteFileWithOpenFlags(opts.Flags) {
child.writeFile = openP9File
child.writeFDLisa = d.fs.clientLisa.NewFD(openLisaFD)
child.writeFD = openHostFD
child.writeFD = atomicbitops.FromInt32(openHostFD)
}
child.handleMu.Unlock()
}
File diff suppressed because it is too large Load Diff
+11 -12
View File
@@ -18,7 +18,6 @@ import (
"fmt"
"io"
"math"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
@@ -59,10 +58,10 @@ func newRegularFileFD(mnt *vfs.Mount, d *dentry, flags uint32) (*regularFileFD,
}); err != nil {
return nil, err
}
if fd.vfsfd.IsWritable() && (atomic.LoadUint32(&d.mode)&0111 != 0) {
if fd.vfsfd.IsWritable() && (d.mode.Load()&0111 != 0) {
metric.SuspiciousOperationsMetric.Increment("opened_write_execute_file")
}
if atomic.LoadInt32(&d.mmapFD) >= 0 {
if d.mmapFD.Load() >= 0 {
fsmetric.GoferOpensHost.Increment()
} else {
fsmetric.GoferOpens9P.Increment()
@@ -128,7 +127,7 @@ func (fd *regularFileFD) PRead(ctx context.Context, dst usermem.IOSequence, offs
start := fsmetric.StartReadWait()
d := fd.dentry()
defer func() {
if atomic.LoadInt32(&d.readFD) >= 0 {
if d.readFD.Load() >= 0 {
fsmetric.GoferReadsHost.Increment()
fsmetric.FinishReadWait(fsmetric.GoferReadWaitHost, start)
} else {
@@ -286,11 +285,11 @@ func (fd *regularFileFD) pwrite(ctx context.Context, src usermem.IOSequence, off
// As with Linux, writing clears the setuid and setgid bits.
if n > 0 {
oldMode := atomic.LoadUint32(&d.mode)
oldMode := d.mode.Load()
// If setuid or setgid were set, update d.mode and propagate
// changes to the host.
if newMode := vfs.ClearSUIDAndSGID(oldMode); newMode != oldMode {
atomic.StoreUint32(&d.mode, newMode)
d.mode.Store(newMode)
if d.fs.opts.lisaEnabled {
stat := linux.Statx{Mask: linux.STATX_MODE, Mode: uint16(newMode)}
failureMask, failureErr, err := d.controlFDLisa.SetStat(ctx, &stat)
@@ -399,7 +398,7 @@ func (rw *dentryReadWriter) ReadToBlocks(dsts safemem.BlockSeq) (uint64, error)
// dentry.readHandleLocked() without locking dentry.dataMu.
rw.d.handleMu.RLock()
h := rw.d.readHandleLocked()
if (rw.d.mmapFD >= 0 && !rw.d.fs.opts.forcePageCache) || rw.d.fs.opts.interop == InteropModeShared || rw.direct {
if (rw.d.mmapFD.RacyLoad() >= 0 && !rw.d.fs.opts.forcePageCache) || rw.d.fs.opts.interop == InteropModeShared || rw.direct {
n, err := h.readToBlocksAt(rw.ctx, dsts, rw.off)
rw.d.handleMu.RUnlock()
rw.off += n
@@ -519,7 +518,7 @@ func (rw *dentryReadWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, erro
// without locking dentry.dataMu.
rw.d.handleMu.RLock()
h := rw.d.writeHandleLocked()
if (rw.d.mmapFD >= 0 && !rw.d.fs.opts.forcePageCache) || rw.d.fs.opts.interop == InteropModeShared || rw.direct {
if (rw.d.mmapFD.RacyLoad() >= 0 && !rw.d.fs.opts.forcePageCache) || rw.d.fs.opts.interop == InteropModeShared || rw.direct {
n, err := h.writeFromBlocksAt(rw.ctx, srcs, rw.off)
rw.off += n
rw.d.dataMu.Lock()
@@ -720,7 +719,7 @@ func (fd *regularFileFD) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpt
case InteropModeShared:
// All mappings require a host FD to be coherent with other
// filesystem users.
if atomic.LoadInt32(&d.mmapFD) < 0 {
if d.mmapFD.Load() < 0 {
return linuxerr.ENODEV
}
default:
@@ -790,7 +789,7 @@ func (d *dentry) CopyMapping(ctx context.Context, ms memmap.MappingSpace, srcAR,
// Translate implements memmap.Mappable.Translate.
func (d *dentry) Translate(ctx context.Context, required, optional memmap.MappableRange, at hostarch.AccessType) ([]memmap.Translation, error) {
d.handleMu.RLock()
if d.mmapFD >= 0 && !d.fs.opts.forcePageCache {
if d.mmapFD.RacyLoad() >= 0 && !d.fs.opts.forcePageCache {
d.handleMu.RUnlock()
mr := optional
if d.fs.opts.limitHostFDTranslation {
@@ -981,12 +980,12 @@ func (d *dentryPlatformFile) DecRef(fr memmap.FileRange) {
func (d *dentryPlatformFile) MapInternal(fr memmap.FileRange, at hostarch.AccessType) (safemem.BlockSeq, error) {
d.handleMu.RLock()
defer d.handleMu.RUnlock()
return d.hostFileMapper.MapInternal(fr, int(d.mmapFD), at.Write)
return d.hostFileMapper.MapInternal(fr, int(d.mmapFD.RacyLoad()), at.Write)
}
// FD implements memmap.File.FD.
func (d *dentryPlatformFile) FD() int {
d.handleMu.RLock()
defer d.handleMu.RUnlock()
return int(d.mmapFD)
return int(d.mmapFD.RacyLoad())
}
+5 -5
View File
@@ -17,9 +17,9 @@ package gofer
import (
"fmt"
"io"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fdnotifier"
@@ -100,7 +100,7 @@ func (fd *specialFileFD) savePipeData(ctx context.Context) error {
}
}
if len(fd.buf) != 0 {
atomic.StoreUint32(&fd.haveBuf, 1)
fd.haveBuf.Store(1)
}
return nil
}
@@ -149,9 +149,9 @@ func (d *dentry) beforeSave() {
// afterLoad is invoked by stateify.
func (d *dentry) afterLoad() {
d.readFD = -1
d.writeFD = -1
d.mmapFD = -1
d.readFD = atomicbitops.FromInt32(-1)
d.writeFD = atomicbitops.FromInt32(-1)
d.mmapFD = atomicbitops.FromInt32(-1)
if d.refs.Load() != -1 {
refsvfs2.Register(d)
}
+6 -7
View File
@@ -16,10 +16,10 @@ package gofer
import (
"fmt"
"sync/atomic"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fdnotifier"
@@ -74,10 +74,9 @@ type specialFileFD struct {
// If haveBuf is non-zero, this FD represents a pipe, and buf contains data
// read from the pipe from previous calls to specialFileFD.savePipeData().
// haveBuf and buf are protected by bufMu. haveBuf is accessed using atomic
// memory operations.
// haveBuf and buf are protected by bufMu.
bufMu sync.Mutex `state:"nosave"`
haveBuf uint32
haveBuf atomicbitops.Uint32
buf []byte
// If handle.fd >= 0, hostFileMapper caches mappings of handle.fd, and
@@ -119,7 +118,7 @@ func newSpecialFileFD(h handle, mnt *vfs.Mount, d *dentry, flags uint32) (*speci
d.fs.syncMu.Lock()
d.fs.specialFileFDs[fd] = struct{}{}
d.fs.syncMu.Unlock()
if fd.vfsfd.IsWritable() && (atomic.LoadUint32(&d.mode)&0111 != 0) {
if fd.vfsfd.IsWritable() && (d.mode.Load()&0111 != 0) {
metric.SuspiciousOperationsMetric.Increment("opened_write_execute_file")
}
if h.fd >= 0 {
@@ -239,7 +238,7 @@ func (fd *specialFileFD) PRead(ctx context.Context, dst usermem.IOSequence, offs
}
bufN := int64(0)
if atomic.LoadUint32(&fd.haveBuf) != 0 {
if fd.haveBuf.Load() != 0 {
var err error
fd.bufMu.Lock()
if len(fd.buf) != 0 {
@@ -248,7 +247,7 @@ func (fd *specialFileFD) PRead(ctx context.Context, dst usermem.IOSequence, offs
dst = dst.DropFirst(n)
fd.buf = fd.buf[n:]
if len(fd.buf) == 0 {
atomic.StoreUint32(&fd.haveBuf, 0)
fd.haveBuf.Store(0)
fd.buf = nil
}
bufN = int64(n)
+4 -6
View File
@@ -15,8 +15,6 @@
package gofer
import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
@@ -40,7 +38,7 @@ func (d *dentry) touchAtime(mnt *vfs.Mount) {
now := d.fs.clock.Now().Nanoseconds()
d.metadataMu.Lock()
d.atime.Store(now)
atomic.StoreUint32(&d.atimeDirty, 1)
d.atimeDirty.Store(1)
d.metadataMu.Unlock()
mnt.EndWrite()
}
@@ -55,7 +53,7 @@ func (d *dentry) touchAtimeLocked(mnt *vfs.Mount) {
}
now := d.fs.clock.Now().Nanoseconds()
d.atime.Store(now)
atomic.StoreUint32(&d.atimeDirty, 1)
d.atimeDirty.Store(1)
mnt.EndWrite()
}
@@ -77,7 +75,7 @@ func (d *dentry) touchCMtime() {
d.metadataMu.Lock()
d.mtime.Store(now)
d.ctime.Store(now)
atomic.StoreUint32(&d.mtimeDirty, 1)
d.mtimeDirty.Store(1)
d.metadataMu.Unlock()
}
@@ -88,5 +86,5 @@ func (d *dentry) touchCMtimeLocked() {
now := d.fs.clock.Now().Nanoseconds()
d.mtime.Store(now)
d.ctime.Store(now)
atomic.StoreUint32(&d.mtimeDirty, 1)
d.mtimeDirty.Store(1)
}
+20 -18
View File
@@ -19,10 +19,10 @@ package host
import (
"fmt"
"math"
"sync/atomic"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fdnotifier"
@@ -55,23 +55,23 @@ type virtualOwner struct {
// mu protects the fields below and they can be accessed using atomic memory
// operations.
mu sync.Mutex `state:"nosave"`
uid uint32
gid uint32
uid atomicbitops.Uint32
gid atomicbitops.Uint32
// mode is also stored, otherwise setting the host file to `0000` could remove
// access to the file.
mode uint32
mode atomicbitops.Uint32
}
func (v *virtualOwner) atomicUID() uint32 {
return atomic.LoadUint32(&v.uid)
return v.uid.Load()
}
func (v *virtualOwner) atomicGID() uint32 {
return atomic.LoadUint32(&v.gid)
return v.gid.Load()
}
func (v *virtualOwner) atomicMode() uint32 {
return atomic.LoadUint32(&v.mode)
return v.mode.Load()
}
func isEpollable(fd int) bool {
@@ -153,10 +153,9 @@ type inode struct {
// If haveBuf is non-zero, hostFD represents a pipe, and buf contains data
// read from the pipe from previous calls to inode.beforeSave(). haveBuf
// and buf are protected by bufMu. haveBuf is accessed using atomic memory
// operations.
// and buf are protected by bufMu.
bufMu sync.Mutex `state:"nosave"`
haveBuf uint32
haveBuf atomicbitops.Uint32
buf []byte
}
@@ -249,9 +248,9 @@ func NewFD(ctx context.Context, mnt *vfs.Mount, hostFD int, opts *NewFDOptions)
}
if opts.VirtualOwner {
i.virtualOwner.enabled = true
i.virtualOwner.uid = uint32(opts.UID)
i.virtualOwner.gid = uint32(opts.GID)
i.virtualOwner.mode = stat.Mode
i.virtualOwner.uid = atomicbitops.FromUint32(uint32(opts.UID))
i.virtualOwner.gid = atomicbitops.FromUint32(uint32(opts.GID))
i.virtualOwner.mode = atomicbitops.FromUint32(stat.Mode)
}
d := &kernfs.Dentry{}
@@ -521,7 +520,8 @@ func (i *inode) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Cre
if m&linux.STATX_MODE != 0 {
if i.virtualOwner.enabled {
i.virtualOwner.mode = uint32(opts.Stat.Mode)
// We hold i.virtualOwner.mu.
i.virtualOwner.mode = atomicbitops.FromUint32(uint32(opts.Stat.Mode))
} else {
if err := unix.Fchmod(i.hostFD, uint32(s.Mode)); err != nil {
return err
@@ -555,10 +555,12 @@ func (i *inode) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Cre
}
if i.virtualOwner.enabled {
if m&linux.STATX_UID != 0 {
i.virtualOwner.uid = opts.Stat.UID
// We hold i.virtualOwner.mu.
i.virtualOwner.uid = atomicbitops.FromUint32(opts.Stat.UID)
}
if m&linux.STATX_GID != 0 {
i.virtualOwner.gid = opts.Stat.GID
// We hold i.virtualOwner.mu.
i.virtualOwner.gid = atomicbitops.FromUint32(opts.Stat.GID)
}
}
return nil
@@ -757,7 +759,7 @@ func (f *fileDescription) Read(ctx context.Context, dst usermem.IOSequence, opts
}
func (i *inode) readFromBuf(ctx context.Context, dst *usermem.IOSequence) (int64, error) {
if atomic.LoadUint32(&i.haveBuf) == 0 {
if i.haveBuf.Load() == 0 {
return 0, nil
}
i.bufMu.Lock()
@@ -769,7 +771,7 @@ func (i *inode) readFromBuf(ctx context.Context, dst *usermem.IOSequence) (int64
*dst = dst.DropFirst(n)
i.buf = i.buf[n:]
if len(i.buf) == 0 {
atomic.StoreUint32(&i.haveBuf, 0)
i.haveBuf.Store(0)
i.buf = nil
}
return int64(n), err
+1 -2
View File
@@ -17,7 +17,6 @@ package host
import (
"fmt"
"io"
"sync/atomic"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/fdnotifier"
@@ -52,7 +51,7 @@ func (i *inode) beforeSave() {
}
}
if len(i.buf) != 0 {
atomic.StoreUint32(&i.haveBuf, 1)
i.haveBuf.Store(1)
}
}
}
+27 -28
View File
@@ -16,7 +16,6 @@ package kernfs
import (
"fmt"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
@@ -178,11 +177,11 @@ type InodeAttrs struct {
devMajor uint32
devMinor uint32
ino atomicbitops.Uint64
mode uint32
uid uint32
gid uint32
nlink uint32
blockSize uint32
mode atomicbitops.Uint32
uid atomicbitops.Uint32
gid atomicbitops.Uint32
nlink atomicbitops.Uint32
blockSize atomicbitops.Uint32
// Timestamps, all nsecs from the Unix epoch.
atime atomicbitops.Int64
@@ -203,11 +202,11 @@ func (a *InodeAttrs) Init(ctx context.Context, creds *auth.Credentials, devMajor
a.devMajor = devMajor
a.devMinor = devMinor
a.ino.Store(ino)
atomic.StoreUint32(&a.mode, uint32(mode))
atomic.StoreUint32(&a.uid, uint32(creds.EffectiveKUID))
atomic.StoreUint32(&a.gid, uint32(creds.EffectiveKGID))
atomic.StoreUint32(&a.nlink, nlink)
atomic.StoreUint32(&a.blockSize, hostarch.PageSize)
a.mode.Store(uint32(mode))
a.uid.Store(uint32(creds.EffectiveKUID))
a.gid.Store(uint32(creds.EffectiveKGID))
a.nlink.Store(nlink)
a.blockSize.Store(hostarch.PageSize)
now := ktime.NowFromContext(ctx).Nanoseconds()
a.atime.Store(now)
a.mtime.Store(now)
@@ -231,12 +230,12 @@ func (a *InodeAttrs) Ino() uint64 {
// Mode implements Inode.Mode.
func (a *InodeAttrs) Mode() linux.FileMode {
return linux.FileMode(atomic.LoadUint32(&a.mode))
return linux.FileMode(a.mode.Load())
}
// Links returns the link count.
func (a *InodeAttrs) Links() uint32 {
return atomic.LoadUint32(&a.nlink)
return a.nlink.Load()
}
// TouchAtime updates a.atime to the current time.
@@ -270,10 +269,10 @@ func (a *InodeAttrs) Stat(context.Context, *vfs.Filesystem, vfs.StatOptions) (li
stat.DevMinor = a.devMinor
stat.Ino = a.ino.Load()
stat.Mode = uint16(a.Mode())
stat.UID = atomic.LoadUint32(&a.uid)
stat.GID = atomic.LoadUint32(&a.gid)
stat.Nlink = atomic.LoadUint32(&a.nlink)
stat.Blksize = atomic.LoadUint32(&a.blockSize)
stat.UID = a.uid.Load()
stat.GID = a.gid.Load()
stat.Nlink = a.nlink.Load()
stat.Blksize = a.blockSize.Load()
stat.Atime = linux.NsecToStatxTimestamp(a.atime.Load())
stat.Mtime = linux.NsecToStatxTimestamp(a.mtime.Load())
stat.Ctime = linux.NsecToStatxTimestamp(a.ctime.Load())
@@ -296,29 +295,29 @@ func (a *InodeAttrs) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *aut
if opts.Stat.Mask&linux.STATX_SIZE != 0 && a.Mode().IsDir() {
return linuxerr.EISDIR
}
if err := vfs.CheckSetStat(ctx, creds, &opts, a.Mode(), auth.KUID(atomic.LoadUint32(&a.uid)), auth.KGID(atomic.LoadUint32(&a.gid))); err != nil {
if err := vfs.CheckSetStat(ctx, creds, &opts, a.Mode(), auth.KUID(a.uid.Load()), auth.KGID(a.gid.Load())); err != nil {
return err
}
clearSID := false
stat := opts.Stat
if stat.Mask&linux.STATX_UID != 0 {
atomic.StoreUint32(&a.uid, stat.UID)
a.uid.Store(stat.UID)
clearSID = true
}
if stat.Mask&linux.STATX_GID != 0 {
atomic.StoreUint32(&a.gid, stat.GID)
a.gid.Store(stat.GID)
clearSID = true
}
if stat.Mask&linux.STATX_MODE != 0 {
for {
old := atomic.LoadUint32(&a.mode)
old := a.mode.Load()
ft := old & linux.S_IFMT
newMode := ft | uint32(stat.Mode & ^uint16(linux.S_IFMT))
if clearSID {
newMode = vfs.ClearSUIDAndSGID(newMode)
}
if swapped := atomic.CompareAndSwapUint32(&a.mode, old, newMode); swapped {
if swapped := a.mode.CompareAndSwap(old, newMode); swapped {
clearSID = false
break
}
@@ -329,9 +328,9 @@ func (a *InodeAttrs) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *aut
// STATX_MODE.
if clearSID {
for {
old := atomic.LoadUint32(&a.mode)
old := a.mode.Load()
newMode := vfs.ClearSUIDAndSGID(old)
if swapped := atomic.CompareAndSwapUint32(&a.mode, old, newMode); swapped {
if swapped := a.mode.CompareAndSwap(old, newMode); swapped {
break
}
}
@@ -360,21 +359,21 @@ func (a *InodeAttrs) CheckPermissions(_ context.Context, creds *auth.Credentials
creds,
ats,
a.Mode(),
auth.KUID(atomic.LoadUint32(&a.uid)),
auth.KGID(atomic.LoadUint32(&a.gid)),
auth.KUID(a.uid.Load()),
auth.KGID(a.gid.Load()),
)
}
// IncLinks implements Inode.IncLinks.
func (a *InodeAttrs) IncLinks(n uint32) {
if atomic.AddUint32(&a.nlink, n) <= n {
if a.nlink.Add(n) <= n {
panic("InodeLink.IncLinks called with no existing links")
}
}
// DecLinks implements Inode.DecLinks.
func (a *InodeAttrs) DecLinks() {
if nlink := atomic.AddUint32(&a.nlink, ^uint32(0)); nlink == ^uint32(0) {
if nlink := a.nlink.Add(^uint32(0)); nlink == ^uint32(0) {
// Negative overflow
panic("Inode.DecLinks called at 0 links")
}
+6 -7
View File
@@ -57,7 +57,6 @@ package kernfs
import (
"fmt"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
@@ -221,8 +220,8 @@ type Dentry struct {
fs *Filesystem
// flags caches useful information about the dentry from the inode. See the
// dflags* consts above. Must be accessed by atomic ops.
flags uint32
// dflags* consts above.
flags atomicbitops.Uint32
parent *Dentry
name string
@@ -459,10 +458,10 @@ func (d *Dentry) Init(fs *Filesystem, inode Inode) {
d.refs.Store(1)
ftype := inode.Mode().FileType()
if ftype == linux.ModeDirectory {
d.flags |= dflagsIsDir
d.flags = atomicbitops.FromUint32(d.flags.RacyLoad() | dflagsIsDir)
}
if ftype == linux.ModeSymlink {
d.flags |= dflagsIsSymlink
d.flags = atomicbitops.FromUint32(d.flags.RacyLoad() | dflagsIsSymlink)
}
refsvfs2.Register(d)
}
@@ -474,12 +473,12 @@ func (d *Dentry) VFSDentry() *vfs.Dentry {
// isDir checks whether the dentry points to a directory inode.
func (d *Dentry) isDir() bool {
return atomic.LoadUint32(&d.flags)&dflagsIsDir != 0
return d.flags.Load()&dflagsIsDir != 0
}
// isSymlink checks whether the dentry points to a symlink inode.
func (d *Dentry) isSymlink() bool {
return atomic.LoadUint32(&d.flags)&dflagsIsSymlink != 0
return d.flags.Load()&dflagsIsSymlink != 0
}
// InotifyWithParent implements vfs.DentryImpl.InotifyWithParent.
+28 -22
View File
@@ -16,7 +16,6 @@ package overlay
import (
"fmt"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
@@ -29,7 +28,7 @@ import (
)
func (d *dentry) isCopiedUp() bool {
return atomic.LoadUint32(&d.copiedUp) != 0
return d.copiedUp.Load() != 0
}
// copyUpLocked ensures that d exists on the upper layer, i.e. d.upperVD.Ok().
@@ -49,7 +48,7 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
// credentials from context rather an take an explicit creds parameter.
ctx = auth.ContextWithCredentials(ctx, d.fs.creds)
ftype := atomic.LoadUint32(&d.mode) & linux.S_IFMT
ftype := d.mode.Load() & linux.S_IFMT
switch ftype {
case linux.S_IFREG, linux.S_IFDIR, linux.S_IFLNK, linux.S_IFBLK, linux.S_IFCHR:
// Can be copied-up.
@@ -126,7 +125,8 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
defer oldFD.DecRef(ctx)
newFD, err := vfsObj.OpenAt(ctx, d.fs.creds, &newpop, &vfs.OpenOptions{
Flags: linux.O_WRONLY | linux.O_CREAT | linux.O_EXCL,
Mode: linux.FileMode(d.mode &^ linux.S_IFMT),
// d.mode can be read because d.copyMu is locked.
Mode: linux.FileMode(d.mode.RacyLoad() &^ linux.S_IFMT),
})
if err != nil {
return err
@@ -157,9 +157,10 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
}
if err := newFD.SetStat(ctx, vfs.SetStatOptions{
Stat: linux.Statx{
Mask: linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
UID: d.uid,
GID: d.gid,
Mask: linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
// d.uid and d.gid can be read because d.copyMu is locked.
UID: d.uid.RacyLoad(),
GID: d.gid.RacyLoad(),
Atime: oldStat.Atime,
Mtime: oldStat.Mtime,
},
@@ -172,16 +173,18 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
case linux.S_IFDIR:
if err := vfsObj.MkdirAt(ctx, d.fs.creds, &newpop, &vfs.MkdirOptions{
Mode: linux.FileMode(d.mode &^ linux.S_IFMT),
// d.mode can be read because d.copyMu is locked.
Mode: linux.FileMode(d.mode.RacyLoad() &^ linux.S_IFMT),
ForSyntheticMountpoint: forSyntheticMountpoint,
}); err != nil {
return err
}
if err := vfsObj.SetStatAt(ctx, d.fs.creds, &newpop, &vfs.SetStatOptions{
Stat: linux.Statx{
Mask: linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
UID: d.uid,
GID: d.gid,
Mask: linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
// d.uid and d.gid can be read because d.copyMu is locked.
UID: d.uid.RacyLoad(),
GID: d.gid.RacyLoad(),
Atime: oldStat.Atime,
Mtime: oldStat.Mtime,
},
@@ -206,10 +209,11 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
}
if err := vfsObj.SetStatAt(ctx, d.fs.creds, &newpop, &vfs.SetStatOptions{
Stat: linux.Statx{
Mask: linux.STATX_MODE | linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
Mode: uint16(d.mode),
UID: d.uid,
GID: d.gid,
Mask: linux.STATX_MODE | linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
// d.{uid,gid,mode} can be read because d.copyMu is locked.
Mode: uint16(d.mode.RacyLoad()),
UID: d.uid.RacyLoad(),
GID: d.gid.RacyLoad(),
Atime: oldStat.Atime,
Mtime: oldStat.Mtime,
},
@@ -226,7 +230,8 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
case linux.S_IFBLK, linux.S_IFCHR:
if err := vfsObj.MknodAt(ctx, d.fs.creds, &newpop, &vfs.MknodOptions{
Mode: linux.FileMode(d.mode),
// d.mode can be read because d.copyMu is locked.
Mode: linux.FileMode(d.mode.RacyLoad()),
DevMajor: oldStat.RdevMajor,
DevMinor: oldStat.RdevMinor,
}); err != nil {
@@ -234,9 +239,10 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
}
if err := vfsObj.SetStatAt(ctx, d.fs.creds, &newpop, &vfs.SetStatOptions{
Stat: linux.Statx{
Mask: linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
UID: d.uid,
GID: d.gid,
Mask: linux.STATX_UID | linux.STATX_GID | oldStat.Mask&timestampsMask,
// d.uid and d.gid can be read because d.copyMu is locked.
UID: d.uid.RacyLoad(),
GID: d.gid.RacyLoad(),
Atime: oldStat.Atime,
Mtime: oldStat.Mtime,
},
@@ -278,8 +284,8 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
cleanupUndoCopyUp()
return linuxerr.EREMOTE
}
atomic.StoreUint32(&d.devMajor, upperStat.DevMajor)
atomic.StoreUint32(&d.devMinor, upperStat.DevMinor)
d.devMajor.Store(upperStat.DevMajor)
d.devMinor.Store(upperStat.DevMinor)
d.ino.Store(upperStat.Ino)
}
@@ -339,7 +345,7 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
d.lowerMappings.RemoveAll()
}
atomic.StoreUint32(&d.copiedUp, 1)
d.copiedUp.Store(1)
return nil
}
+2 -4
View File
@@ -15,8 +15,6 @@
package overlay
import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
@@ -26,7 +24,7 @@ import (
)
func (d *dentry) isDir() bool {
return atomic.LoadUint32(&d.mode)&linux.S_IFMT == linux.S_IFDIR
return d.mode.Load()&linux.S_IFMT == linux.S_IFDIR
}
// Preconditions:
@@ -168,7 +166,7 @@ func (d *dentry) getDirentsLocked(ctx context.Context) ([]vfs.Dirent, error) {
},
{
Name: "..",
Type: uint8(atomic.LoadUint32(&parent.mode) >> 12),
Type: uint8(parent.mode.Load() >> 12),
Ino: parent.ino.Load(),
NextOff: 2,
},
+14 -14
View File
@@ -17,7 +17,6 @@ package overlay
import (
"fmt"
"strings"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
@@ -272,7 +271,7 @@ func (fs *filesystem) lookupLocked(ctx context.Context, parent *dentry, name str
childVD.IncRef()
if isUpper {
child.upperVD = childVD
child.copiedUp = 1
child.copiedUp = atomicbitops.FromUint32(1)
} else {
child.lowerVDs = append(child.lowerVDs, childVD)
}
@@ -282,11 +281,11 @@ func (fs *filesystem) lookupLocked(ctx context.Context, parent *dentry, name str
} else {
topLookupLayer = lookupLayerLower
}
child.mode = uint32(stat.Mode)
child.uid = stat.UID
child.gid = stat.GID
child.devMajor = stat.DevMajor
child.devMinor = stat.DevMinor
child.mode = atomicbitops.FromUint32(uint32(stat.Mode))
child.uid = atomicbitops.FromUint32(stat.UID)
child.gid = atomicbitops.FromUint32(stat.GID)
child.devMajor = atomicbitops.FromUint32(stat.DevMajor)
child.devMinor = atomicbitops.FromUint32(stat.DevMinor)
child.ino = atomicbitops.FromUint64(stat.Ino)
}
@@ -319,14 +318,15 @@ func (fs *filesystem) lookupLocked(ctx context.Context, parent *dentry, name str
// Device and inode numbers were copied from the topmost layer above. Remap
// the device number to an appropriate overlay-private one.
childDevMinor, err := fs.getPrivateDevMinor(child.devMajor, child.devMinor)
// We can use RacyLoad() because child is still being initialized.
childDevMinor, err := fs.getPrivateDevMinor(child.devMajor.RacyLoad(), child.devMinor.RacyLoad())
if err != nil {
ctx.Infof("overlay.filesystem.lookupLocked: failed to map layer device number (%d, %d) to an overlay-specific device number: %v", child.devMajor, child.devMinor, err)
ctx.Infof("overlay.filesystem.lookupLocked: failed to map layer device number (%d, %d) to an overlay-specific device number: %v", child.devMajor.RacyLoad(), child.devMinor.RacyLoad(), err)
child.destroyLocked(ctx)
return nil, topLookupLayer, err
}
child.devMajor = linux.UNNAMED_MAJOR
child.devMinor = childDevMinor
child.devMajor = atomicbitops.FromUint32(linux.UNNAMED_MAJOR)
child.devMinor = atomicbitops.FromUint32(childDevMinor)
parent.IncRef()
child.parent = parent
@@ -887,7 +887,7 @@ func (d *dentry) openCopiedUp(ctx context.Context, rp *vfs.ResolvingPath, opts *
// Directory FDs open FDs from each layer when directory entries are read,
// so they don't require opening an FD from d.topLayer() up front.
ftype := atomic.LoadUint32(&d.mode) & linux.S_IFMT
ftype := d.mode.Load() & linux.S_IFMT
if ftype == linux.S_IFDIR {
// Can't open directories with O_CREAT.
if opts.Flags&linux.O_CREAT != 0 {
@@ -1440,8 +1440,8 @@ func (fs *filesystem) SetStatAt(ctx context.Context, rp *vfs.ResolvingPath, opts
// Precondition: d.fs.renameMu must be held for reading.
func (d *dentry) setStatLocked(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.SetStatOptions) error {
mode := linux.FileMode(atomic.LoadUint32(&d.mode))
if err := vfs.CheckSetStat(ctx, rp.Credentials(), &opts, mode, auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid))); err != nil {
mode := linux.FileMode(d.mode.Load())
if err := vfs.CheckSetStat(ctx, rp.Credentials(), &opts, mode, auth.KUID(d.uid.Load()), auth.KGID(d.gid.Load())); err != nil {
return err
}
mnt := rp.Mount()
+34 -36
View File
@@ -36,7 +36,6 @@ package overlay
import (
"fmt"
"strings"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
@@ -254,7 +253,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
root.refs = atomicbitops.FromInt64(1)
if fs.opts.UpperRoot.Ok() {
fs.opts.UpperRoot.IncRef()
root.copiedUp = 1
root.copiedUp = atomicbitops.FromUint32(1)
root.upperVD = fs.opts.UpperRoot
}
for _, lowerRoot := range fs.opts.LowerRoots {
@@ -286,10 +285,10 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
fs.vfsfs.DecRef(ctx)
return nil, nil, linuxerr.EINVAL
}
root.mode = uint32(rootStat.Mode)
root.uid = rootStat.UID
root.gid = rootStat.GID
root.devMajor = linux.UNNAMED_MAJOR
root.mode = atomicbitops.FromUint32(uint32(rootStat.Mode))
root.uid = atomicbitops.FromUint32(rootStat.UID)
root.gid = atomicbitops.FromUint32(rootStat.GID)
root.devMajor = atomicbitops.FromUint32(linux.UNNAMED_MAJOR)
rootDevMinor, err := fs.getPrivateDevMinor(rootStat.DevMajor, rootStat.DevMinor)
if err != nil {
ctx.Infof("overlay.FilesystemType.GetFilesystem: failed to get device number for root: %v", err)
@@ -297,7 +296,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
fs.vfsfs.DecRef(ctx)
return nil, nil, err
}
root.devMinor = rootDevMinor
root.devMinor = atomicbitops.FromUint32(rootDevMinor)
root.ino.Store(rootStat.Ino)
return &fs.vfsfs, &root.vfsd, nil
@@ -386,14 +385,14 @@ type dentry struct {
// mode, uid, and gid are the file mode, owner, and group of the file in
// the topmost layer (and therefore the overlay file as well), and are used
// for permission checks on this dentry. These fields are protected by
// copyMu and accessed using atomic memory operations.
mode uint32
uid uint32
gid uint32
// copyMu.
mode atomicbitops.Uint32
uid atomicbitops.Uint32
gid atomicbitops.Uint32
// copiedUp is 1 if this dentry has been copied-up (i.e. upperVD.Ok()) and
// 0 otherwise. copiedUp is accessed using atomic memory operations.
copiedUp uint32
// 0 otherwise.
copiedUp atomicbitops.Uint32
// parent is the dentry corresponding to this dentry's parent directory.
// name is this dentry's name in parent. If this dentry is a filesystem
@@ -426,10 +425,9 @@ type dentry struct {
inlineLowerVDs [1]vfs.VirtualDentry
// devMajor, devMinor, and ino are the device major/minor and inode numbers
// used by this dentry. These fields are protected by copyMu and accessed
// using atomic memory operations.
devMajor uint32
devMinor uint32
// used by this dentry. These fields are protected by copyMu.
devMajor atomicbitops.Uint32
devMinor atomicbitops.Uint32
ino atomicbitops.Uint64
// If this dentry represents a regular file, then:
@@ -459,7 +457,7 @@ type dentry struct {
lowerMappings memmap.MappingSet
dataMu sync.RWMutex `state:"nosave"`
wrappedMappable memmap.Mappable
isMappable uint32
isMappable atomicbitops.Uint32
locks vfs.FileLocks
@@ -688,13 +686,13 @@ func (d *dentry) topLookupLayer() lookupLayer {
}
func (d *dentry) checkPermissions(creds *auth.Credentials, ats vfs.AccessTypes) error {
return vfs.GenericCheckPermissions(creds, ats, linux.FileMode(atomic.LoadUint32(&d.mode)), auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid)))
return vfs.GenericCheckPermissions(creds, ats, linux.FileMode(d.mode.Load()), auth.KUID(d.uid.Load()), auth.KGID(d.gid.Load()))
}
func (d *dentry) checkXattrPermissions(creds *auth.Credentials, name string, ats vfs.AccessTypes) error {
mode := linux.FileMode(atomic.LoadUint32(&d.mode))
kuid := auth.KUID(atomic.LoadUint32(&d.uid))
kgid := auth.KGID(atomic.LoadUint32(&d.gid))
mode := linux.FileMode(d.mode.Load())
kuid := auth.KUID(d.uid.Load())
kgid := auth.KGID(d.gid.Load())
if err := vfs.GenericCheckPermissions(creds, ats, mode, kuid, kgid); err != nil {
return err
}
@@ -716,34 +714,34 @@ func (d *dentry) statInternalTo(ctx context.Context, opts *vfs.StatOptions, stat
// and some of our tests expect this.
stat.Nlink = 2
}
stat.UID = atomic.LoadUint32(&d.uid)
stat.GID = atomic.LoadUint32(&d.gid)
stat.Mode = uint16(atomic.LoadUint32(&d.mode))
stat.UID = d.uid.Load()
stat.GID = d.gid.Load()
stat.Mode = uint16(d.mode.Load())
stat.Ino = d.ino.Load()
stat.DevMajor = atomic.LoadUint32(&d.devMajor)
stat.DevMinor = atomic.LoadUint32(&d.devMinor)
stat.DevMajor = d.devMajor.Load()
stat.DevMinor = d.devMinor.Load()
}
// Preconditions: d.copyMu must be locked for writing.
func (d *dentry) updateAfterSetStatLocked(opts *vfs.SetStatOptions) {
if opts.Stat.Mask&linux.STATX_MODE != 0 {
atomic.StoreUint32(&d.mode, (d.mode&linux.S_IFMT)|uint32(opts.Stat.Mode&^linux.S_IFMT))
d.mode.Store((d.mode.RacyLoad() & linux.S_IFMT) | uint32(opts.Stat.Mode&^linux.S_IFMT))
}
if opts.Stat.Mask&linux.STATX_UID != 0 {
atomic.StoreUint32(&d.uid, opts.Stat.UID)
d.uid.Store(opts.Stat.UID)
}
if opts.Stat.Mask&linux.STATX_GID != 0 {
atomic.StoreUint32(&d.gid, opts.Stat.GID)
d.gid.Store(opts.Stat.GID)
}
}
func (d *dentry) mayDelete(creds *auth.Credentials, child *dentry) error {
return vfs.CheckDeleteSticky(
creds,
linux.FileMode(atomic.LoadUint32(&d.mode)),
auth.KUID(atomic.LoadUint32(&d.uid)),
auth.KUID(atomic.LoadUint32(&child.uid)),
auth.KGID(atomic.LoadUint32(&child.gid)),
linux.FileMode(d.mode.Load()),
auth.KUID(d.uid.Load()),
auth.KUID(child.uid.Load()),
auth.KGID(child.gid.Load()),
)
}
@@ -758,8 +756,8 @@ func (d *dentry) newChildOwnerStat(mode linux.FileMode, creds *auth.Credentials)
// Set GID and possibly the SGID bit if the parent is an SGID directory.
d.copyMu.RLock()
defer d.copyMu.RUnlock()
if atomic.LoadUint32(&d.mode)&linux.ModeSetGID == linux.ModeSetGID {
stat.GID = atomic.LoadUint32(&d.gid)
if d.mode.Load()&linux.ModeSetGID == linux.ModeSetGID {
stat.GID = d.gid.Load()
if stat.Mode&linux.ModeDirectory == linux.ModeDirectory {
stat.Mode = uint16(mode) | linux.ModeSetGID
stat.Mask |= linux.STATX_MODE
+10 -12
View File
@@ -15,8 +15,6 @@
package overlay
import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
@@ -32,11 +30,11 @@ import (
)
func (d *dentry) isRegularFile() bool {
return atomic.LoadUint32(&d.mode)&linux.S_IFMT == linux.S_IFREG
return d.mode.Load()&linux.S_IFMT == linux.S_IFREG
}
func (d *dentry) isSymlink() bool {
return atomic.LoadUint32(&d.mode)&linux.S_IFMT == linux.S_IFLNK
return d.mode.Load()&linux.S_IFMT == linux.S_IFLNK
}
func (d *dentry) readlink(ctx context.Context) (string, error) {
@@ -169,8 +167,8 @@ func (fd *regularFileFD) Allocate(ctx context.Context, mode, offset, length uint
// SetStat implements vfs.FileDescriptionImpl.SetStat.
func (fd *regularFileFD) SetStat(ctx context.Context, opts vfs.SetStatOptions) error {
d := fd.dentry()
mode := linux.FileMode(atomic.LoadUint32(&d.mode))
if err := vfs.CheckSetStat(ctx, auth.CredentialsFromContext(ctx), &opts, mode, auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid))); err != nil {
mode := linux.FileMode(d.mode.Load())
if err := vfs.CheckSetStat(ctx, auth.CredentialsFromContext(ctx), &opts, mode, auth.KUID(d.uid.Load()), auth.KGID(d.gid.Load())); err != nil {
return err
}
mnt := fd.vfsfd.Mount()
@@ -332,7 +330,7 @@ func (fd *regularFileFD) updateSetUserGroupIDs(ctx context.Context, wrappedFD *v
// Writing can clear the setuid and/or setgid bits. We only have to
// check this if something was written and one of those bits was set.
dentry := fd.dentry()
if written == 0 || atomic.LoadUint32(&dentry.mode)&(linux.S_ISUID|linux.S_ISGID) == 0 {
if written == 0 || dentry.mode.Load()&(linux.S_ISUID|linux.S_ISGID) == 0 {
return written, nil
}
stat, err := wrappedFD.Stat(ctx, vfs.StatOptions{Mask: linux.STATX_MODE})
@@ -341,7 +339,7 @@ func (fd *regularFileFD) updateSetUserGroupIDs(ctx context.Context, wrappedFD *v
}
dentry.copyMu.Lock()
defer dentry.copyMu.Unlock()
atomic.StoreUint32(&dentry.mode, uint32(stat.Mode))
dentry.mode.Store(uint32(stat.Mode))
return written, nil
}
@@ -398,13 +396,13 @@ func (fd *regularFileFD) ensureMappable(ctx context.Context, opts *memmap.MMapOp
d := fd.dentry()
// Fast path if we already have a Mappable for the current top layer.
if atomic.LoadUint32(&d.isMappable) != 0 {
if d.isMappable.Load() != 0 {
return nil
}
// Only permit mmap of regular files, since other file types may have
// unpredictable behavior when mmapped (e.g. /dev/zero).
if atomic.LoadUint32(&d.mode)&linux.S_IFMT != linux.S_IFREG {
if d.mode.Load()&linux.S_IFMT != linux.S_IFREG {
return linuxerr.ENODEV
}
@@ -413,7 +411,7 @@ func (fd *regularFileFD) ensureMappable(ctx context.Context, opts *memmap.MMapOp
defer fd.mu.Unlock()
d.copyMu.RLock()
defer d.copyMu.RUnlock()
if atomic.LoadUint32(&d.isMappable) != 0 {
if d.isMappable.Load() != 0 {
return nil
}
wrappedFD, err := fd.currentFDLocked(ctx)
@@ -435,7 +433,7 @@ func (fd *regularFileFD) ensureMappable(ctx context.Context, opts *memmap.MMapOp
defer d.dataMu.Unlock()
if d.wrappedMappable == nil {
d.wrappedMappable = opts.Mappable
atomic.StoreUint32(&d.isMappable, 1)
d.isMappable.Store(1)
}
return nil
}
+4 -4
View File
@@ -17,9 +17,9 @@ package proc
import (
"bytes"
"fmt"
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/hostarch"
@@ -44,14 +44,14 @@ type yamaPtraceScope struct {
kernfs.DynamicBytesFile
// level is the ptrace_scope level.
level *int32
level *atomicbitops.Int32
}
var _ vfs.WritableDynamicBytesSource = (*yamaPtraceScope)(nil)
// Generate implements vfs.DynamicBytesSource.Generate.
func (s *yamaPtraceScope) Generate(ctx context.Context, buf *bytes.Buffer) error {
_, err := fmt.Fprintf(buf, "%d\n", atomic.LoadInt32(s.level))
_, err := fmt.Fprintf(buf, "%d\n", s.level.Load())
return err
}
@@ -79,6 +79,6 @@ func (s *yamaPtraceScope) Write(ctx context.Context, _ *vfs.FileDescription, src
return 0, linuxerr.EINVAL
}
atomic.StoreInt32(s.level, v)
s.level.Store(v)
return n, nil
}
+2 -1
View File
@@ -18,6 +18,7 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
@@ -45,6 +46,6 @@ func (fs *filesystem) newDeviceFile(kuid auth.KUID, kgid auth.KGID, mode linux.F
panic(fmt.Sprintf("invalid DeviceKind: %v", kind))
}
file.inode.init(file, fs, kuid, kgid, mode, parentDir)
file.inode.nlink = 1 // from parent directory
file.inode.nlink = atomicbitops.FromUint32(1) // from parent directory
return &file.inode
}

Some files were not shown because too many files have changed in this diff Show More