• bpm@sgi.com's avatar
    xfs: xfs_bmap_add_extent_delay_real should init br_startblock · 24446fc6
    bpm@sgi.com authored
    When filling in the middle of a previous delayed allocation in
    xfs_bmap_add_extent_delay_real, set br_startblock of the new delay
    extent to the right to nullstartblock instead of 0 before inserting
    the extent into the ifork (xfs_iext_insert), rather than setting
    br_startblock afterward.
    
    Adding the extent into the ifork with br_startblock=0 can lead to
    the extent being copied into the btree by xfs_bmap_extent_to_btree
    if we happen to convert from extents format to btree format before
    updating br_startblock with the correct value.  The unexpected
    addition of this delay extent to the btree can cause subsequent
    XFS_WANT_CORRUPTED_GOTO filesystem shutdown in several
    xfs_bmap_add_extent_delay_real cases where we are converting a delay
    extent to real and unexpectedly find an extent already inserted.
    For example:
    
    911         case BMAP_LEFT_FILLING:
    912                 /*
    913                  * Filling in the first part of a previous delayed allocation.
    914                  * The left neighbor is not contiguous.
    915                  */
    916                 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
    917                 xfs_bmbt_set_startoff(ep, new_endoff);
    918                 temp = PREV.br_blockcount - new->br_blockcount;
    919                 xfs_bmbt_set_blockcount(ep, temp);
    920                 xfs_iext_insert(ip, idx, 1, new, state);
    921                 ip->i_df.if_lastex = idx;
    922                 ip->i_d.di_nextents++;
    923                 if (cur == NULL)
    924                         rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
    925                 else {
    926                         rval = XFS_ILOG_CORE;
    927                         if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
    928                                         new->br_startblock, new->br_blockcount,
    929                                         &i)))
    930                                 goto done;
    931                         XFS_WANT_CORRUPTED_GOTO(i == 0, done);
    
    With the bogus extent in the btree we shutdown the filesystem at
    931.  The conversion from extents to btree format happens when the
    number of extents in the inode increases above ip->i_df.if_ext_max.
    xfs_bmap_extent_to_btree copies extents from the ifork into the
    btree, ignoring all delalloc extents which are denoted by
    br_startblock having some value of nullstartblock.
    
    SGI-PV: 1013221
    Signed-off-by: default avatarBen Myers <bpm@sgi.com>
    Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
    Signed-off-by: default avatarAlex Elder <aelder@sgi.com>
    24446fc6
xfs_bmap.c 185 KB