mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Do not infer negative entry using lisafs.WalkComponentDoesNotExist.
After 8342c57ae8 ("Split gofer.dentry.dirMu into two mutexes"), the gofer
client allows concurrent walks under a directory dentry. Also creation
operations (like mkdir, symlink, etc) only write lock dentry.opMu for the
parent directory.
This means that when performing a WalkMultiple RPC, the status =
WalkComponentDoesNotExist information is not useful anymore. Lets take an
example, A.WalkMultiple([B, C, D]) => [B inode, C inode] (indicating D does not
exist). The RPC is made with A.opMu read locked. So D can be created
concurrently because that only requires C.opMu write lock. So we can not
create a negative entry for D. D could have been created and evicted from the
dentry tree. So we can't know about its presence on the remote filesystem.
PiperOrigin-RevId: 520960039
This commit is contained in:
@@ -284,8 +284,8 @@ func (d *lisafsDentry) getRemoteChild(ctx context.Context, name string) (*dentry
|
||||
|
||||
// Preconditions:
|
||||
// - fs.renameMu must be locked.
|
||||
// - parent.opMu must be locked.
|
||||
// - parent.isDir().
|
||||
// - d.opMu must be locked.
|
||||
// - d.isDir().
|
||||
// - !rp.Done().
|
||||
//
|
||||
// Postcondition: The returned dentry is already cached appropriately.
|
||||
@@ -303,11 +303,13 @@ func (d *lisafsDentry) getRemoteChildAndWalkPathLocked(ctx context.Context, rp *
|
||||
}
|
||||
names = append(names, name)
|
||||
}
|
||||
status, inodes, err := d.controlFD.WalkMultiple(ctx, names)
|
||||
_, inodes, err := d.controlFD.WalkMultiple(ctx, names)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(inodes) == 0 {
|
||||
// d.opMu is locked. So a new child could not have appeared concurrently.
|
||||
// It should be safe to mark this as a negative entry.
|
||||
d.childrenMu.Lock()
|
||||
defer d.childrenMu.Unlock()
|
||||
d.cacheNegativeLookupLocked(names[0])
|
||||
@@ -371,12 +373,6 @@ func (d *lisafsDentry) getRemoteChildAndWalkPathLocked(ctx context.Context, rp *
|
||||
ret = child
|
||||
}
|
||||
}
|
||||
|
||||
if status == lisafs.WalkComponentDoesNotExist && curParent.isDir() {
|
||||
curParentLock()
|
||||
curParent.cacheNegativeLookupLocked(names[len(inodes)]) // +checklocksforce: locked via curParentLock().
|
||||
curParentUnlock()
|
||||
}
|
||||
return ret, dentryCreationErr
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user