xfs: inode log reservations are still too small
authorDave Chinner <dchinner@redhat.com>
Fri, 7 Mar 2014 05:19:14 +0000 (16:19 +1100)
committerDave Chinner <david@fromorbit.com>
Fri, 7 Mar 2014 05:19:14 +0000 (16:19 +1100)
commitfe4c224aa1ffa4352849ac5f452de7132739bee2
treee1ce69eaee8e3134be309a4ede5f5afd78fb81d4
parenta49935f200e24e95fffcc705014c4b60ad78ff1f
xfs: inode log reservations are still too small

Back in commit 23956703 ("xfs: inode log reservations are too
small"), the reservation size was increased to take into account the
difference in size between the in-memory BMBT block headers and the
on-disk BMDR headers. This solved a transaction overrun when logging
the inode size.

Recently, however, we've seen a number of these same overruns on
kernels with the above fix in it. All of them have been by 4 bytes,
so we must still not be accounting for something correctly.

Through inspection it turns out the above commit didn't take into
account everything it should have. That is, it only accounts for a
single log op_hdr structure, when it can actually require up to four
op_hdrs - one for each region (log iovec) that is formatted. These
regions are the inode log format header, the inode core, and the two
forks that can be held in the literal area of the inode.

This means we are not accounting for 36 bytes of log space that the
transaction can use, and hence when we get inodes in certain formats
with particular fragmentation patterns we can overrun the
transaction. Fix this by adding the correct accounting for log
op_headers in the transaction.

Tested-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_trans_resv.c