• Bob Peterson's avatar
    GFS2: rgrp free blocks used incorrectly · f6753df3
    Bob Peterson authored
    Before this patch, several functions in rgrp.c checked the value of
    rgd->rd_free_clone. That does not take into account blocks that were
    reserved by a multi-block reservation. This causes a problem when
    space gets tight in the file system. For example, when function
    gfs2_inplace_reserve checks to see if a rgrp has enough blocks to
    satisfy the request, it can accept a rgrp that it should reject
    because, although there are enough blocks to satisfy the request
    _now_, those blocks may be reserved for another running process.
    
    A second problem with this occurs when we've reserved the remaining
    blocks in an rgrp: function rg_mblk_search() can reject an rgrp
    improperly because it calculates:
    
       u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved;
    
    But rd_reserved includes blocks that the current process just
    reserved in its own call to inplace_reserve. For example, it can
    reserve the last 128 blocks of an rgrp, then reject that same rgrp
    because the above calculates out to free_blocks = 0;
    
    Consequences include, but are not limited to, (1) leaving holes,
    and thus increasing file system fragmentation, and (2) reporting
    file system is full long before it actually is.
    
    This patch introduces a new function, rgd_free, which returns the
    number of clone-free blocks (blocks that are truly free as opposed
    to blocks that are still being used because an unlinked file is
    still open) minus the number of blocks reserved by processes, but
    not counting the blocks we ourselves reserved (because obviously
    we need to allocate them).
    Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
    Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
    f6753df3
rgrp.c 70.5 KB