• Brian Foster's avatar
    xfs: fix off-by-one in inode alloc block reservation calculation · 657f1019
    Brian Foster authored
    The inode chunk allocation transaction reserves inobt_maxlevels-1
    blocks to accommodate a full split of the inode btree. A full split
    requires an allocation for every existing level and a new root
    block, which means inobt_maxlevels is the worst case block
    requirement for a transaction that inserts to the inobt. This can
    lead to a transaction block reservation overrun when tmpfile
    creation allocates an inode chunk and expands the inobt to its
    maximum depth. This problem has been observed in conjunction with
    overlayfs, which makes frequent use of tmpfiles internally.
    
    The existing reservation code goes back as far as the Linux git repo
    history (v2.6.12). It was likely never observed as a problem because
    the traditional file/directory creation transactions also include
    worst case block reservation for directory modifications, which most
    likely is able to make up for a single block deficiency in the inode
    allocation portion of the calculation. tmpfile support is relatively
    more recent (v3.15), less heavily used, and only includes the inode
    allocation block reservation as tmpfiles aren't linked into the
    directory tree on creation.
    
    Fix up the inode alloc block reservation macro and a couple of the
    block allocator minleft parameters that enforce an allocation to
    leave enough free blocks in the AG for a full inobt split.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    657f1019
xfs_trans_space.h 3.7 KB