Do not allowing setting project ID on non-empty directories
We have previously relied on the PROJINHERIT flag for XFS quotas, which causes the ID of the parent directory to be recursively applied to subdirectories under the volume's parent directory. However, PROJINHERIT only applies to directories created after the project ID was first set. Pre-existing directories do not get the project ID if we only set it on the parent. This means that quota enforcement is not complete if we allow quotas to be set on directories that are not empty. We could set recursively but that comes with its own problems; quotas on directories that contain pre-existing files behave strangely. Relevant to https://github.com/containers/podman/issues/25368 but is not a fix for that PR, more of a cleanup to make sure we don't make the same mistake elsewhere. Signed-off-by: Matt Heon <mheon@redhat.com>
This commit is contained in:
parent
3a013da40e
commit
c6bce46c29
|
|
@ -190,7 +190,8 @@ func NewControl(basePath string) (*Control, error) {
|
|||
}
|
||||
|
||||
// SetQuota - assign a unique project id to directory and set the quota limits
|
||||
// for that project id
|
||||
// for that project id.
|
||||
// targetPath must exist, must be a directory, and must be empty.
|
||||
func (q *Control) SetQuota(targetPath string, quota Quota) error {
|
||||
var projectID uint32
|
||||
value, ok := q.quotas.Load(targetPath)
|
||||
|
|
@ -200,10 +201,20 @@ func (q *Control) SetQuota(targetPath string, quota Quota) error {
|
|||
if !ok {
|
||||
projectID = q.nextProjectID
|
||||
|
||||
// The directory we are setting an ID on must be empty, as
|
||||
// the ID will not be propagated to pre-existing subdirectories.
|
||||
dents, err := os.ReadDir(targetPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading directory %s: %w", targetPath, err)
|
||||
}
|
||||
if len(dents) > 0 {
|
||||
return fmt.Errorf("can only set project ID on empty directories, %s is not empty", targetPath)
|
||||
}
|
||||
|
||||
//
|
||||
// assign project id to new container directory
|
||||
//
|
||||
err := setProjectID(targetPath, projectID)
|
||||
err = setProjectID(targetPath, projectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue