diff options
Diffstat (limited to 'fs/xfs/xfs_buf.c')
-rw-r--r-- | fs/xfs/xfs_buf.c | 244 |
1 files changed, 98 insertions, 146 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index c57836dc778f..cf0ac056815f 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | static kmem_zone_t *xfs_buf_zone; | 44 | static kmem_zone_t *xfs_buf_zone; |
45 | STATIC int xfsbufd(void *); | 45 | STATIC int xfsbufd(void *); |
46 | STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); | ||
47 | 46 | ||
48 | static struct workqueue_struct *xfslogd_workqueue; | 47 | static struct workqueue_struct *xfslogd_workqueue; |
49 | struct workqueue_struct *xfsdatad_workqueue; | 48 | struct workqueue_struct *xfsdatad_workqueue; |
@@ -66,10 +65,6 @@ struct workqueue_struct *xfsconvertd_workqueue; | |||
66 | #define xb_to_km(flags) \ | 65 | #define xb_to_km(flags) \ |
67 | (((flags) & XBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP) | 66 | (((flags) & XBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP) |
68 | 67 | ||
69 | #define xfs_buf_allocate(flags) \ | ||
70 | kmem_zone_alloc(xfs_buf_zone, xb_to_km(flags)) | ||
71 | #define xfs_buf_deallocate(bp) \ | ||
72 | kmem_zone_free(xfs_buf_zone, (bp)); | ||
73 | 68 | ||
74 | static inline int | 69 | static inline int |
75 | xfs_buf_is_vmapped( | 70 | xfs_buf_is_vmapped( |
@@ -152,6 +147,7 @@ xfs_buf_stale( | |||
152 | struct xfs_buf *bp) | 147 | struct xfs_buf *bp) |
153 | { | 148 | { |
154 | bp->b_flags |= XBF_STALE; | 149 | bp->b_flags |= XBF_STALE; |
150 | xfs_buf_delwri_dequeue(bp); | ||
155 | atomic_set(&(bp)->b_lru_ref, 0); | 151 | atomic_set(&(bp)->b_lru_ref, 0); |
156 | if (!list_empty(&bp->b_lru)) { | 152 | if (!list_empty(&bp->b_lru)) { |
157 | struct xfs_buftarg *btp = bp->b_target; | 153 | struct xfs_buftarg *btp = bp->b_target; |
@@ -167,14 +163,19 @@ xfs_buf_stale( | |||
167 | ASSERT(atomic_read(&bp->b_hold) >= 1); | 163 | ASSERT(atomic_read(&bp->b_hold) >= 1); |
168 | } | 164 | } |
169 | 165 | ||
170 | STATIC void | 166 | struct xfs_buf * |
171 | _xfs_buf_initialize( | 167 | xfs_buf_alloc( |
172 | xfs_buf_t *bp, | 168 | struct xfs_buftarg *target, |
173 | xfs_buftarg_t *target, | ||
174 | xfs_off_t range_base, | 169 | xfs_off_t range_base, |
175 | size_t range_length, | 170 | size_t range_length, |
176 | xfs_buf_flags_t flags) | 171 | xfs_buf_flags_t flags) |
177 | { | 172 | { |
173 | struct xfs_buf *bp; | ||
174 | |||
175 | bp = kmem_zone_alloc(xfs_buf_zone, xb_to_km(flags)); | ||
176 | if (unlikely(!bp)) | ||
177 | return NULL; | ||
178 | |||
178 | /* | 179 | /* |
179 | * We don't want certain flags to appear in b_flags. | 180 | * We don't want certain flags to appear in b_flags. |
180 | */ | 181 | */ |
@@ -203,8 +204,9 @@ _xfs_buf_initialize( | |||
203 | init_waitqueue_head(&bp->b_waiters); | 204 | init_waitqueue_head(&bp->b_waiters); |
204 | 205 | ||
205 | XFS_STATS_INC(xb_create); | 206 | XFS_STATS_INC(xb_create); |
206 | |||
207 | trace_xfs_buf_init(bp, _RET_IP_); | 207 | trace_xfs_buf_init(bp, _RET_IP_); |
208 | |||
209 | return bp; | ||
208 | } | 210 | } |
209 | 211 | ||
210 | /* | 212 | /* |
@@ -277,7 +279,7 @@ xfs_buf_free( | |||
277 | } else if (bp->b_flags & _XBF_KMEM) | 279 | } else if (bp->b_flags & _XBF_KMEM) |
278 | kmem_free(bp->b_addr); | 280 | kmem_free(bp->b_addr); |
279 | _xfs_buf_free_pages(bp); | 281 | _xfs_buf_free_pages(bp); |
280 | xfs_buf_deallocate(bp); | 282 | kmem_zone_free(xfs_buf_zone, bp); |
281 | } | 283 | } |
282 | 284 | ||
283 | /* | 285 | /* |
@@ -416,10 +418,7 @@ _xfs_buf_map_pages( | |||
416 | /* | 418 | /* |
417 | * Look up, and creates if absent, a lockable buffer for | 419 | * Look up, and creates if absent, a lockable buffer for |
418 | * a given range of an inode. The buffer is returned | 420 | * a given range of an inode. The buffer is returned |
419 | * locked. If other overlapping buffers exist, they are | 421 | * locked. No I/O is implied by this call. |
420 | * released before the new buffer is created and locked, | ||
421 | * which may imply that this call will block until those buffers | ||
422 | * are unlocked. No I/O is implied by this call. | ||
423 | */ | 422 | */ |
424 | xfs_buf_t * | 423 | xfs_buf_t * |
425 | _xfs_buf_find( | 424 | _xfs_buf_find( |
@@ -481,8 +480,6 @@ _xfs_buf_find( | |||
481 | 480 | ||
482 | /* No match found */ | 481 | /* No match found */ |
483 | if (new_bp) { | 482 | if (new_bp) { |
484 | _xfs_buf_initialize(new_bp, btp, range_base, | ||
485 | range_length, flags); | ||
486 | rb_link_node(&new_bp->b_rbnode, parent, rbp); | 483 | rb_link_node(&new_bp->b_rbnode, parent, rbp); |
487 | rb_insert_color(&new_bp->b_rbnode, &pag->pag_buf_tree); | 484 | rb_insert_color(&new_bp->b_rbnode, &pag->pag_buf_tree); |
488 | /* the buffer keeps the perag reference until it is freed */ | 485 | /* the buffer keeps the perag reference until it is freed */ |
@@ -525,35 +522,51 @@ found: | |||
525 | } | 522 | } |
526 | 523 | ||
527 | /* | 524 | /* |
528 | * Assembles a buffer covering the specified range. | 525 | * Assembles a buffer covering the specified range. The code is optimised for |
529 | * Storage in memory for all portions of the buffer will be allocated, | 526 | * cache hits, as metadata intensive workloads will see 3 orders of magnitude |
530 | * although backing storage may not be. | 527 | * more hits than misses. |
531 | */ | 528 | */ |
532 | xfs_buf_t * | 529 | struct xfs_buf * |
533 | xfs_buf_get( | 530 | xfs_buf_get( |
534 | xfs_buftarg_t *target,/* target for buffer */ | 531 | xfs_buftarg_t *target,/* target for buffer */ |
535 | xfs_off_t ioff, /* starting offset of range */ | 532 | xfs_off_t ioff, /* starting offset of range */ |
536 | size_t isize, /* length of range */ | 533 | size_t isize, /* length of range */ |
537 | xfs_buf_flags_t flags) | 534 | xfs_buf_flags_t flags) |
538 | { | 535 | { |
539 | xfs_buf_t *bp, *new_bp; | 536 | struct xfs_buf *bp; |
537 | struct xfs_buf *new_bp; | ||
540 | int error = 0; | 538 | int error = 0; |
541 | 539 | ||
542 | new_bp = xfs_buf_allocate(flags); | 540 | bp = _xfs_buf_find(target, ioff, isize, flags, NULL); |
541 | if (likely(bp)) | ||
542 | goto found; | ||
543 | |||
544 | new_bp = xfs_buf_alloc(target, ioff << BBSHIFT, isize << BBSHIFT, | ||
545 | flags); | ||
543 | if (unlikely(!new_bp)) | 546 | if (unlikely(!new_bp)) |
544 | return NULL; | 547 | return NULL; |
545 | 548 | ||
546 | bp = _xfs_buf_find(target, ioff, isize, flags, new_bp); | 549 | bp = _xfs_buf_find(target, ioff, isize, flags, new_bp); |
550 | if (!bp) { | ||
551 | kmem_zone_free(xfs_buf_zone, new_bp); | ||
552 | return NULL; | ||
553 | } | ||
554 | |||
547 | if (bp == new_bp) { | 555 | if (bp == new_bp) { |
548 | error = xfs_buf_allocate_memory(bp, flags); | 556 | error = xfs_buf_allocate_memory(bp, flags); |
549 | if (error) | 557 | if (error) |
550 | goto no_buffer; | 558 | goto no_buffer; |
551 | } else { | 559 | } else |
552 | xfs_buf_deallocate(new_bp); | 560 | kmem_zone_free(xfs_buf_zone, new_bp); |
553 | if (unlikely(bp == NULL)) | ||
554 | return NULL; | ||
555 | } | ||
556 | 561 | ||
562 | /* | ||
563 | * Now we have a workable buffer, fill in the block number so | ||
564 | * that we can do IO on it. | ||
565 | */ | ||
566 | bp->b_bn = ioff; | ||
567 | bp->b_count_desired = bp->b_buffer_length; | ||
568 | |||
569 | found: | ||
557 | if (!(bp->b_flags & XBF_MAPPED)) { | 570 | if (!(bp->b_flags & XBF_MAPPED)) { |
558 | error = _xfs_buf_map_pages(bp, flags); | 571 | error = _xfs_buf_map_pages(bp, flags); |
559 | if (unlikely(error)) { | 572 | if (unlikely(error)) { |
@@ -564,18 +577,10 @@ xfs_buf_get( | |||
564 | } | 577 | } |
565 | 578 | ||
566 | XFS_STATS_INC(xb_get); | 579 | XFS_STATS_INC(xb_get); |
567 | |||
568 | /* | ||
569 | * Always fill in the block number now, the mapped cases can do | ||
570 | * their own overlay of this later. | ||
571 | */ | ||
572 | bp->b_bn = ioff; | ||
573 | bp->b_count_desired = bp->b_buffer_length; | ||
574 | |||
575 | trace_xfs_buf_get(bp, flags, _RET_IP_); | 580 | trace_xfs_buf_get(bp, flags, _RET_IP_); |
576 | return bp; | 581 | return bp; |
577 | 582 | ||
578 | no_buffer: | 583 | no_buffer: |
579 | if (flags & (XBF_LOCK | XBF_TRYLOCK)) | 584 | if (flags & (XBF_LOCK | XBF_TRYLOCK)) |
580 | xfs_buf_unlock(bp); | 585 | xfs_buf_unlock(bp); |
581 | xfs_buf_rele(bp); | 586 | xfs_buf_rele(bp); |
@@ -689,19 +694,6 @@ xfs_buf_read_uncached( | |||
689 | return bp; | 694 | return bp; |
690 | } | 695 | } |
691 | 696 | ||
692 | xfs_buf_t * | ||
693 | xfs_buf_get_empty( | ||
694 | size_t len, | ||
695 | xfs_buftarg_t *target) | ||
696 | { | ||
697 | xfs_buf_t *bp; | ||
698 | |||
699 | bp = xfs_buf_allocate(0); | ||
700 | if (bp) | ||
701 | _xfs_buf_initialize(bp, target, 0, len, 0); | ||
702 | return bp; | ||
703 | } | ||
704 | |||
705 | /* | 697 | /* |
706 | * Return a buffer allocated as an empty buffer and associated to external | 698 | * Return a buffer allocated as an empty buffer and associated to external |
707 | * memory via xfs_buf_associate_memory() back to it's empty state. | 699 | * memory via xfs_buf_associate_memory() back to it's empty state. |
@@ -787,10 +779,9 @@ xfs_buf_get_uncached( | |||
787 | int error, i; | 779 | int error, i; |
788 | xfs_buf_t *bp; | 780 | xfs_buf_t *bp; |
789 | 781 | ||
790 | bp = xfs_buf_allocate(0); | 782 | bp = xfs_buf_alloc(target, 0, len, 0); |
791 | if (unlikely(bp == NULL)) | 783 | if (unlikely(bp == NULL)) |
792 | goto fail; | 784 | goto fail; |
793 | _xfs_buf_initialize(bp, target, 0, len, 0); | ||
794 | 785 | ||
795 | error = _xfs_buf_get_pages(bp, page_count, 0); | 786 | error = _xfs_buf_get_pages(bp, page_count, 0); |
796 | if (error) | 787 | if (error) |
@@ -818,7 +809,7 @@ xfs_buf_get_uncached( | |||
818 | __free_page(bp->b_pages[i]); | 809 | __free_page(bp->b_pages[i]); |
819 | _xfs_buf_free_pages(bp); | 810 | _xfs_buf_free_pages(bp); |
820 | fail_free_buf: | 811 | fail_free_buf: |
821 | xfs_buf_deallocate(bp); | 812 | kmem_zone_free(xfs_buf_zone, bp); |
822 | fail: | 813 | fail: |
823 | return NULL; | 814 | return NULL; |
824 | } | 815 | } |
@@ -937,12 +928,6 @@ void | |||
937 | xfs_buf_unlock( | 928 | xfs_buf_unlock( |
938 | struct xfs_buf *bp) | 929 | struct xfs_buf *bp) |
939 | { | 930 | { |
940 | if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) { | ||
941 | atomic_inc(&bp->b_hold); | ||
942 | bp->b_flags |= XBF_ASYNC; | ||
943 | xfs_buf_delwri_queue(bp, 0); | ||
944 | } | ||
945 | |||
946 | XB_CLEAR_OWNER(bp); | 931 | XB_CLEAR_OWNER(bp); |
947 | up(&bp->b_sema); | 932 | up(&bp->b_sema); |
948 | 933 | ||
@@ -1019,9 +1004,19 @@ xfs_buf_ioerror( | |||
1019 | trace_xfs_buf_ioerror(bp, error, _RET_IP_); | 1004 | trace_xfs_buf_ioerror(bp, error, _RET_IP_); |
1020 | } | 1005 | } |
1021 | 1006 | ||
1007 | void | ||
1008 | xfs_buf_ioerror_alert( | ||
1009 | struct xfs_buf *bp, | ||
1010 | const char *func) | ||
1011 | { | ||
1012 | xfs_alert(bp->b_target->bt_mount, | ||
1013 | "metadata I/O error: block 0x%llx (\"%s\") error %d buf count %zd", | ||
1014 | (__uint64_t)XFS_BUF_ADDR(bp), func, | ||
1015 | bp->b_error, XFS_BUF_COUNT(bp)); | ||
1016 | } | ||
1017 | |||
1022 | int | 1018 | int |
1023 | xfs_bwrite( | 1019 | xfs_bwrite( |
1024 | struct xfs_mount *mp, | ||
1025 | struct xfs_buf *bp) | 1020 | struct xfs_buf *bp) |
1026 | { | 1021 | { |
1027 | int error; | 1022 | int error; |
@@ -1033,25 +1028,13 @@ xfs_bwrite( | |||
1033 | xfs_bdstrat_cb(bp); | 1028 | xfs_bdstrat_cb(bp); |
1034 | 1029 | ||
1035 | error = xfs_buf_iowait(bp); | 1030 | error = xfs_buf_iowait(bp); |
1036 | if (error) | 1031 | if (error) { |
1037 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); | 1032 | xfs_force_shutdown(bp->b_target->bt_mount, |
1038 | xfs_buf_relse(bp); | 1033 | SHUTDOWN_META_IO_ERROR); |
1034 | } | ||
1039 | return error; | 1035 | return error; |
1040 | } | 1036 | } |
1041 | 1037 | ||
1042 | void | ||
1043 | xfs_bdwrite( | ||
1044 | void *mp, | ||
1045 | struct xfs_buf *bp) | ||
1046 | { | ||
1047 | trace_xfs_buf_bdwrite(bp, _RET_IP_); | ||
1048 | |||
1049 | bp->b_flags &= ~XBF_READ; | ||
1050 | bp->b_flags |= (XBF_DELWRI | XBF_ASYNC); | ||
1051 | |||
1052 | xfs_buf_delwri_queue(bp, 1); | ||
1053 | } | ||
1054 | |||
1055 | /* | 1038 | /* |
1056 | * Called when we want to stop a buffer from getting written or read. | 1039 | * Called when we want to stop a buffer from getting written or read. |
1057 | * We attach the EIO error, muck with its flags, and call xfs_buf_ioend | 1040 | * We attach the EIO error, muck with its flags, and call xfs_buf_ioend |
@@ -1074,9 +1057,8 @@ xfs_bioerror( | |||
1074 | * We're calling xfs_buf_ioend, so delete XBF_DONE flag. | 1057 | * We're calling xfs_buf_ioend, so delete XBF_DONE flag. |
1075 | */ | 1058 | */ |
1076 | XFS_BUF_UNREAD(bp); | 1059 | XFS_BUF_UNREAD(bp); |
1077 | XFS_BUF_UNDELAYWRITE(bp); | ||
1078 | XFS_BUF_UNDONE(bp); | 1060 | XFS_BUF_UNDONE(bp); |
1079 | XFS_BUF_STALE(bp); | 1061 | xfs_buf_stale(bp); |
1080 | 1062 | ||
1081 | xfs_buf_ioend(bp, 0); | 1063 | xfs_buf_ioend(bp, 0); |
1082 | 1064 | ||
@@ -1103,9 +1085,8 @@ xfs_bioerror_relse( | |||
1103 | * change that interface. | 1085 | * change that interface. |
1104 | */ | 1086 | */ |
1105 | XFS_BUF_UNREAD(bp); | 1087 | XFS_BUF_UNREAD(bp); |
1106 | XFS_BUF_UNDELAYWRITE(bp); | ||
1107 | XFS_BUF_DONE(bp); | 1088 | XFS_BUF_DONE(bp); |
1108 | XFS_BUF_STALE(bp); | 1089 | xfs_buf_stale(bp); |
1109 | bp->b_iodone = NULL; | 1090 | bp->b_iodone = NULL; |
1110 | if (!(fl & XBF_ASYNC)) { | 1091 | if (!(fl & XBF_ASYNC)) { |
1111 | /* | 1092 | /* |
@@ -1115,7 +1096,7 @@ xfs_bioerror_relse( | |||
1115 | * ASYNC buffers. | 1096 | * ASYNC buffers. |
1116 | */ | 1097 | */ |
1117 | xfs_buf_ioerror(bp, EIO); | 1098 | xfs_buf_ioerror(bp, EIO); |
1118 | XFS_BUF_FINISH_IOWAIT(bp); | 1099 | complete(&bp->b_iowait); |
1119 | } else { | 1100 | } else { |
1120 | xfs_buf_relse(bp); | 1101 | xfs_buf_relse(bp); |
1121 | } | 1102 | } |
@@ -1275,15 +1256,10 @@ xfs_buf_iorequest( | |||
1275 | { | 1256 | { |
1276 | trace_xfs_buf_iorequest(bp, _RET_IP_); | 1257 | trace_xfs_buf_iorequest(bp, _RET_IP_); |
1277 | 1258 | ||
1278 | if (bp->b_flags & XBF_DELWRI) { | 1259 | ASSERT(!(bp->b_flags & XBF_DELWRI)); |
1279 | xfs_buf_delwri_queue(bp, 1); | ||
1280 | return 0; | ||
1281 | } | ||
1282 | 1260 | ||
1283 | if (bp->b_flags & XBF_WRITE) { | 1261 | if (bp->b_flags & XBF_WRITE) |
1284 | xfs_buf_wait_unpin(bp); | 1262 | xfs_buf_wait_unpin(bp); |
1285 | } | ||
1286 | |||
1287 | xfs_buf_hold(bp); | 1263 | xfs_buf_hold(bp); |
1288 | 1264 | ||
1289 | /* Set the count to 1 initially, this will stop an I/O | 1265 | /* Set the count to 1 initially, this will stop an I/O |
@@ -1481,9 +1457,13 @@ xfs_setsize_buftarg_flags( | |||
1481 | btp->bt_smask = sectorsize - 1; | 1457 | btp->bt_smask = sectorsize - 1; |
1482 | 1458 | ||
1483 | if (set_blocksize(btp->bt_bdev, sectorsize)) { | 1459 | if (set_blocksize(btp->bt_bdev, sectorsize)) { |
1460 | char name[BDEVNAME_SIZE]; | ||
1461 | |||
1462 | bdevname(btp->bt_bdev, name); | ||
1463 | |||
1484 | xfs_warn(btp->bt_mount, | 1464 | xfs_warn(btp->bt_mount, |
1485 | "Cannot set_blocksize to %u on device %s\n", | 1465 | "Cannot set_blocksize to %u on device %s\n", |
1486 | sectorsize, xfs_buf_target_name(btp)); | 1466 | sectorsize, name); |
1487 | return EINVAL; | 1467 | return EINVAL; |
1488 | } | 1468 | } |
1489 | 1469 | ||
@@ -1514,12 +1494,12 @@ xfs_setsize_buftarg( | |||
1514 | } | 1494 | } |
1515 | 1495 | ||
1516 | STATIC int | 1496 | STATIC int |
1517 | xfs_alloc_delwrite_queue( | 1497 | xfs_alloc_delwri_queue( |
1518 | xfs_buftarg_t *btp, | 1498 | xfs_buftarg_t *btp, |
1519 | const char *fsname) | 1499 | const char *fsname) |
1520 | { | 1500 | { |
1521 | INIT_LIST_HEAD(&btp->bt_delwrite_queue); | 1501 | INIT_LIST_HEAD(&btp->bt_delwri_queue); |
1522 | spin_lock_init(&btp->bt_delwrite_lock); | 1502 | spin_lock_init(&btp->bt_delwri_lock); |
1523 | btp->bt_flags = 0; | 1503 | btp->bt_flags = 0; |
1524 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd/%s", fsname); | 1504 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd/%s", fsname); |
1525 | if (IS_ERR(btp->bt_task)) | 1505 | if (IS_ERR(btp->bt_task)) |
@@ -1549,7 +1529,7 @@ xfs_alloc_buftarg( | |||
1549 | spin_lock_init(&btp->bt_lru_lock); | 1529 | spin_lock_init(&btp->bt_lru_lock); |
1550 | if (xfs_setsize_buftarg_early(btp, bdev)) | 1530 | if (xfs_setsize_buftarg_early(btp, bdev)) |
1551 | goto error; | 1531 | goto error; |
1552 | if (xfs_alloc_delwrite_queue(btp, fsname)) | 1532 | if (xfs_alloc_delwri_queue(btp, fsname)) |
1553 | goto error; | 1533 | goto error; |
1554 | btp->bt_shrinker.shrink = xfs_buftarg_shrink; | 1534 | btp->bt_shrinker.shrink = xfs_buftarg_shrink; |
1555 | btp->bt_shrinker.seeks = DEFAULT_SEEKS; | 1535 | btp->bt_shrinker.seeks = DEFAULT_SEEKS; |
@@ -1565,56 +1545,48 @@ error: | |||
1565 | /* | 1545 | /* |
1566 | * Delayed write buffer handling | 1546 | * Delayed write buffer handling |
1567 | */ | 1547 | */ |
1568 | STATIC void | 1548 | void |
1569 | xfs_buf_delwri_queue( | 1549 | xfs_buf_delwri_queue( |
1570 | xfs_buf_t *bp, | 1550 | xfs_buf_t *bp) |
1571 | int unlock) | ||
1572 | { | 1551 | { |
1573 | struct list_head *dwq = &bp->b_target->bt_delwrite_queue; | 1552 | struct xfs_buftarg *btp = bp->b_target; |
1574 | spinlock_t *dwlk = &bp->b_target->bt_delwrite_lock; | ||
1575 | 1553 | ||
1576 | trace_xfs_buf_delwri_queue(bp, _RET_IP_); | 1554 | trace_xfs_buf_delwri_queue(bp, _RET_IP_); |
1577 | 1555 | ||
1578 | ASSERT((bp->b_flags&(XBF_DELWRI|XBF_ASYNC)) == (XBF_DELWRI|XBF_ASYNC)); | 1556 | ASSERT(!(bp->b_flags & XBF_READ)); |
1579 | 1557 | ||
1580 | spin_lock(dwlk); | 1558 | spin_lock(&btp->bt_delwri_lock); |
1581 | /* If already in the queue, dequeue and place at tail */ | ||
1582 | if (!list_empty(&bp->b_list)) { | 1559 | if (!list_empty(&bp->b_list)) { |
1560 | /* if already in the queue, move it to the tail */ | ||
1583 | ASSERT(bp->b_flags & _XBF_DELWRI_Q); | 1561 | ASSERT(bp->b_flags & _XBF_DELWRI_Q); |
1584 | if (unlock) | 1562 | list_move_tail(&bp->b_list, &btp->bt_delwri_queue); |
1585 | atomic_dec(&bp->b_hold); | 1563 | } else { |
1586 | list_del(&bp->b_list); | ||
1587 | } | ||
1588 | |||
1589 | if (list_empty(dwq)) { | ||
1590 | /* start xfsbufd as it is about to have something to do */ | 1564 | /* start xfsbufd as it is about to have something to do */ |
1591 | wake_up_process(bp->b_target->bt_task); | 1565 | if (list_empty(&btp->bt_delwri_queue)) |
1592 | } | 1566 | wake_up_process(bp->b_target->bt_task); |
1593 | 1567 | ||
1594 | bp->b_flags |= _XBF_DELWRI_Q; | 1568 | atomic_inc(&bp->b_hold); |
1595 | list_add_tail(&bp->b_list, dwq); | 1569 | bp->b_flags |= XBF_DELWRI | _XBF_DELWRI_Q | XBF_ASYNC; |
1570 | list_add_tail(&bp->b_list, &btp->bt_delwri_queue); | ||
1571 | } | ||
1596 | bp->b_queuetime = jiffies; | 1572 | bp->b_queuetime = jiffies; |
1597 | spin_unlock(dwlk); | 1573 | spin_unlock(&btp->bt_delwri_lock); |
1598 | |||
1599 | if (unlock) | ||
1600 | xfs_buf_unlock(bp); | ||
1601 | } | 1574 | } |
1602 | 1575 | ||
1603 | void | 1576 | void |
1604 | xfs_buf_delwri_dequeue( | 1577 | xfs_buf_delwri_dequeue( |
1605 | xfs_buf_t *bp) | 1578 | xfs_buf_t *bp) |
1606 | { | 1579 | { |
1607 | spinlock_t *dwlk = &bp->b_target->bt_delwrite_lock; | ||
1608 | int dequeued = 0; | 1580 | int dequeued = 0; |
1609 | 1581 | ||
1610 | spin_lock(dwlk); | 1582 | spin_lock(&bp->b_target->bt_delwri_lock); |
1611 | if ((bp->b_flags & XBF_DELWRI) && !list_empty(&bp->b_list)) { | 1583 | if ((bp->b_flags & XBF_DELWRI) && !list_empty(&bp->b_list)) { |
1612 | ASSERT(bp->b_flags & _XBF_DELWRI_Q); | 1584 | ASSERT(bp->b_flags & _XBF_DELWRI_Q); |
1613 | list_del_init(&bp->b_list); | 1585 | list_del_init(&bp->b_list); |
1614 | dequeued = 1; | 1586 | dequeued = 1; |
1615 | } | 1587 | } |
1616 | bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); | 1588 | bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); |
1617 | spin_unlock(dwlk); | 1589 | spin_unlock(&bp->b_target->bt_delwri_lock); |
1618 | 1590 | ||
1619 | if (dequeued) | 1591 | if (dequeued) |
1620 | xfs_buf_rele(bp); | 1592 | xfs_buf_rele(bp); |
@@ -1646,16 +1618,9 @@ xfs_buf_delwri_promote( | |||
1646 | if (bp->b_queuetime < jiffies - age) | 1618 | if (bp->b_queuetime < jiffies - age) |
1647 | return; | 1619 | return; |
1648 | bp->b_queuetime = jiffies - age; | 1620 | bp->b_queuetime = jiffies - age; |
1649 | spin_lock(&btp->bt_delwrite_lock); | 1621 | spin_lock(&btp->bt_delwri_lock); |
1650 | list_move(&bp->b_list, &btp->bt_delwrite_queue); | 1622 | list_move(&bp->b_list, &btp->bt_delwri_queue); |
1651 | spin_unlock(&btp->bt_delwrite_lock); | 1623 | spin_unlock(&btp->bt_delwri_lock); |
1652 | } | ||
1653 | |||
1654 | STATIC void | ||
1655 | xfs_buf_runall_queues( | ||
1656 | struct workqueue_struct *queue) | ||
1657 | { | ||
1658 | flush_workqueue(queue); | ||
1659 | } | 1624 | } |
1660 | 1625 | ||
1661 | /* | 1626 | /* |
@@ -1669,15 +1634,13 @@ xfs_buf_delwri_split( | |||
1669 | unsigned long age) | 1634 | unsigned long age) |
1670 | { | 1635 | { |
1671 | xfs_buf_t *bp, *n; | 1636 | xfs_buf_t *bp, *n; |
1672 | struct list_head *dwq = &target->bt_delwrite_queue; | ||
1673 | spinlock_t *dwlk = &target->bt_delwrite_lock; | ||
1674 | int skipped = 0; | 1637 | int skipped = 0; |
1675 | int force; | 1638 | int force; |
1676 | 1639 | ||
1677 | force = test_and_clear_bit(XBT_FORCE_FLUSH, &target->bt_flags); | 1640 | force = test_and_clear_bit(XBT_FORCE_FLUSH, &target->bt_flags); |
1678 | INIT_LIST_HEAD(list); | 1641 | INIT_LIST_HEAD(list); |
1679 | spin_lock(dwlk); | 1642 | spin_lock(&target->bt_delwri_lock); |
1680 | list_for_each_entry_safe(bp, n, dwq, b_list) { | 1643 | list_for_each_entry_safe(bp, n, &target->bt_delwri_queue, b_list) { |
1681 | ASSERT(bp->b_flags & XBF_DELWRI); | 1644 | ASSERT(bp->b_flags & XBF_DELWRI); |
1682 | 1645 | ||
1683 | if (!xfs_buf_ispinned(bp) && xfs_buf_trylock(bp)) { | 1646 | if (!xfs_buf_ispinned(bp) && xfs_buf_trylock(bp)) { |
@@ -1694,10 +1657,9 @@ xfs_buf_delwri_split( | |||
1694 | } else | 1657 | } else |
1695 | skipped++; | 1658 | skipped++; |
1696 | } | 1659 | } |
1697 | spin_unlock(dwlk); | ||
1698 | 1660 | ||
1661 | spin_unlock(&target->bt_delwri_lock); | ||
1699 | return skipped; | 1662 | return skipped; |
1700 | |||
1701 | } | 1663 | } |
1702 | 1664 | ||
1703 | /* | 1665 | /* |
@@ -1747,7 +1709,7 @@ xfsbufd( | |||
1747 | } | 1709 | } |
1748 | 1710 | ||
1749 | /* sleep for a long time if there is nothing to do. */ | 1711 | /* sleep for a long time if there is nothing to do. */ |
1750 | if (list_empty(&target->bt_delwrite_queue)) | 1712 | if (list_empty(&target->bt_delwri_queue)) |
1751 | tout = MAX_SCHEDULE_TIMEOUT; | 1713 | tout = MAX_SCHEDULE_TIMEOUT; |
1752 | schedule_timeout_interruptible(tout); | 1714 | schedule_timeout_interruptible(tout); |
1753 | 1715 | ||
@@ -1783,9 +1745,7 @@ xfs_flush_buftarg( | |||
1783 | LIST_HEAD(wait_list); | 1745 | LIST_HEAD(wait_list); |
1784 | struct blk_plug plug; | 1746 | struct blk_plug plug; |
1785 | 1747 | ||
1786 | xfs_buf_runall_queues(xfsconvertd_workqueue); | 1748 | flush_workqueue(xfslogd_workqueue); |
1787 | xfs_buf_runall_queues(xfsdatad_workqueue); | ||
1788 | xfs_buf_runall_queues(xfslogd_workqueue); | ||
1789 | 1749 | ||
1790 | set_bit(XBT_FORCE_FLUSH, &target->bt_flags); | 1750 | set_bit(XBT_FORCE_FLUSH, &target->bt_flags); |
1791 | pincount = xfs_buf_delwri_split(target, &tmp_list, 0); | 1751 | pincount = xfs_buf_delwri_split(target, &tmp_list, 0); |
@@ -1866,11 +1826,3 @@ xfs_buf_terminate(void) | |||
1866 | destroy_workqueue(xfslogd_workqueue); | 1826 | destroy_workqueue(xfslogd_workqueue); |
1867 | kmem_zone_destroy(xfs_buf_zone); | 1827 | kmem_zone_destroy(xfs_buf_zone); |
1868 | } | 1828 | } |
1869 | |||
1870 | #ifdef CONFIG_KDB_MODULES | ||
1871 | struct list_head * | ||
1872 | xfs_get_buftarg_list(void) | ||
1873 | { | ||
1874 | return &xfs_buftarg_list; | ||
1875 | } | ||
1876 | #endif | ||