Changes since last update:

- Fix a rounding error in the fallocate code
 - Minor code cleanups
 - Make sure to zero memory buffers before formatting metadata blocks
 - Fix a few places where we forgot to log an inode metadata update
 - Remove broken error handling that tried to clean up after a failure
   but still got it wrong
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEUzaAxoMeQq6m2jMV+H93GTRKtOsFAl2eA4EACgkQ+H93GTRK
 tOsosxAAgOgEvFrIZQDnzio+yQ9OysiFWCiiT3b+91f8v1v3MNBXP2EEyLA4zZEK
 TlgaFvNCoTO2Q16r+PKCSDFVBwEw/8t2YEylS6X6/GKBUGc/BDBZ5ROZdzQH3Wng
 a98M7GaQektTUqQuKlv3fHiL1Fucp0FonCG3wiuNw6/vzH6RxxwOTTkd2F67Zkn6
 9N7bRoEPh7d6h1Ah7myf/ONA1f3mGEiFuvyb3/KCZPr1WKDFFflzhUboJnMq8Br5
 N55Bq3uoc4+btS4eVxr3XjEXD1zImBiXq7gcEoCRDZNfv+/2VcaDYRkXQu40NbOI
 psH+1xy9lQvLSSbCm6zI1enpfVAm3qxUVktp9G4i4dKtjJQL7HzuvW7ckdzcRaav
 QKbkTmgGQFFI5yLpNHVN+zs+exdkwG6whNyY3Frt5yNh8bH8yRZxrb7YMzfIkNOl
 8O1Tl0ZFGzJtjggXPhAKCoGz2yz8oO2G2JzejfWvdyrku2heyGLktnm98Uk/Sx0g
 90hHTC8KYfLm8r0PuH+lv5c/AwTDr4prJO2wQkU2ZDCCLxXjNsHa3vuxMDmK6PRV
 Y+ryOP6OcyQkB+BkY3/HOlxjen71Z91hdMFNVajRmVwNuFzHCK3yHhsMitBPDEnx
 PnotQQihRmVKP8hw7/3zPfLoDEwO+hPa19JbqUFLXp7xl/OzF6A=
 =MFMd
 -----END PGP SIGNATURE-----

Merge tag 'xfs-5.4-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Darrick Wong:
 "A couple of small code cleanups and bug fixes for rounding errors,
  metadata logging errors, and an extra layer of safeguards against
  leaking memory contents.

   - Fix a rounding error in the fallocate code

   - Minor code cleanups

   - Make sure to zero memory buffers before formatting metadata blocks

   - Fix a few places where we forgot to log an inode metadata update

   - Remove broken error handling that tried to clean up after a failure
     but still got it wrong"

* tag 'xfs-5.4-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: move local to extent inode logging into bmap helper
  xfs: remove broken error handling on failed attr sf to leaf change
  xfs: log the inode on directory sf to block format change
  xfs: assure zeroed memory buffers for certain kmem allocations
  xfs: removed unused error variable from xchk_refcountbt_rec
  xfs: remove unused flags arg from xfs_get_aghdr_buf()
  xfs: Fix tail rounding in xfs_alloc_file_space()
This commit is contained in:
Linus Torvalds 2019-10-10 11:47:16 -07:00
commit 9e208aa06c
10 changed files with 29 additions and 31 deletions

View File

