Simple quotas count extents only from the moment the feature is enabled. Therefore, if we do something like: 1. create subvol S 2. write F in S 3. enable quotas 4. remove F 5. write G in S then after 3. and 4. we would expect the simple quota usage of S to be 0 (putting aside some metadata extents that might be written) and after 5., it should be the size of G plus metadata. Therefore, we need to be able to determine whether a particular quota delta we are processing predates simple quota enablement. To do this, store the transaction id when quotas were enabled. In fs_info for immediate use and in the quota status item to make it recoverable on mount. When we see a delta, check if the generation of the extent item is less than that of quota enablement. If so, we should ignore the delta from this extent.
Showing the changes to include/uapi (1 of 6 files). Show all
Unified · Split
| @@ -1277,6 +1277,15 @@ struct btrfs_qgroup_status_item { · 1276 unmodified lines | |||
| 1277 | * of the scan. It contains a logical address | 1277 | * of the scan. It contains a logical address |
| 1278 | */ | 1278 | */ |
| 1279 | __le64 rescan; | 1279 | __le64 rescan; |
| 1280 | |||
| 1281 | /* | ||
| 1282 | * The generation when quotas were last enabled. Used by simple quotas to | ||
| 1283 | * avoid decrementing when freeing an extent that was written before | ||
| 1284 | * enable. | ||
| 1285 | * | ||
| 1286 | * Set only if flags contain BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE. | ||
| 1287 | */ | ||
| 1288 | __le64 enable_gen; | ||
| 1280 | } __attribute__ ((__packed__)); | 1289 | } __attribute__ ((__packed__)); |
| 1281 | 1290 | ||
| 1282 | struct btrfs_qgroup_info_item { | 1291 | struct btrfs_qgroup_info_item { |