forked from TrueCloudLab/restic
fs: make generic and extended attrs independent of each other
This commit is contained in:
parent
6084848e5a
commit
087f95a298
6 changed files with 37 additions and 32 deletions
|
@ -22,11 +22,8 @@ func nodeFromFileInfo(path string, fi os.FileInfo, ignoreXattrListError bool) (*
|
||||||
return node, err
|
return node, err
|
||||||
}
|
}
|
||||||
|
|
||||||
allowExtended, err := nodeFillGenericAttributes(node, path, &stat)
|
err := nodeFillGenericAttributes(node, path, &stat)
|
||||||
if allowExtended {
|
|
||||||
// Skip processing ExtendedAttributes if allowExtended is false.
|
|
||||||
err = errors.Join(err, nodeFillExtendedAttributes(node, path, ignoreXattrListError))
|
err = errors.Join(err, nodeFillExtendedAttributes(node, path, ignoreXattrListError))
|
||||||
}
|
|
||||||
return node, err
|
return node, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,6 @@ func nodeRestoreGenericAttributes(node *restic.Node, _ string, warn func(msg str
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodeFillGenericAttributes is a no-op on AIX.
|
// nodeFillGenericAttributes is a no-op on AIX.
|
||||||
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) (allowExtended bool, err error) {
|
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) error {
|
||||||
return true, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,6 @@ func nodeRestoreGenericAttributes(node *restic.Node, _ string, warn func(msg str
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodeFillGenericAttributes is a no-op on netbsd.
|
// nodeFillGenericAttributes is a no-op on netbsd.
|
||||||
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) (allowExtended bool, err error) {
|
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) error {
|
||||||
return true, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,6 @@ func nodeRestoreGenericAttributes(node *restic.Node, _ string, warn func(msg str
|
||||||
}
|
}
|
||||||
|
|
||||||
// fillGenericAttributes is a no-op on openbsd.
|
// fillGenericAttributes is a no-op on openbsd.
|
||||||
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) (allowExtended bool, err error) {
|
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) error {
|
||||||
return true, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,28 @@ func nodeRestoreExtendedAttributes(node *restic.Node, path string) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill extended attributes in the node. This also includes the Generic attributes for windows.
|
// fill extended attributes in the node
|
||||||
|
// It also checks if the volume supports extended attributes and stores the result in a map
|
||||||
|
// so that it does not have to be checked again for subsequent calls for paths in the same volume.
|
||||||
func nodeFillExtendedAttributes(node *restic.Node, path string, _ bool) (err error) {
|
func nodeFillExtendedAttributes(node *restic.Node, path string, _ bool) (err error) {
|
||||||
|
if strings.Contains(filepath.Base(path), ":") {
|
||||||
|
// Do not process for Alternate Data Streams in Windows
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// only capture xattrs for file/dir
|
||||||
|
if node.Type != restic.NodeTypeFile && node.Type != restic.NodeTypeDir {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
allowExtended, err := checkAndStoreEASupport(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !allowExtended {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var fileHandle windows.Handle
|
var fileHandle windows.Handle
|
||||||
if fileHandle, err = openHandleForEA(node.Type, path, false); fileHandle == 0 {
|
if fileHandle, err = openHandleForEA(node.Type, path, false); fileHandle == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -316,40 +336,28 @@ func decryptFile(pathPointer *uint16) error {
|
||||||
|
|
||||||
// nodeFillGenericAttributes fills in the generic attributes for windows like File Attributes,
|
// nodeFillGenericAttributes fills in the generic attributes for windows like File Attributes,
|
||||||
// Created time and Security Descriptors.
|
// Created time and Security Descriptors.
|
||||||
// It also checks if the volume supports extended attributes and stores the result in a map
|
func nodeFillGenericAttributes(node *restic.Node, path string, stat *ExtendedFileInfo) error {
|
||||||
// so that it does not have to be checked again for subsequent calls for paths in the same volume.
|
|
||||||
func nodeFillGenericAttributes(node *restic.Node, path string, stat *ExtendedFileInfo) (allowExtended bool, err error) {
|
|
||||||
if strings.Contains(filepath.Base(path), ":") {
|
if strings.Contains(filepath.Base(path), ":") {
|
||||||
// Do not process for Alternate Data Streams in Windows
|
// Do not process for Alternate Data Streams in Windows
|
||||||
// Also do not allow processing of extended attributes for ADS.
|
return nil
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isVolume, err := isVolumePath(path)
|
isVolume, err := isVolumePath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return err
|
||||||
}
|
}
|
||||||
if isVolume {
|
if isVolume {
|
||||||
// Do not process file attributes, created time and sd for windows root volume paths
|
// Do not process file attributes, created time and sd for windows root volume paths
|
||||||
// Security descriptors are not supported for root volume paths.
|
// Security descriptors are not supported for root volume paths.
|
||||||
// Though file attributes and created time are supported for root volume paths,
|
// Though file attributes and created time are supported for root volume paths,
|
||||||
// we ignore them and we do not want to replace them during every restore.
|
// we ignore them and we do not want to replace them during every restore.
|
||||||
allowExtended, err = checkAndStoreEASupport(path)
|
return nil
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return allowExtended, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var sd *[]byte
|
var sd *[]byte
|
||||||
if node.Type == restic.NodeTypeFile || node.Type == restic.NodeTypeDir {
|
if node.Type == restic.NodeTypeFile || node.Type == restic.NodeTypeDir {
|
||||||
// Check EA support and get security descriptor for file/dir only
|
|
||||||
allowExtended, err = checkAndStoreEASupport(path)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if sd, err = getSecurityDescriptor(path); err != nil {
|
if sd, err = getSecurityDescriptor(path); err != nil {
|
||||||
return allowExtended, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +369,7 @@ func nodeFillGenericAttributes(node *restic.Node, path string, stat *ExtendedFil
|
||||||
FileAttributes: &winFI.FileAttributes,
|
FileAttributes: &winFI.FileAttributes,
|
||||||
SecurityDescriptor: sd,
|
SecurityDescriptor: sd,
|
||||||
})
|
})
|
||||||
return allowExtended, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkAndStoreEASupport checks if the volume of the path supports extended attributes and stores the result in a map
|
// checkAndStoreEASupport checks if the volume of the path supports extended attributes and stores the result in a map
|
||||||
|
|
|
@ -71,8 +71,8 @@ func nodeRestoreGenericAttributes(node *restic.Node, _ string, warn func(msg str
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodeFillGenericAttributes is a no-op.
|
// nodeFillGenericAttributes is a no-op.
|
||||||
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) (allowExtended bool, err error) {
|
func nodeFillGenericAttributes(_ *restic.Node, _ string, _ *ExtendedFileInfo) error {
|
||||||
return true, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodeRestoreExtendedAttributes(node *restic.Node, path string) error {
|
func nodeRestoreExtendedAttributes(node *restic.Node, path string) error {
|
||||||
|
|
Loading…
Reference in a new issue