Release the lock after reading all the fields from FileAsync in NotifyEvent.

This CL makes changes to read all the fields from FAsync struct at once to
avoid inconsistent results when FileAsync is changed.

PiperOrigin-RevId: 543528321
This commit is contained in:
Nayana Bidari
2023-06-26 13:41:57 -07:00
committed by gVisor bot
parent 22fc34339b
commit 76a0532368
+20 -17
View File
@@ -88,20 +88,21 @@ type FileAsync struct {
// NotifyEvent implements waiter.EventListener.NotifyEvent.
func (a *FileAsync) NotifyEvent(mask waiter.EventMask) {
a.mu.Lock()
locked := true
defer func() {
if locked {
a.mu.Unlock()
}
}()
if !a.registered {
a.mu.Unlock()
return
}
// Read all the required fields which are lock protected from FileAsync
// and release the lock.
t := a.recipientT
tg := a.recipientTG
creds := a.requester
sig := a.signal
if a.recipientPG != nil {
tg = a.recipientPG.Originator()
}
a.mu.Unlock()
if tg != nil {
t = tg.Leader()
}
@@ -109,13 +110,13 @@ func (a *FileAsync) NotifyEvent(mask waiter.EventMask) {
// No recipient has been registered.
return
}
c := t.Credentials()
tCreds := t.Credentials()
// Logic from sigio_perm in fs/fcntl.c.
permCheck := (a.requester.EffectiveKUID == 0 ||
a.requester.EffectiveKUID == c.SavedKUID ||
a.requester.EffectiveKUID == c.RealKUID ||
a.requester.RealKUID == c.SavedKUID ||
a.requester.RealKUID == c.RealKUID)
permCheck := (creds.EffectiveKUID == 0 ||
creds.EffectiveKUID == tCreds.SavedKUID ||
creds.EffectiveKUID == tCreds.RealKUID ||
creds.RealKUID == tCreds.SavedKUID ||
creds.RealKUID == tCreds.RealKUID)
if !permCheck {
return
}
@@ -123,8 +124,8 @@ func (a *FileAsync) NotifyEvent(mask waiter.EventMask) {
Signo: int32(linux.SIGIO),
Code: linux.SI_KERNEL,
}
if a.signal != 0 {
signalInfo.Signo = int32(a.signal)
if sig != 0 {
signalInfo.Signo = int32(sig)
signalInfo.SetFD(uint32(a.fd))
var band int64
for m, bandCode := range bandTable {
@@ -134,9 +135,11 @@ func (a *FileAsync) NotifyEvent(mask waiter.EventMask) {
}
signalInfo.SetBand(band)
}
a.mu.Unlock()
locked = false
t.SendSignal(signalInfo)
if tg != nil {
t.SendGroupSignal(signalInfo)
} else {
t.SendSignal(signalInfo)
}
}
// Register sets the file which will be monitored for IO events.