xfs: updates for 4.8-rc5
Changes in this update: o iomap FIEMAP_EXTENT_MERGED usage fix o additional mount-time feature restrictions o rmap btree query fixes o freeze/unmount io completion workqueue fix o memory corruption fix for deferred operations handling -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXyKjtAAoJEK3oKUf0dfoduy4QAMihN9Gqr4BEyTjaW0yGzvLX 3vLTUxUm6U0pHvspuPmgKDFmlaoir1PiUJMcuuFLSSpM+AbUyoRiUjryiwqyU+WH OOB8YPTk10jBdHnHRG1LowLGOuNdTau6FnzX3JHesOTd+keOSjLVHkBBZ9Gt0wgT TDPDvZI+6QTvy8HtOfkysnBbG1SUNqtNnr7mk77YL7YzJD7sctytCy5sBWJWbIyl RxafJ7CRGCbvFAQEzkQuYQKZtQrtO6Q0wulZLDegOa4aQOp6BPeKVlkGBEayOsY0 Zcg/mdiLL4UKF0PQqcHcWMWtbPfE/qFtwobEHpxVPc3OnkX1dcFID8a46pjqmTgP mmBO3NQODKvMNkn2U3Wao5TAMGRU5cRTc7xxgLy4nJCIEqTYfi6P5izzF+GOV0mB ION5VmnxztuSTTr/xXIFJDSImRvV/ztaiI81ZnArVoqEmUYuBL+z27bRLz1iCLSa 7r5nzO5qu6CHIQFkNeiqsB+BZnTtS/+K+mlNapV1eb97Mm/aze3n61LwaGd2dTpK 1b0HbychEGknnMu14qwoNl3zh2a/3nfIZJ6XRc2FjeyesehMOOPgAfvl+FYA7GW9 TpXebewg4xIJyaIE1JKLZ4kFnpkzRfbp0OdohDPJwfLVGWi9hurtYI+ASpm8WY+G dG41MCfgbkhU5VgL/zDt =2bMl -----END PGP SIGNATURE----- Merge tag 'xfs-iomap-for-linus-4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs Pull xfs and iomap fixes from Dave Chinner: "Most of these changes are small regression fixes that address problems introduced in the 4.8-rc1 window. The two fixes that aren't (IO completion fix and superblock inprogress check) are fixes for problems introduced some time ago and need to be pushed back to stable kernels. Changes in this update: - iomap FIEMAP_EXTENT_MERGED usage fix - additional mount-time feature restrictions - rmap btree query fixes - freeze/unmount io completion workqueue fix - memory corruption fix for deferred operations handling" * tag 'xfs-iomap-for-linus-4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs: xfs: track log done items directly in the deferred pending work item iomap: don't set FIEMAP_EXTENT_MERGED for extent based filesystems xfs: prevent dropping ioend completions during buftarg wait xfs: fix superblock inprogress check xfs: simple btree query range should look right if LE lookup fails xfs: fix some key handling problems in _btree_simple_query_range xfs: don't log the entire end of the AGF xfs: disallow mounting of realtime + rmap filesystems xfs: don't perform lookups on zero-height btrees
This commit is contained in:
commit
7d1ce606a3
|
@ -428,9 +428,12 @@ static int iomap_to_fiemap(struct fiemap_extent_info *fi,
|
|||
break;
|
||||
}
|
||||
|
||||
if (iomap->flags & IOMAP_F_MERGED)
|
||||
flags |= FIEMAP_EXTENT_MERGED;
|
||||
|
||||
return fiemap_fill_next_extent(fi, iomap->offset,
|
||||
iomap->blkno != IOMAP_NULL_BLOCK ? iomap->blkno << 9: 0,
|
||||
iomap->length, flags | FIEMAP_EXTENT_MERGED);
|
||||
iomap->length, flags);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2278,6 +2278,8 @@ xfs_alloc_log_agf(
|
|||
offsetof(xfs_agf_t, agf_btreeblks),
|
||||
offsetof(xfs_agf_t, agf_uuid),
|
||||
offsetof(xfs_agf_t, agf_rmap_blocks),
|
||||
/* needed so that we don't log the whole rest of the structure: */
|
||||
offsetof(xfs_agf_t, agf_spare64),
|
||||
sizeof(xfs_agf_t)
|
||||
};
|
||||
|
||||
|
|
|
@ -1814,6 +1814,10 @@ xfs_btree_lookup(
|
|||
|
||||
XFS_BTREE_STATS_INC(cur, lookup);
|
||||
|
||||
/* No such thing as a zero-level tree. */
|
||||
if (cur->bc_nlevels == 0)
|
||||
return -EFSCORRUPTED;
|
||||
|
||||
block = NULL;
|
||||
keyno = 0;
|
||||
|
||||
|
@ -4554,15 +4558,22 @@ xfs_btree_simple_query_range(
|
|||
if (error)
|
||||
goto out;
|
||||
|
||||
/* Nothing? See if there's anything to the right. */
|
||||
if (!stat) {
|
||||
error = xfs_btree_increment(cur, 0, &stat);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (stat) {
|
||||
/* Find the record. */
|
||||
error = xfs_btree_get_rec(cur, &recp, &stat);
|
||||
if (error || !stat)
|
||||
break;
|
||||
cur->bc_ops->init_high_key_from_rec(&rec_key, recp);
|
||||
|
||||
/* Skip if high_key(rec) < low_key. */
|
||||
if (firstrec) {
|
||||
cur->bc_ops->init_high_key_from_rec(&rec_key, recp);
|
||||
firstrec = false;
|
||||
diff = cur->bc_ops->diff_two_keys(cur, low_key,
|
||||
&rec_key);
|
||||
|
@ -4571,6 +4582,7 @@ xfs_btree_simple_query_range(
|
|||
}
|
||||
|
||||
/* Stop if high_key < low_key(rec). */
|
||||
cur->bc_ops->init_key_from_rec(&rec_key, recp);
|
||||
diff = cur->bc_ops->diff_two_keys(cur, &rec_key, high_key);
|
||||
if (diff > 0)
|
||||
break;
|
||||
|
|
|
@ -194,7 +194,7 @@ xfs_defer_trans_abort(
|
|||
/* Abort intent items. */
|
||||
list_for_each_entry(dfp, &dop->dop_pending, dfp_list) {
|
||||
trace_xfs_defer_pending_abort(tp->t_mountp, dfp);
|
||||
if (dfp->dfp_committed)
|
||||
if (!dfp->dfp_done)
|
||||
dfp->dfp_type->abort_intent(dfp->dfp_intent);
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,6 @@ xfs_defer_finish(
|
|||
struct xfs_defer_pending *dfp;
|
||||
struct list_head *li;
|
||||
struct list_head *n;
|
||||
void *done_item = NULL;
|
||||
void *state;
|
||||
int error = 0;
|
||||
void (*cleanup_fn)(struct xfs_trans *, void *, int);
|
||||
|
@ -309,19 +308,11 @@ xfs_defer_finish(
|
|||
if (error)
|
||||
goto out;
|
||||
|
||||
/* Mark all pending intents as committed. */
|
||||
list_for_each_entry_reverse(dfp, &dop->dop_pending, dfp_list) {
|
||||
if (dfp->dfp_committed)
|
||||
break;
|
||||
trace_xfs_defer_pending_commit((*tp)->t_mountp, dfp);
|
||||
dfp->dfp_committed = true;
|
||||
}
|
||||
|
||||
/* Log an intent-done item for the first pending item. */
|
||||
dfp = list_first_entry(&dop->dop_pending,
|
||||
struct xfs_defer_pending, dfp_list);
|
||||
trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp);
|
||||
done_item = dfp->dfp_type->create_done(*tp, dfp->dfp_intent,
|
||||
dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent,
|
||||
dfp->dfp_count);
|
||||
cleanup_fn = dfp->dfp_type->finish_cleanup;
|
||||
|
||||
|
@ -331,7 +322,7 @@ xfs_defer_finish(
|
|||
list_del(li);
|
||||
dfp->dfp_count--;
|
||||
error = dfp->dfp_type->finish_item(*tp, dop, li,
|
||||
done_item, &state);
|
||||
dfp->dfp_done, &state);
|
||||
if (error) {
|
||||
/*
|
||||
* Clean up after ourselves and jump out.
|
||||
|
@ -428,8 +419,8 @@ xfs_defer_add(
|
|||
dfp = kmem_alloc(sizeof(struct xfs_defer_pending),
|
||||
KM_SLEEP | KM_NOFS);
|
||||
dfp->dfp_type = defer_op_types[type];
|
||||
dfp->dfp_committed = false;
|
||||
dfp->dfp_intent = NULL;
|
||||
dfp->dfp_done = NULL;
|
||||
dfp->dfp_count = 0;
|
||||
INIT_LIST_HEAD(&dfp->dfp_work);
|
||||
list_add_tail(&dfp->dfp_list, &dop->dop_intake);
|
||||
|
|
|
@ -30,8 +30,8 @@ struct xfs_defer_op_type;
|
|||
struct xfs_defer_pending {
|
||||
const struct xfs_defer_op_type *dfp_type; /* function pointers */
|
||||
struct list_head dfp_list; /* pending items */
|
||||
bool dfp_committed; /* committed trans? */
|
||||
void *dfp_intent; /* log intent item */
|
||||
void *dfp_done; /* log done item */
|
||||
struct list_head dfp_work; /* work items */
|
||||
unsigned int dfp_count; /* # extent items */
|
||||
};
|
||||
|
|
|
@ -674,7 +674,8 @@ typedef struct xfs_agf {
|
|||
#define XFS_AGF_BTREEBLKS 0x00000800
|
||||
#define XFS_AGF_UUID 0x00001000
|
||||
#define XFS_AGF_RMAP_BLOCKS 0x00002000
|
||||
#define XFS_AGF_NUM_BITS 14
|
||||
#define XFS_AGF_SPARE64 0x00004000
|
||||
#define XFS_AGF_NUM_BITS 15
|
||||
#define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1)
|
||||
|
||||
#define XFS_AGF_FLAGS \
|
||||
|
@ -691,7 +692,8 @@ typedef struct xfs_agf {
|
|||
{ XFS_AGF_LONGEST, "LONGEST" }, \
|
||||
{ XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \
|
||||
{ XFS_AGF_UUID, "UUID" }, \
|
||||
{ XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" }
|
||||
{ XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" }, \
|
||||
{ XFS_AGF_SPARE64, "SPARE64" }
|
||||
|
||||
/* disk block (xfs_daddr_t) in the AG */
|
||||
#define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
|
||||
|
|
|
@ -583,7 +583,8 @@ xfs_sb_verify(
|
|||
* Only check the in progress field for the primary superblock as
|
||||
* mkfs.xfs doesn't clear it from secondary superblocks.
|
||||
*/
|
||||
return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
|
||||
return xfs_mount_validate_sb(mp, &sb,
|
||||
bp->b_maps[0].bm_bn == XFS_SB_DADDR,
|
||||
check_version);
|
||||
}
|
||||
|
||||
|
|
|
@ -1611,7 +1611,7 @@ xfs_wait_buftarg(
|
|||
*/
|
||||
while (percpu_counter_sum(&btp->bt_io_count))
|
||||
delay(100);
|
||||
drain_workqueue(btp->bt_mount->m_buf_workqueue);
|
||||
flush_workqueue(btp->bt_mount->m_buf_workqueue);
|
||||
|
||||
/* loop until there is nothing left on the lru list. */
|
||||
while (list_lru_count(&btp->bt_lru)) {
|
||||
|
|
|
@ -1574,9 +1574,16 @@ xfs_fs_fill_super(
|
|||
}
|
||||
}
|
||||
|
||||
if (xfs_sb_version_hasrmapbt(&mp->m_sb))
|
||||
if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
|
||||
if (mp->m_sb.sb_rblocks) {
|
||||
xfs_alert(mp,
|
||||
"EXPERIMENTAL reverse mapping btree not compatible with realtime device!");
|
||||
error = -EINVAL;
|
||||
goto out_filestream_unmount;
|
||||
}
|
||||
xfs_alert(mp,
|
||||
"EXPERIMENTAL reverse mapping btree feature enabled. Use at your own risk!");
|
||||
}
|
||||
|
||||
error = xfs_mountfs(mp);
|
||||
if (error)
|
||||
|
|
|
@ -2295,7 +2295,7 @@ DECLARE_EVENT_CLASS(xfs_defer_pending_class,
|
|||
__entry->dev = mp ? mp->m_super->s_dev : 0;
|
||||
__entry->type = dfp->dfp_type->type;
|
||||
__entry->intent = dfp->dfp_intent;
|
||||
__entry->committed = dfp->dfp_committed;
|
||||
__entry->committed = dfp->dfp_done != NULL;
|
||||
__entry->nr = dfp->dfp_count;
|
||||
),
|
||||
TP_printk("dev %d:%d optype %d intent %p committed %d nr %d\n",
|
||||
|
|
|
@ -18,6 +18,11 @@ struct vm_fault;
|
|||
#define IOMAP_MAPPED 0x03 /* blocks allocated @blkno */
|
||||
#define IOMAP_UNWRITTEN 0x04 /* blocks allocated @blkno in unwritten state */
|
||||
|
||||
/*
|
||||
* Flags for iomap mappings:
|
||||
*/
|
||||
#define IOMAP_F_MERGED 0x01 /* contains multiple blocks/extents */
|
||||
|
||||
/*
|
||||
* Magic value for blkno:
|
||||
*/
|
||||
|
@ -27,7 +32,8 @@ struct iomap {
|
|||
sector_t blkno; /* 1st sector of mapping, 512b units */
|
||||
loff_t offset; /* file offset of mapping, bytes */
|
||||
u64 length; /* length of mapping, bytes */
|
||||
int type; /* type of mapping */
|
||||
u16 type; /* type of mapping */
|
||||
u16 flags; /* flags for mapping */
|
||||
struct block_device *bdev; /* block device for I/O */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue