Rewrite the file/dir chowing to be less intense on the system and use walker function
This commit is contained in:
parent
64df3e168f
commit
ecb2cb05ce
|
@ -463,70 +463,46 @@ func (fs *Filesystem) Rename(from string, to string) error {
|
||||||
return os.Rename(cleanedFrom, cleanedTo)
|
return os.Rename(cleanedFrom, cleanedTo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively iterates over a directory and sets the permissions on all of the
|
// Recursively iterates over a file or directory and sets the permissions on all of the
|
||||||
// underlying files.
|
// underlying files. Iterate over all of the files and directories. If it is a file just
|
||||||
|
// go ahead and perform the chown operation. Otherwise dig deeper into the directory until
|
||||||
|
// we've run out of directories to dig into.
|
||||||
func (fs *Filesystem) Chown(path string) error {
|
func (fs *Filesystem) Chown(path string) error {
|
||||||
cleaned, err := fs.SafePath(path)
|
cleaned, err := fs.SafePath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s, err := os.Stat(cleaned); err != nil {
|
uid := config.Get().System.User.Uid
|
||||||
|
gid := config.Get().System.User.Gid
|
||||||
|
|
||||||
|
// Start by just chowning the initial path that we received.
|
||||||
|
if err := os.Chown(cleaned, uid, gid); err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
} else if !s.IsDir() {
|
|
||||||
return os.Chown(cleaned, config.Get().System.User.Uid, config.Get().System.User.Gid)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs.chownDirectory(cleaned)
|
// If this is not a directory we can now return from the function, there is nothing
|
||||||
}
|
// left that we need to do.
|
||||||
|
if st, _ := os.Stat(cleaned); !st.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate over all of the files and directories. If it is a file just go ahead and perform
|
// If this was a directory, begin walking over its contents recursively and ensure that all
|
||||||
// the chown operation. Otherwise dig deeper into the directory until we've run out of
|
// of the subfiles and directories get their permissions updated as well.
|
||||||
// directories to dig into.
|
return fs.Walk(cleaned, func(path string, f os.FileInfo, err error) error {
|
||||||
func (fs *Filesystem) chownDirectory(path string) error {
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
cleaned, err := fs.SafePath(path)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithStack(err)
|
return fs.handleWalkerError(err, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chown the directory itself.
|
|
||||||
os.Chown(cleaned, config.Get().System.User.Uid, config.Get().System.User.Gid)
|
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(cleaned)
|
|
||||||
if err != nil {
|
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range files {
|
|
||||||
// Do not attempt to chmod a symlink. Go's os.Chown function will affect the symlink
|
// Do not attempt to chmod a symlink. Go's os.Chown function will affect the symlink
|
||||||
// so if it points to a location outside the data directory the user would be able to
|
// so if it points to a location outside the data directory the user would be able to
|
||||||
// (un)intentionally modify that files permissions.
|
// (un)intentionally modify that files permissions.
|
||||||
if f.Mode()&os.ModeSymlink != 0 {
|
if f.Mode()&os.ModeSymlink != 0 {
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := fs.SafeJoin(cleaned, f)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if f.IsDir() {
|
|
||||||
wg.Add(1)
|
|
||||||
|
|
||||||
go func(p string) {
|
|
||||||
defer wg.Done()
|
|
||||||
fs.chownDirectory(p)
|
|
||||||
}(p)
|
|
||||||
} else {
|
|
||||||
os.Chown(p, config.Get().System.User.Uid, config.Get().System.User.Gid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.Chown(path, uid, gid)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copies a given file to the same location and appends a suffix to the file to indicate that
|
// Copies a given file to the same location and appends a suffix to the file to indicate that
|
||||||
|
|
Loading…
Reference in New Issue
Block a user