diff --git a/pkg/sentry/fsimpl/gofer/dentry_impl.go b/pkg/sentry/fsimpl/gofer/dentry_impl.go index 0f264245c..a1a62fe1f 100644 --- a/pkg/sentry/fsimpl/gofer/dentry_impl.go +++ b/pkg/sentry/fsimpl/gofer/dentry_impl.go @@ -352,6 +352,7 @@ func (d *dentry) mknod(ctx context.Context, name string, creds *auth.Credentials // Preconditions: // - !d.isSynthetic(). +// - !target.isSynthetic(). // - d.fs.renameMu must be locked. func (d *dentry) link(ctx context.Context, target *dentry, name string) (*dentry, error) { switch dt := d.impl.(type) { diff --git a/pkg/sentry/fsimpl/gofer/directfs_dentry.go b/pkg/sentry/fsimpl/gofer/directfs_dentry.go index 165ea1cc5..6d01ccbb1 100644 --- a/pkg/sentry/fsimpl/gofer/directfs_dentry.go +++ b/pkg/sentry/fsimpl/gofer/directfs_dentry.go @@ -538,6 +538,8 @@ func (d *directfsDentry) link(target *directfsDentry, name string) (*dentry, err } // Note that we don't need to set uid/gid for the new child. This is a hard // link. The original file already has the right owner. + // TODO(gvisor.dev/issue/6739): Hard linked dentries should share the same + // inode fields. return d.getCreatedChild(name, -1 /* uid */, -1 /* gid */, false /* isDir */) } diff --git a/pkg/sentry/fsimpl/gofer/filesystem.go b/pkg/sentry/fsimpl/gofer/filesystem.go index 8b4d0f94c..a625a9639 100644 --- a/pkg/sentry/fsimpl/gofer/filesystem.go +++ b/pkg/sentry/fsimpl/gofer/filesystem.go @@ -809,6 +809,10 @@ func (fs *filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs. if d.nlink.Load() == math.MaxUint32 { return nil, linuxerr.EMLINK } + if d.isSynthetic() { + // TODO(gvisor.dev/issue/6739): Add synthetic file hard link support. + return nil, linuxerr.EOPNOTSUPP + } return parent.link(ctx, d, name) }, nil) diff --git a/pkg/sentry/fsimpl/gofer/lisafs_dentry.go b/pkg/sentry/fsimpl/gofer/lisafs_dentry.go index cc7f63a6e..245002e0e 100644 --- a/pkg/sentry/fsimpl/gofer/lisafs_dentry.go +++ b/pkg/sentry/fsimpl/gofer/lisafs_dentry.go @@ -425,6 +425,8 @@ func (d *lisafsDentry) link(ctx context.Context, target *lisafsDentry, name stri if err != nil { return nil, err } + // TODO(gvisor.dev/issue/6739): Hard linked dentries should share the same + // inode fields. return d.newChildDentry(ctx, &linkInode, name) }