@ -28,12 +28,11 @@ xfs_get_aghdr_buf(
struct xfs_mount *mp, struct xfs_mount *mp,
xfs_daddr_t blkno, xfs_daddr_t blkno,
size_t numblks, size_t numblks,
int flags,
const struct xfs_buf_ops *ops) const struct xfs_buf_ops *ops)
{ {
struct xfs_buf *bp; struct xfs_buf *bp;
bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags); bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0);
if (!bp) if (!bp)
return NULL; return NULL;
@ -345,7 +344,7 @@ xfs_ag_init_hdr(
{ {
struct xfs_buf *bp; struct xfs_buf *bp;
bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, 0, ops); bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, ops);
if (!bp) if (!bp)
return -ENOMEM; return -ENOMEM;

View File

@ -826,32 +826,17 @@ xfs_attr_shortform_to_leaf(
sf = (xfs_attr_shortform_t *)tmpbuffer; sf = (xfs_attr_shortform_t *)tmpbuffer;
xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK); xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
bp = NULL; bp = NULL;
error = xfs_da_grow_inode(args, &blkno); error = xfs_da_grow_inode(args, &blkno);
if (error) { if (error)
/*
* If we hit an IO error middle of the transaction inside
* grow_inode(), we may have inconsistent data. Bail out.
*/
if (error == -EIO)
goto out;
xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */
memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */
goto out; goto out;
}
ASSERT(blkno == 0); ASSERT(blkno == 0);
error = xfs_attr3_leaf_create(args, blkno, &bp); error = xfs_attr3_leaf_create(args, blkno, &bp);
if (error) { if (error)
/* xfs_attr3_leaf_create may not have instantiated a block */
if (bp && (xfs_da_shrink_inode(args, 0, bp) != 0))
goto out;
xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */
memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */
goto out; goto out;
}
memset((char *)&nargs, 0, sizeof(nargs)); memset((char *)&nargs, 0, sizeof(nargs));
nargs.dp = dp; nargs.dp = dp;

View File

@ -792,6 +792,7 @@ out_root_realloc:
*/ */
void void
xfs_bmap_local_to_extents_empty( xfs_bmap_local_to_extents_empty(
struct xfs_trans *tp,
struct xfs_inode *ip, struct xfs_inode *ip,
int whichfork) int whichfork)
{ {
@ -808,6 +809,7 @@ xfs_bmap_local_to_extents_empty(
ifp->if_u1.if_root = NULL; ifp->if_u1.if_root = NULL;
ifp->if_height = 0; ifp->if_height = 0;
XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
} }
@ -840,7 +842,7 @@ xfs_bmap_local_to_extents(
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
if (!ifp->if_bytes) { if (!ifp->if_bytes) {
xfs_bmap_local_to_extents_empty(ip, whichfork); xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
flags = XFS_ILOG_CORE; flags = XFS_ILOG_CORE;
goto done; goto done;
} }
@ -887,7 +889,7 @@ xfs_bmap_local_to_extents(
/* account for the change in fork size */ /* account for the change in fork size */
xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
xfs_bmap_local_to_extents_empty(ip, whichfork); xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
flags |= XFS_ILOG_CORE; flags |= XFS_ILOG_CORE;
ifp->if_u1.if_root = NULL; ifp->if_u1.if_root = NULL;

View File

@ -182,7 +182,8 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
xfs_filblks_t len); xfs_filblks_t len);
int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version); int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version);
void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
struct xfs_inode *ip, int whichfork);
void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno, void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,
xfs_filblks_t len, const struct xfs_owner_info *oinfo, xfs_filblks_t len, const struct xfs_owner_info *oinfo,
bool skip_discard); bool skip_discard);

View File

@ -1096,7 +1096,7 @@ xfs_dir2_sf_to_block(
memcpy(sfp, oldsfp, ifp->if_bytes); memcpy(sfp, oldsfp, ifp->if_bytes);
xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK); xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK);
xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK); xfs_bmap_local_to_extents_empty(tp, dp, XFS_DATA_FORK);
dp->i_d.di_size = 0; dp->i_d.di_size = 0;
/* /*

View File

@ -341,7 +341,6 @@ xchk_refcountbt_rec(
xfs_extlen_t len; xfs_extlen_t len;
xfs_nlink_t refcount; xfs_nlink_t refcount;
bool has_cowflag; bool has_cowflag;
int error = 0;
bno = be32_to_cpu(rec->refc.rc_startblock); bno = be32_to_cpu(rec->refc.rc_startblock);
len = be32_to_cpu(rec->refc.rc_blockcount); len = be32_to_cpu(rec->refc.rc_blockcount);
@ -366,7 +365,7 @@ xchk_refcountbt_rec(
xchk_refcountbt_xref(bs->sc, bno, len, refcount); xchk_refcountbt_xref(bs->sc, bno, len, refcount);
return error; return 0;
} }
/* Make sure we have as many refc blocks as the rmap says. */ /* Make sure we have as many refc blocks as the rmap says. */

