// LinkAt implements vfs.FilesystemImpl.LinkAt.
LinkAt implements vfs.FilesystemImpl.LinkAt.
// LinkAt implements vfs . FilesystemImpl . LinkAt .
func (fs *filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs.VirtualDentry) error {
	return fs.doCreateAt(ctx, rp, false , func(parentDir *directory, name string) error {
		if rp.Mount() != vd.Mount() {
			return syserror.EXDEV
		}
		d := vd.Dentry().Impl().(*dentry)
		i := d.inode
		if i.isDir() {
			return syserror.EPERM
		}
		if err := vfs.MayLink(auth.CredentialsFromContext(ctx), linux.FileMode(atomic.LoadUint32(&i.mode)), auth.KUID(atomic.LoadUint32(&i.uid)), auth.KGID(atomic.LoadUint32(&i.gid))); err != nil {
			return err
		}
		if i.nlink == 0 {
			return syserror.ENOENT
		}
		if i.nlink == maxLinks {
			return syserror.EMLINK
		}
		i.incLinksLocked()
		i.watches.Notify(ctx, "", linux.IN_ATTRIB, 0, vfs.InodeEvent, false )
		parentDir.insertChildLocked(fs.newDentry(i), name)
		return nil
	})
}
func ( fs * filesystem ) LinkAt ( ctx context . Context , rp * vfs . ResolvingPath , vd vfs . VirtualDentry ) error { return fs . doCreateAt ( ctx , rp , false , func ( parentDir * directory , name string ) error { if rp . Mount ( ) != vd . Mount ( ) { return syserror . EXDEV } d := vd . Dentry ( ) . Impl ( ) . ( * dentry ) i := d . inode if i . isDir ( ) { return syserror . EPERM } if err := vfs . MayLink ( auth . CredentialsFromContext ( ctx ) , linux . FileMode ( atomic . LoadUint32 ( & i . mode ) ) , auth . KUID ( atomic . LoadUint32 ( & i . uid ) ) , auth . KGID ( atomic . LoadUint32 ( & i . gid ) ) ) ; err != nil { return err } if i . nlink == 0 { return syserror . ENOENT } if i . nlink == maxLinks { return syserror . EMLINK } i . incLinksLocked ( ) i . watches . Notify ( ctx , " " , linux . IN_ATTRIB , 0 , vfs . InodeEvent , false ) parentDir . insertChildLocked ( fs . newDentry ( i ) , name ) return nil } ) }
LinkAt implements vfs.FilesystemImpl.LinkAt.
LinkAt implements vfs . FilesystemImpl . LinkAt .
/* dir */ /* unlinked */