Error out when attempting to hard link synthetic files in non-synthetic dir.

This is consistent with attempting to hard link a synthetic file in a synthetic
directory (fs.LinkAt() => fs.doCreateAt(..., createInSyntheticDir=nil)), which
should result in error.

Due to #6739, fsimpl/gofer does not support hard links correctly since it does
not have an inode abstraction. All inode fields are embedded in the dentry.
So inode attributes and file data of hard linked files can go out of sync.
In remote_revalidating mode, at least the inode attributes of non-synthetic
files are refreshed on each access. But since synthetic files don't exist on
the remote filesystem, there is no way to sync hard linked synthetic dentries.
We'd have to wait for #6739 to be resolved to add such support. For now
returning EOPNOTSUPP is most consistent.

Fixes #10143.

PiperOrigin-RevId: 615537813
This commit is contained in:
Ayush Ranjan
2024-03-13 14:09:18 -07:00
committed by gVisor bot
parent 73f7d3d3f7
commit f8f12199af
4 changed files with 9 additions and 0 deletions
+1
View File
@@ -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) {
@@ -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 */)
}
+4
View File
@@ -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)
+2
View File
@@ -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)
}