View File

@ -864,6 +864,7 @@ xfs_alloc_file_space(
xfs_filblks_t allocatesize_fsb; xfs_filblks_t allocatesize_fsb;
xfs_extlen_t extsz, temp; xfs_extlen_t extsz, temp;
xfs_fileoff_t startoffset_fsb; xfs_fileoff_t startoffset_fsb;
xfs_fileoff_t endoffset_fsb;
int nimaps; int nimaps;
int quota_flag; int quota_flag;
int rt; int rt;
@ -891,7 +892,8 @@ xfs_alloc_file_space(
imapp = &imaps[0]; imapp = &imaps[0];
nimaps = 1; nimaps = 1;
startoffset_fsb = XFS_B_TO_FSBT(mp, offset); startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
allocatesize_fsb = XFS_B_TO_FSB(mp, count); endoffset_fsb = XFS_B_TO_FSB(mp, offset + count);
allocatesize_fsb = endoffset_fsb - startoffset_fsb;
/* /*
* Allocate file space until done or until there is an error * Allocate file space until done or until there is an error

View File

@ -345,6 +345,15 @@ xfs_buf_allocate_memory(
unsigned short page_count, i; unsigned short page_count, i;
xfs_off_t start, end; xfs_off_t start, end;
int error; int error;
xfs_km_flags_t kmflag_mask = 0;
/*
* assure zeroed buffer for non-read cases.
*/
if (!(flags & XBF_READ)) {
kmflag_mask |= KM_ZERO;
gfp_mask |= __GFP_ZERO;
}
/* /*
* for buffers that are contained within a single page, just allocate * for buffers that are contained within a single page, just allocate
@ -354,7 +363,8 @@ xfs_buf_allocate_memory(
size = BBTOB(bp->b_length); size = BBTOB(bp->b_length);
if (size < PAGE_SIZE) { if (size < PAGE_SIZE) {
int align_mask = xfs_buftarg_dma_alignment(bp->b_target); int align_mask = xfs_buftarg_dma_alignment(bp->b_target);
bp->b_addr = kmem_alloc_io(size, align_mask, KM_NOFS); bp->b_addr = kmem_alloc_io(size, align_mask,
KM_NOFS | kmflag_mask);
if (!bp->b_addr) { if (!bp->b_addr) {
/* low memory - use alloc_page loop instead */ /* low memory - use alloc_page loop instead */
goto use_alloc_page; goto use_alloc_page;

View File

@ -1443,7 +1443,7 @@ xlog_alloc_log(
prev_iclog = iclog; prev_iclog = iclog;
iclog->ic_data = kmem_alloc_io(log->l_iclog_size, align_mask, iclog->ic_data = kmem_alloc_io(log->l_iclog_size, align_mask,
KM_MAYFAIL); KM_MAYFAIL | KM_ZERO);
if (!iclog->ic_data) if (!iclog->ic_data)
goto out_free_iclog; goto out_free_iclog;
#ifdef DEBUG #ifdef DEBUG

View File

@ -127,7 +127,7 @@ xlog_alloc_buffer(
if (nbblks > 1 && log->l_sectBBsize > 1) if (nbblks > 1 && log->l_sectBBsize > 1)
nbblks += log->l_sectBBsize; nbblks += log->l_sectBBsize;
nbblks = round_up(nbblks, log->l_sectBBsize); nbblks = round_up(nbblks, log->l_sectBBsize);
return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL); return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL | KM_ZERO);
} }
/* /*