max_oversubscription_ratio is used throughout Cinder as the ratio between the total physical capacity and the total virtual capacity (virtual capacity = thin-provisioned capacity). The function caculate_virtual_free_capacity takes a backend and calculates the virtual free capacity by taking *total_capacity* and multiplying it by max_over_subscription_ratio before subtracting the space already provisioned and the space reserved.

Even though max_over_subscription_ratio deals with the *total* virtual/physical capacity, some places in the code treat this differently:

* The Pure Storage volume driver returns the ratio between provisioned space and used (written) space. This is the ratio between currently allocated and written data, not totals available on the array.

* The Kaminario volume driver does the same, although the driver doesn't even report this capability correctly (returns "max_oversubscription_ratio" instead of "max_over_subscription_ratio")

I'm assuming that the drivers are calculating the value wrong (or I don't understand the values they use) because the rest of Cinder itself treats max_over_subscription_ratio as *total* virtual / *total* physical.

There is one other place in Cinder which uses max_over_subscription_ratio in an inconsistent manner: CapacityFilter calculates "adjusted_free_virtual" as "free * max_over_subscription_ratio" where "free" is "free physical capacity". This calculation can never be accurate because the ratio between the free physical space and the free virtual space is not constant. For example:

If max_over_subscription_ratio is 1.2 and the physical capacity of the backend is 1 TB, then the total virtual capacity of the backend is 1.2 TB. If 200 GBs are then allocated *and written*, then "free physical space" will be 800 GB and free virtual space will be 1 TB. In this case "free * max_over_subscription_ratio" (800 * 1.2) will be 960 GB - not 1 TB - so the calculation is incorrect.

The function caculate_virtual_free_capacity is made for the correct calculation, and CapacityFilter should use it.

Fix proposed to branch: master/review.openstack.org/484354

Review: https:/