Skip to content

Commit

Permalink
Merge branch 'xfs-4.10-misc-fixes-1' into for-next
Browse files Browse the repository at this point in the history
  • Loading branch information
dchinner committed Nov 9, 2016
2 parents 8f23d31 + 98efe8a commit 0fc204e
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 122 deletions.
49 changes: 23 additions & 26 deletions fs/xfs/libxfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ xfs_bmap_trace_exlist(
state |= BMAP_ATTRFORK;

ifp = XFS_IFORK_PTR(ip, whichfork);
ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
ASSERT(cnt == xfs_iext_count(ifp));
for (idx = 0; idx < cnt; idx++)
trace_xfs_extlist(ip, idx, whichfork, caller_ip);
}
Expand Down Expand Up @@ -811,7 +811,7 @@ xfs_bmap_extents_to_btree(
XFS_BTREE_LONG_PTRS);

arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
for (cnt = i = 0; i < nextents; i++) {
ep = xfs_iext_get_ext(ifp, i);
if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) {
Expand Down Expand Up @@ -1296,7 +1296,7 @@ xfs_bmap_read_extents(
/*
* Here with bp and block set to the leftmost leaf node in the tree.
*/
room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
room = xfs_iext_count(ifp);
i = 0;
/*
* Loop over all leaf nodes. Copy information to the extent records.
Expand Down Expand Up @@ -1361,7 +1361,7 @@ xfs_bmap_read_extents(
return error;
block = XFS_BUF_TO_BLOCK(bp);
}
ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
ASSERT(i == xfs_iext_count(ifp));
ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
XFS_BMAP_TRACE_EXLIST(ip, i, whichfork);
return 0;
Expand Down Expand Up @@ -1404,7 +1404,7 @@ xfs_bmap_search_multi_extents(
if (lastx > 0) {
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
}
if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
if (lastx < xfs_iext_count(ifp)) {
xfs_bmbt_get_all(ep, gotp);
*eofp = 0;
} else {
Expand Down Expand Up @@ -1497,7 +1497,7 @@ xfs_bmap_first_unused(
(error = xfs_iread_extents(tp, ip, whichfork)))
return error;
lowest = *first_unused;
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
off = xfs_bmbt_get_startoff(ep);
Expand Down Expand Up @@ -1582,7 +1582,7 @@ xfs_bmap_last_extent(
return error;
}

nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
if (nextents == 0) {
*is_empty = 1;
return 0;
Expand Down Expand Up @@ -1735,7 +1735,7 @@ xfs_bmap_add_extent_delay_real(
&bma->ip->i_d.di_nextents);

ASSERT(bma->idx >= 0);
ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
ASSERT(bma->idx <= xfs_iext_count(ifp));
ASSERT(!isnullstartblock(new->br_startblock));
ASSERT(!bma->cur ||
(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
Expand Down Expand Up @@ -1794,7 +1794,7 @@ xfs_bmap_add_extent_delay_real(
* Don't set contiguous if the combined extent would be too large.
* Also check for all-three-contiguous being too large.
*/
if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
if (bma->idx < xfs_iext_count(ifp) - 1) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx + 1), &RIGHT);

Expand Down Expand Up @@ -2300,7 +2300,7 @@ xfs_bmap_add_extent_unwritten_real(
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);

ASSERT(*idx >= 0);
ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
ASSERT(*idx <= xfs_iext_count(ifp));
ASSERT(!isnullstartblock(new->br_startblock));

