summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/devpts
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fsimpl/devpts')
-rw-r--r--pkg/sentry/fsimpl/devpts/devpts.go47
-rw-r--r--pkg/sentry/fsimpl/devpts/devpts_state_autogen.go53
-rw-r--r--pkg/sentry/fsimpl/devpts/master.go5
-rw-r--r--pkg/sentry/fsimpl/devpts/replica.go3
4 files changed, 49 insertions, 59 deletions
diff --git a/pkg/sentry/fsimpl/devpts/devpts.go b/pkg/sentry/fsimpl/devpts/devpts.go
index 903135fae..8e34e26df 100644
--- a/pkg/sentry/fsimpl/devpts/devpts.go
+++ b/pkg/sentry/fsimpl/devpts/devpts.go
@@ -87,7 +87,9 @@ func (fstype FilesystemType) newFilesystem(vfsObj *vfs.VirtualFilesystem, creds
root.InodeAttrs.Init(creds, linux.UNNAMED_MAJOR, devMinor, 1, linux.ModeDirectory|0555)
root.OrderedChildren.Init(kernfs.OrderedChildrenOptions{})
root.EnableLeakCheck()
- root.dentry.Init(root)
+
+ var rootD kernfs.Dentry
+ rootD.Init(&fs.Filesystem, root)
// Construct the pts master inode and dentry. Linux always uses inode
// id 2 for ptmx. See fs/devpts/inode.c:mknod_ptmx.
@@ -95,15 +97,14 @@ func (fstype FilesystemType) newFilesystem(vfsObj *vfs.VirtualFilesystem, creds
root: root,
}
master.InodeAttrs.Init(creds, linux.UNNAMED_MAJOR, devMinor, 2, linux.ModeCharacterDevice|0666)
- master.dentry.Init(master)
// Add the master as a child of the root.
- links := root.OrderedChildren.Populate(&root.dentry, map[string]*kernfs.Dentry{
- "ptmx": &master.dentry,
+ links := root.OrderedChildren.Populate(map[string]kernfs.Inode{
+ "ptmx": master,
})
root.IncLinks(links)
- return fs, &root.dentry, nil
+ return fs, &rootD, nil
}
// Release implements vfs.FilesystemImpl.Release.
@@ -117,24 +118,19 @@ func (fs *filesystem) Release(ctx context.Context) {
// +stateify savable
type rootInode struct {
implStatFS
- kernfs.AlwaysValid
+ kernfs.InodeAlwaysValid
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNotSymlink
+ kernfs.InodeTemporary // This holds no meaning as this inode can't be Looked up and is always valid.
kernfs.OrderedChildren
rootInodeRefs
locks vfs.FileLocks
- // Keep a reference to this inode's dentry.
- dentry kernfs.Dentry
-
// master is the master pty inode. Immutable.
master *masterInode
- // root is the root directory inode for this filesystem. Immutable.
- root *rootInode
-
// mu protects the fields below.
mu sync.Mutex `state:"nosave"`
@@ -173,21 +169,24 @@ func (i *rootInode) allocateTerminal(creds *auth.Credentials) (*Terminal, error)
// Linux always uses pty index + 3 as the inode id. See
// fs/devpts/inode.c:devpts_pty_new().
replica.InodeAttrs.Init(creds, i.InodeAttrs.DevMajor(), i.InodeAttrs.DevMinor(), uint64(idx+3), linux.ModeCharacterDevice|0600)
- replica.dentry.Init(replica)
i.replicas[idx] = replica
return t, nil
}
// masterClose is called when the master end of t is closed.
-func (i *rootInode) masterClose(t *Terminal) {
+func (i *rootInode) masterClose(ctx context.Context, t *Terminal) {
i.mu.Lock()
defer i.mu.Unlock()
// Sanity check that replica with idx exists.
- if _, ok := i.replicas[t.n]; !ok {
+ ri, ok := i.replicas[t.n]
+ if !ok {
panic(fmt.Sprintf("pty with index %d does not exist", t.n))
}
+
+ // Drop the ref on replica inode taken during rootInode.allocateTerminal.
+ ri.DecRef(ctx)
delete(i.replicas, t.n)
}
@@ -203,16 +202,22 @@ func (i *rootInode) Open(ctx context.Context, rp *vfs.ResolvingPath, d *kernfs.D
}
// Lookup implements kernfs.Inode.Lookup.
-func (i *rootInode) Lookup(ctx context.Context, name string) (*kernfs.Dentry, error) {
+func (i *rootInode) Lookup(ctx context.Context, name string) (kernfs.Inode, error) {
+ // Check if a static entry was looked up.
+ if d, err := i.OrderedChildren.Lookup(ctx, name); err == nil {
+ return d, nil
+ }
+
+ // Not a static entry.
idx, err := strconv.ParseUint(name, 10, 32)
if err != nil {
return nil, syserror.ENOENT
}
i.mu.Lock()
defer i.mu.Unlock()
- if si, ok := i.replicas[uint32(idx)]; ok {
- si.dentry.IncRef()
- return &si.dentry, nil
+ if ri, ok := i.replicas[uint32(idx)]; ok {
+ ri.IncRef() // This ref is passed to the dentry upon creation via Init.
+ return ri, nil
}
return nil, syserror.ENOENT
@@ -243,8 +248,8 @@ func (i *rootInode) IterDirents(ctx context.Context, cb vfs.IterDirentsCallback,
}
// DecRef implements kernfs.Inode.DecRef.
-func (i *rootInode) DecRef(context.Context) {
- i.rootInodeRefs.DecRef(i.Destroy)
+func (i *rootInode) DecRef(ctx context.Context) {
+ i.rootInodeRefs.DecRef(func() { i.Destroy(ctx) })
}
// +stateify savable
diff --git a/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go b/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go
index d2c9ffa7d..12bb996cb 100644
--- a/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go
+++ b/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go
@@ -58,16 +58,15 @@ func (i *rootInode) StateTypeName() string {
func (i *rootInode) StateFields() []string {
return []string{
"implStatFS",
- "AlwaysValid",
+ "InodeAlwaysValid",
"InodeAttrs",
"InodeDirectoryNoNewChildren",
"InodeNotSymlink",
+ "InodeTemporary",
"OrderedChildren",
"rootInodeRefs",
"locks",
- "dentry",
"master",
- "root",
"replicas",
"nextIdx",
}
@@ -78,36 +77,34 @@ func (i *rootInode) beforeSave() {}
func (i *rootInode) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.implStatFS)
- stateSinkObject.Save(1, &i.AlwaysValid)
+ stateSinkObject.Save(1, &i.InodeAlwaysValid)
stateSinkObject.Save(2, &i.InodeAttrs)
stateSinkObject.Save(3, &i.InodeDirectoryNoNewChildren)
stateSinkObject.Save(4, &i.InodeNotSymlink)
- stateSinkObject.Save(5, &i.OrderedChildren)
- stateSinkObject.Save(6, &i.rootInodeRefs)
- stateSinkObject.Save(7, &i.locks)
- stateSinkObject.Save(8, &i.dentry)
+ stateSinkObject.Save(5, &i.InodeTemporary)
+ stateSinkObject.Save(6, &i.OrderedChildren)
+ stateSinkObject.Save(7, &i.rootInodeRefs)
+ stateSinkObject.Save(8, &i.locks)
stateSinkObject.Save(9, &i.master)
- stateSinkObject.Save(10, &i.root)
- stateSinkObject.Save(11, &i.replicas)
- stateSinkObject.Save(12, &i.nextIdx)
+ stateSinkObject.Save(10, &i.replicas)
+ stateSinkObject.Save(11, &i.nextIdx)
}
func (i *rootInode) afterLoad() {}
func (i *rootInode) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.implStatFS)
- stateSourceObject.Load(1, &i.AlwaysValid)
+ stateSourceObject.Load(1, &i.InodeAlwaysValid)
stateSourceObject.Load(2, &i.InodeAttrs)
stateSourceObject.Load(3, &i.InodeDirectoryNoNewChildren)
stateSourceObject.Load(4, &i.InodeNotSymlink)
- stateSourceObject.Load(5, &i.OrderedChildren)
- stateSourceObject.Load(6, &i.rootInodeRefs)
- stateSourceObject.Load(7, &i.locks)
- stateSourceObject.Load(8, &i.dentry)
+ stateSourceObject.Load(5, &i.InodeTemporary)
+ stateSourceObject.Load(6, &i.OrderedChildren)
+ stateSourceObject.Load(7, &i.rootInodeRefs)
+ stateSourceObject.Load(8, &i.locks)
stateSourceObject.Load(9, &i.master)
- stateSourceObject.Load(10, &i.root)
- stateSourceObject.Load(11, &i.replicas)
- stateSourceObject.Load(12, &i.nextIdx)
+ stateSourceObject.Load(10, &i.replicas)
+ stateSourceObject.Load(11, &i.nextIdx)
}
func (i *implStatFS) StateTypeName() string {
@@ -220,7 +217,6 @@ func (mi *masterInode) StateFields() []string {
"InodeNotDirectory",
"InodeNotSymlink",
"locks",
- "dentry",
"root",
}
}
@@ -235,8 +231,7 @@ func (mi *masterInode) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(3, &mi.InodeNotDirectory)
stateSinkObject.Save(4, &mi.InodeNotSymlink)
stateSinkObject.Save(5, &mi.locks)
- stateSinkObject.Save(6, &mi.dentry)
- stateSinkObject.Save(7, &mi.root)
+ stateSinkObject.Save(6, &mi.root)
}
func (mi *masterInode) afterLoad() {}
@@ -248,8 +243,7 @@ func (mi *masterInode) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(3, &mi.InodeNotDirectory)
stateSourceObject.Load(4, &mi.InodeNotSymlink)
stateSourceObject.Load(5, &mi.locks)
- stateSourceObject.Load(6, &mi.dentry)
- stateSourceObject.Load(7, &mi.root)
+ stateSourceObject.Load(6, &mi.root)
}
func (mfd *masterFileDescription) StateTypeName() string {
@@ -334,7 +328,6 @@ func (ri *replicaInode) StateFields() []string {
"InodeNotDirectory",
"InodeNotSymlink",
"locks",
- "dentry",
"root",
"t",
}
@@ -350,9 +343,8 @@ func (ri *replicaInode) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(3, &ri.InodeNotDirectory)
stateSinkObject.Save(4, &ri.InodeNotSymlink)
stateSinkObject.Save(5, &ri.locks)
- stateSinkObject.Save(6, &ri.dentry)
- stateSinkObject.Save(7, &ri.root)
- stateSinkObject.Save(8, &ri.t)
+ stateSinkObject.Save(6, &ri.root)
+ stateSinkObject.Save(7, &ri.t)
}
func (ri *replicaInode) afterLoad() {}
@@ -364,9 +356,8 @@ func (ri *replicaInode) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(3, &ri.InodeNotDirectory)
stateSourceObject.Load(4, &ri.InodeNotSymlink)
stateSourceObject.Load(5, &ri.locks)
- stateSourceObject.Load(6, &ri.dentry)
- stateSourceObject.Load(7, &ri.root)
- stateSourceObject.Load(8, &ri.t)
+ stateSourceObject.Load(6, &ri.root)
+ stateSourceObject.Load(7, &ri.t)
}
func (rfd *replicaFileDescription) StateTypeName() string {
diff --git a/pkg/sentry/fsimpl/devpts/master.go b/pkg/sentry/fsimpl/devpts/master.go
index 69c2fe951..fda30fb93 100644
--- a/pkg/sentry/fsimpl/devpts/master.go
+++ b/pkg/sentry/fsimpl/devpts/master.go
@@ -42,9 +42,6 @@ type masterInode struct {
locks vfs.FileLocks
- // Keep a reference to this inode's dentry.
- dentry kernfs.Dentry
-
// root is the devpts root inode.
root *rootInode
}
@@ -103,7 +100,7 @@ var _ vfs.FileDescriptionImpl = (*masterFileDescription)(nil)
// Release implements vfs.FileDescriptionImpl.Release.
func (mfd *masterFileDescription) Release(ctx context.Context) {
- mfd.inode.root.masterClose(mfd.t)
+ mfd.inode.root.masterClose(ctx, mfd.t)
}
// EventRegister implements waiter.Waitable.EventRegister.
diff --git a/pkg/sentry/fsimpl/devpts/replica.go b/pkg/sentry/fsimpl/devpts/replica.go
index 6515c5536..70c68cf0a 100644
--- a/pkg/sentry/fsimpl/devpts/replica.go
+++ b/pkg/sentry/fsimpl/devpts/replica.go
@@ -41,9 +41,6 @@ type replicaInode struct {
locks vfs.FileLocks
- // Keep a reference to this inode's dentry.
- dentry kernfs.Dentry
-
// root is the devpts root inode.
root *rootInode