mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add anonymous device number allocation to VFS2.
Note that in VFS2, filesystem device numbers are per-vfs.FilesystemImpl rather than global, avoiding the need for a "registry" type to handle save/restore. (This is more consistent with Linux anyway: compare e.g. mm/shmem.c:shmem_mount() => fs/super.c:mount_nodev() => (indirectly) set_anon_super().) PiperOrigin-RevId: 291425193
This commit is contained in:
@@ -98,3 +98,32 @@ func (vfs *VirtualFilesystem) OpenDeviceSpecialFile(ctx context.Context, mnt *Mo
|
||||
}
|
||||
return rd.dev.Open(ctx, mnt, d, *opts)
|
||||
}
|
||||
|
||||
// GetAnonBlockDevMinor allocates and returns an unused minor device number for
|
||||
// an "anonymous" block device with major number 0.
|
||||
func (vfs *VirtualFilesystem) GetAnonBlockDevMinor() (uint32, error) {
|
||||
vfs.anonBlockDevMinorMu.Lock()
|
||||
defer vfs.anonBlockDevMinorMu.Unlock()
|
||||
minor := vfs.anonBlockDevMinorNext
|
||||
const maxDevMinor = (1 << 20) - 1
|
||||
for minor < maxDevMinor {
|
||||
if _, ok := vfs.anonBlockDevMinor[minor]; !ok {
|
||||
vfs.anonBlockDevMinor[minor] = struct{}{}
|
||||
vfs.anonBlockDevMinorNext = minor + 1
|
||||
return minor, nil
|
||||
}
|
||||
minor++
|
||||
}
|
||||
return 0, syserror.EMFILE
|
||||
}
|
||||
|
||||
// PutAnonBlockDevMinor deallocates a minor device number returned by a
|
||||
// previous call to GetAnonBlockDevMinor.
|
||||
func (vfs *VirtualFilesystem) PutAnonBlockDevMinor(minor uint32) {
|
||||
vfs.anonBlockDevMinorMu.Lock()
|
||||
defer vfs.anonBlockDevMinorMu.Unlock()
|
||||
delete(vfs.anonBlockDevMinor, minor)
|
||||
if minor < vfs.anonBlockDevMinorNext {
|
||||
vfs.anonBlockDevMinorNext = minor
|
||||
}
|
||||
}
|
||||
|
||||
+14
-4
@@ -80,6 +80,14 @@ type VirtualFilesystem struct {
|
||||
devicesMu sync.RWMutex
|
||||
devices map[devTuple]*registeredDevice
|
||||
|
||||
// anonBlockDevMinor contains all allocated anonymous block device minor
|
||||
// numbers. anonBlockDevMinorNext is a lower bound for the smallest
|
||||
// unallocated anonymous block device number. anonBlockDevMinorNext and
|
||||
// anonBlockDevMinor are protected by anonBlockDevMinorMu.
|
||||
anonBlockDevMinorMu sync.Mutex
|
||||
anonBlockDevMinorNext uint32
|
||||
anonBlockDevMinor map[uint32]struct{}
|
||||
|
||||
// fsTypes contains all registered FilesystemTypes. fsTypes is protected by
|
||||
// fsTypesMu.
|
||||
fsTypesMu sync.RWMutex
|
||||
@@ -94,10 +102,12 @@ type VirtualFilesystem struct {
|
||||
// New returns a new VirtualFilesystem with no mounts or FilesystemTypes.
|
||||
func New() *VirtualFilesystem {
|
||||
vfs := &VirtualFilesystem{
|
||||
mountpoints: make(map[*Dentry]map[*Mount]struct{}),
|
||||
devices: make(map[devTuple]*registeredDevice),
|
||||
fsTypes: make(map[string]*registeredFilesystemType),
|
||||
filesystems: make(map[*Filesystem]struct{}),
|
||||
mountpoints: make(map[*Dentry]map[*Mount]struct{}),
|
||||
devices: make(map[devTuple]*registeredDevice),
|
||||
anonBlockDevMinorNext: 1,
|
||||
anonBlockDevMinor: make(map[uint32]struct{}),
|
||||
fsTypes: make(map[string]*registeredFilesystemType),
|
||||
filesystems: make(map[*Filesystem]struct{}),
|
||||
}
|
||||
vfs.mounts.Init()
|
||||
return vfs
|
||||
|
||||
Reference in New Issue
Block a user