drivers, chown: support chown of hard links

make sure the same inode is not chowned twice.  Track all the inodes
that are chowned and skip the same inode if it is encountered multiple
times.

Closes: https://github.com/containers/storage/issues/1143

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2022-02-21 15:21:07 +01:00
parent e085aa8d0b
commit f59aa7a19f
No known key found for this signature in database
GPG Key ID: 67E38F7A8BA21772
1 changed files with 26 additions and 1 deletions

View File

@ -7,18 +7,27 @@ import (
"errors"
"fmt"
"os"
"sync"
"syscall"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
)
type inode struct {
Dev uint64
Ino uint64
}
type platformChowner struct {
mutex sync.Mutex
inodes map[inode]bool
}
func newLChowner() *platformChowner {
return &platformChowner{}
return &platformChowner{
inodes: make(map[inode]bool),
}
}
func (c *platformChowner) LChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error {
@ -26,6 +35,22 @@ func (c *platformChowner) LChown(path string, info os.FileInfo, toHost, toContai
if !ok {
return nil
}
i := inode{
Dev: uint64(st.Dev),
Ino: uint64(st.Ino),
}
c.mutex.Lock()
_, found := c.inodes[i]
if !found {
c.inodes[i] = true
}
c.mutex.Unlock()
if found {
return nil
}
// Map an on-disk UID/GID pair from host to container
// using the first map, then back to the host using the
// second map. Skip that first step if they're 0, to