xfs: account finobt blocks properly in perag reservation
authorBrian Foster <bfoster@redhat.com>
Fri, 12 Jan 2018 22:07:21 +0000 (14:07 -0800)
committerDarrick J. Wong <darrick.wong@oracle.com>
Fri, 12 Jan 2018 22:09:08 +0000 (14:09 -0800)
commitad90bb585c45917b6c1bb01c812fba337e689362
tree69620e7c1714549e6534d33a8a5d37e45e7d6a02
parenta8789a5ae28f69d7f3791a0e74f8c44222f3108b
xfs: account finobt blocks properly in perag reservation

XFS started using the perag metadata reservation pool for free inode
btree blocks in commit 76d771b4cbe33 ("xfs: use per-AG reservations
for the finobt"). To handle backwards compatibility, finobt blocks
are accounted against the pool so long as the full reservation is
available at mount time. Otherwise the ->m_inotbt_nores flag is set
and the filesystem falls back to the traditional per-transaction
finobt reservation.

This commit has two problems:

- finobt blocks are always accounted against the metadata
  reservation on allocation, regardless of ->m_inotbt_nores state
- finobt blocks are never returned to the reservation pool on free

The first problem affects reflink+finobt filesystems where the full
finobt reservation is not available at mount time. finobt blocks are
essentially stolen from the reflink reservation, putting refcountbt
management at risk of allocation failure. The second problem is an
unconditional leak of metadata reservation whenever finobt is
enabled.

Update the finobt block allocation callouts to consider
->m_inotbt_nores and account blocks appropriately. Blocks should be
consistently accounted against the metadata pool when
->m_inotbt_nores is false and otherwise tagged as RESV_NONE.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/libxfs/xfs_ialloc_btree.c