XFS_STATS_INC(mp, xs_add_exlist);
Expand Down Expand Up @@ -2356,7 +2356,7 @@ xfs_bmap_add_extent_unwritten_real(
* Don't set contiguous if the combined extent would be too large.
* Also check for all-three-contiguous being too large.
*/
if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
if (*idx < xfs_iext_count(&ip->i_df) - 1) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT);
if (isnullstartblock(RIGHT.br_startblock))
Expand Down Expand Up @@ -2836,7 +2836,7 @@ xfs_bmap_add_extent_hole_delay(
* Check and set flags if the current (right) segment exists.
* If it doesn't exist, we're converting the hole at end-of-file.
*/
if (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
if (*idx < xfs_iext_count(ifp)) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right);

Expand Down Expand Up @@ -2966,7 +2966,7 @@ xfs_bmap_add_extent_hole_real(
ifp = XFS_IFORK_PTR(bma->ip, whichfork);

ASSERT(bma->idx >= 0);
ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
ASSERT(bma->idx <= xfs_iext_count(ifp));
ASSERT(!isnullstartblock(new->br_startblock));
ASSERT(!bma->cur ||
!(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
Expand All @@ -2992,7 +2992,7 @@ xfs_bmap_add_extent_hole_real(
* Check and set flags if this segment has a current value.
* Not true if we're inserting into the "hole" at eof.
*/
if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
if (bma->idx < xfs_iext_count(ifp)) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &right);
if (isnullstartblock(right.br_startblock))
Expand Down Expand Up @@ -4221,7 +4221,7 @@ xfs_bmapi_read(
break;

/* Else go on to the next record. */
if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
if (++lastx < xfs_iext_count(ifp))
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
else
eof = 1;
Expand Down Expand Up @@ -4733,7 +4733,7 @@ xfs_bmapi_write(

/* Else go on to the next record. */
bma.prev = bma.got;
if (++bma.idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) {
if (++bma.idx < xfs_iext_count(ifp)) {
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx),
&bma.got);
} else
Expand Down Expand Up @@ -4885,7 +4885,7 @@ xfs_bmap_del_extent_delay(
da_new = 0;

ASSERT(*idx >= 0);
ASSERT(*idx < ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
ASSERT(*idx <= xfs_iext_count(ifp));
ASSERT(del->br_blockcount > 0);
ASSERT(got->br_startoff <= del->br_startoff);
ASSERT(got_endoff >= del_endoff);
Expand Down Expand Up @@ -5016,7 +5016,7 @@ xfs_bmap_del_extent_cow(
got_endoff = got->br_startoff + got->br_blockcount;

ASSERT(*idx >= 0);
ASSERT(*idx < ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
ASSERT(*idx <= xfs_iext_count(ifp));
ASSERT(del->br_blockcount > 0);
ASSERT(got->br_startoff <= del->br_startoff);
ASSERT(got_endoff >= del_endoff);
Expand Down Expand Up @@ -5122,8 +5122,7 @@ xfs_bmap_del_extent(
state |= BMAP_COWFORK;

ifp = XFS_IFORK_PTR(ip, whichfork);
ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
(uint)sizeof(xfs_bmbt_rec_t)));
ASSERT((*idx >= 0) && (*idx < xfs_iext_count(ifp)));
ASSERT(del->br_blockcount > 0);
ep = xfs_iext_get_ext(ifp, *idx);
xfs_bmbt_get_all(ep, &got);
Expand Down Expand Up @@ -5448,7 +5447,6 @@ __xfs_bunmapi(
int logflags; /* transaction logging flags */
xfs_extlen_t mod; /* rt extent offset */
xfs_mount_t *mp; /* mount structure */
xfs_extnum_t nextents; /* number of file extents */
xfs_bmbt_irec_t prev; /* previous extent record */
xfs_fileoff_t start; /* first file offset deleted */
int tmp_logflags; /* partial logging flags */
Expand Down Expand Up @@ -5480,8 +5478,7 @@ __xfs_bunmapi(
if (!(ifp->if_flags & XFS_IFEXTENTS) &&
(error = xfs_iread_extents(tp, ip, whichfork)))
return error;
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
if (nextents == 0) {
if (xfs_iext_count(ifp) == 0) {
*rlen = 0;
return 0;
}
Expand Down Expand Up @@ -5966,7 +5963,7 @@ xfs_bmse_shift_one(

mp = ip->i_mount;
ifp = XFS_IFORK_PTR(ip, whichfork);
total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
total_extents = xfs_iext_count(ifp);

xfs_bmbt_get_all(gotp, &got);

Expand Down Expand Up @@ -6143,7 +6140,7 @@ xfs_bmap_shift_extents(
* are collapsing out, so we cannot use the count of real extents here.
* Instead we have to calculate it from the incore fork.
*/
total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
total_extents = xfs_iext_count(ifp);
if (total_extents == 0) {
*done = 1;
goto del_cursor;
Expand Down Expand Up @@ -6203,7 +6200,7 @@ xfs_bmap_shift_extents(
* count can change. Update the total and grade the next record.
*/
if (direction == SHIFT_LEFT) {
total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
total_extents = xfs_iext_count(ifp);
stop_extent = total_extents;
}

Expand Down
31 changes: 19 additions & 12 deletions fs/xfs/libxfs/xfs_inode_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,13 @@ xfs_idestroy_fork(
}
}

/* Count number of incore extents based on if_bytes */
xfs_extnum_t
xfs_iext_count(struct xfs_ifork *ifp)
{
return ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
}

/*
* Convert in-core extents to on-disk form
*
Expand Down Expand Up @@ -803,7 +810,7 @@ xfs_iextents_copy(
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
ASSERT(ifp->if_bytes > 0);

nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nrecs = xfs_iext_count(ifp);
XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork);
ASSERT(nrecs > 0);

Expand Down Expand Up @@ -941,7 +948,7 @@ xfs_iext_get_ext(
xfs_extnum_t idx) /* index of target extent */
{
ASSERT(idx >= 0);
ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
ASSERT(idx < xfs_iext_count(ifp));

if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) {
return ifp->if_u1.if_ext_irec->er_extbuf;
Expand Down Expand Up @@ -1017,7 +1024,7 @@ xfs_iext_add(
int new_size; /* size of extents after adding */
xfs_extnum_t nextents; /* number of extents in file */

nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
ASSERT((idx >= 0) && (idx <= nextents));
byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
new_size = ifp->if_bytes + byte_diff;
Expand Down Expand Up @@ -1241,7 +1248,7 @@ xfs_iext_remove(
trace_xfs_iext_remove(ip, idx, state, _RET_IP_);

ASSERT(ext_diff > 0);
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);

if (new_size == 0) {
Expand Down Expand Up @@ -1270,7 +1277,7 @@ xfs_iext_remove_inline(

ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
ASSERT(idx < XFS_INLINE_EXTS);
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
ASSERT(((nextents - ext_diff) > 0) &&
(nextents - ext_diff) < XFS_INLINE_EXTS);

Expand Down Expand Up @@ -1309,7 +1316,7 @@ xfs_iext_remove_direct(
ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
new_size = ifp->if_bytes -
(ext_diff * sizeof(xfs_bmbt_rec_t));
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);

if (new_size == 0) {
xfs_iext_destroy(ifp);
Expand Down Expand Up @@ -1546,7 +1553,7 @@ xfs_iext_indirect_to_direct(
int size; /* size of file extents */

ASSERT(ifp->if_flags & XFS_IFEXTIREC);
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
ASSERT(nextents <= XFS_LINEAR_EXTS);
size = nextents * sizeof(xfs_bmbt_rec_t);

Expand Down Expand Up @@ -1620,7 +1627,7 @@ xfs_iext_bno_to_ext(
xfs_extnum_t nextents; /* number of file extents */
xfs_fileoff_t startoff = 0; /* start offset of extent */

nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
if (nextents == 0) {
*idxp = 0;
return NULL;
Expand Down Expand Up @@ -1733,8 +1740,8 @@ xfs_iext_idx_to_irec(

ASSERT(ifp->if_flags & XFS_IFEXTIREC);
ASSERT(page_idx >= 0);
ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc);
ASSERT(page_idx <= xfs_iext_count(ifp));
ASSERT(page_idx < xfs_iext_count(ifp) || realloc);

nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
erp_idx = 0;
Expand Down Expand Up @@ -1782,7 +1789,7 @@ xfs_iext_irec_init(
xfs_extnum_t nextents; /* number of extents in file */

ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);
ASSERT(nextents <= XFS_LINEAR_EXTS);

erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS);
Expand Down Expand Up @@ -1906,7 +1913,7 @@ xfs_iext_irec_compact(

ASSERT(ifp->if_flags & XFS_IFEXTIREC);
nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
nextents = xfs_iext_count(ifp);

if (nextents == 0) {
xfs_iext_destroy(ifp);
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/libxfs/xfs_inode_fork.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ void xfs_init_local_fork(struct xfs_inode *, int, const void *, int);

struct xfs_bmbt_rec_host *
xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t);
xfs_extnum_t xfs_iext_count(struct xfs_ifork *);
void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t,
struct xfs_bmbt_irec *, int);
void xfs_iext_add(struct xfs_ifork *, xfs_extnum_t, int);
Expand Down
22 changes: 20 additions & 2 deletions fs/xfs/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,26 @@ __xfs_get_blocks(
if (error)
goto out_unlock;

/*
* The only time we can ever safely find delalloc blocks on direct I/O
* is a dio write to post-eof speculative preallocation. All other
* scenarios are indicative of a problem or misuse (such as mixing
* direct and mapped I/O).
*
* The file may be unmapped by the time we get here so we cannot
* reliably fail the I/O based on mapping. Instead, fail the I/O if this
* is a read or a write within eof. Otherwise, carry on but warn as a
* precuation if the file happens to be mapped.
*/
if (direct && imap.br_startblock == DELAYSTARTBLOCK) {
if (!create || offset < i_size_read(VFS_I(ip))) {
WARN_ON_ONCE(1);
error = -EIO;
goto out_unlock;
}
WARN_ON_ONCE(mapping_mapped(VFS_I(ip)->i_mapping));
}

/* for DAX, we convert unwritten extents directly */
if (create &&
(!nimaps ||
Expand Down Expand Up @@ -1444,8 +1464,6 @@ __xfs_get_blocks(
(new || ISUNWRITTEN(&imap))))
set_buffer_new(bh_result);

BUG_ON(direct && imap.br_startblock == DELAYSTARTBLOCK);

return 0;

out_unlock:
Expand Down
Loading

0 comments on commit 0fc204e

Please sign in to comment.