mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-18 12:22:27 -04:00
xfs: keep a reference to the pag for busy extents
Processing of busy extents requires the perag structure, so keep the reference while they are in flight. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
committed by
Darrick J. Wong
parent
b6dc8c6dd2
commit
4a137e0915
@@ -117,11 +117,11 @@ xfs_discard_extents(
|
|||||||
|
|
||||||
blk_start_plug(&plug);
|
blk_start_plug(&plug);
|
||||||
list_for_each_entry(busyp, &extents->extent_list, list) {
|
list_for_each_entry(busyp, &extents->extent_list, list) {
|
||||||
trace_xfs_discard_extent(mp, busyp->agno, busyp->bno,
|
trace_xfs_discard_extent(mp, busyp->pag->pag_agno, busyp->bno,
|
||||||
busyp->length);
|
busyp->length);
|
||||||
|
|
||||||
error = __blkdev_issue_discard(mp->m_ddev_targp->bt_bdev,
|
error = __blkdev_issue_discard(mp->m_ddev_targp->bt_bdev,
|
||||||
XFS_AGB_TO_DADDR(mp, busyp->agno, busyp->bno),
|
xfs_agbno_to_daddr(busyp->pag, busyp->bno),
|
||||||
XFS_FSB_TO_BB(mp, busyp->length),
|
XFS_FSB_TO_BB(mp, busyp->length),
|
||||||
GFP_KERNEL, &bio);
|
GFP_KERNEL, &bio);
|
||||||
if (error && error != -EOPNOTSUPP) {
|
if (error && error != -EOPNOTSUPP) {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ xfs_extent_busy_insert_list(
|
|||||||
|
|
||||||
new = kzalloc(sizeof(struct xfs_extent_busy),
|
new = kzalloc(sizeof(struct xfs_extent_busy),
|
||||||
GFP_KERNEL | __GFP_NOFAIL);
|
GFP_KERNEL | __GFP_NOFAIL);
|
||||||
new->agno = pag->pag_agno;
|
new->pag = xfs_perag_hold(pag);
|
||||||
new->bno = bno;
|
new->bno = bno;
|
||||||
new->length = len;
|
new->length = len;
|
||||||
INIT_LIST_HEAD(&new->list);
|
INIT_LIST_HEAD(&new->list);
|
||||||
@@ -526,12 +526,14 @@ xfs_extent_busy_clear_one(
|
|||||||
busyp->flags = XFS_EXTENT_BUSY_DISCARDED;
|
busyp->flags = XFS_EXTENT_BUSY_DISCARDED;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
trace_xfs_extent_busy_clear(pag->pag_mount, busyp->agno,
|
trace_xfs_extent_busy_clear(pag->pag_mount,
|
||||||
busyp->bno, busyp->length);
|
busyp->pag->pag_agno, busyp->bno,
|
||||||
|
busyp->length);
|
||||||
rb_erase(&busyp->rb_node, &pag->pagb_tree);
|
rb_erase(&busyp->rb_node, &pag->pagb_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_del_init(&busyp->list);
|
list_del_init(&busyp->list);
|
||||||
|
xfs_perag_put(busyp->pag);
|
||||||
kfree(busyp);
|
kfree(busyp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -554,10 +556,9 @@ xfs_extent_busy_clear(
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
struct xfs_perag *pag = xfs_perag_hold(busyp->pag);
|
||||||
bool wakeup = false;
|
bool wakeup = false;
|
||||||
struct xfs_perag *pag;
|
|
||||||
|
|
||||||
pag = xfs_perag_get(mp, busyp->agno);
|
|
||||||
spin_lock(&pag->pagb_lock);
|
spin_lock(&pag->pagb_lock);
|
||||||
do {
|
do {
|
||||||
next = list_next_entry(busyp, list);
|
next = list_next_entry(busyp, list);
|
||||||
@@ -565,7 +566,7 @@ xfs_extent_busy_clear(
|
|||||||
wakeup = true;
|
wakeup = true;
|
||||||
busyp = next;
|
busyp = next;
|
||||||
} while (!list_entry_is_head(busyp, list, list) &&
|
} while (!list_entry_is_head(busyp, list, list) &&
|
||||||
busyp->agno == pag->pag_agno);
|
busyp->pag == pag);
|
||||||
|
|
||||||
if (wakeup) {
|
if (wakeup) {
|
||||||
pag->pagb_gen++;
|
pag->pagb_gen++;
|
||||||
@@ -662,7 +663,7 @@ xfs_extent_busy_ag_cmp(
|
|||||||
container_of(l2, struct xfs_extent_busy, list);
|
container_of(l2, struct xfs_extent_busy, list);
|
||||||
s32 diff;
|
s32 diff;
|
||||||
|
|
||||||
diff = b1->agno - b2->agno;
|
diff = b1->pag->pag_agno - b2->pag->pag_agno;
|
||||||
if (!diff)
|
if (!diff)
|
||||||
diff = b1->bno - b2->bno;
|
diff = b1->bno - b2->bno;
|
||||||
return diff;
|
return diff;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ struct xfs_alloc_arg;
|
|||||||
struct xfs_extent_busy {
|
struct xfs_extent_busy {
|
||||||
struct rb_node rb_node; /* ag by-bno indexed search tree */
|
struct rb_node rb_node; /* ag by-bno indexed search tree */
|
||||||
struct list_head list; /* transaction busy extent list */
|
struct list_head list; /* transaction busy extent list */
|
||||||
xfs_agnumber_t agno;
|
struct xfs_perag *pag;
|
||||||
xfs_agblock_t bno;
|
xfs_agblock_t bno;
|
||||||
xfs_extlen_t length;
|
xfs_extlen_t length;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|||||||
Reference in New Issue
Block a user