diff options
author | Carlos Maiolino <cmaiolino@redhat.com> | 2018-01-24 16:38:49 -0500 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-01-29 10:27:22 -0500 |
commit | 643c8c05e75d978c55ceb584f21a16de5431c17d (patch) | |
tree | 202cba5d5e23b81aa45747a6299699bbff61b001 | |
parent | fb1755a645972ed096047583600838f6cf414e2b (diff) |
Use list_head infra-structure for buffer's log items list
Now that buffer's b_fspriv has been split, just replace the current
singly linked list of xfs_log_items, by the list_head infrastructure.
Also, remove the xfs_log_item argument from xfs_buf_resubmit_failed_buffers(),
there is no need for this argument, once the log items can be walked
through the list_head in the buffer.
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Bill O'Donnell <billodo@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
[darrick: minor style cleanups]
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r-- | fs/xfs/xfs_buf.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 57 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot_item.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 41 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 2 |
9 files changed, 44 insertions, 71 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 0820c1ccf97c..d1da2ee9e6db 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -236,6 +236,7 @@ _xfs_buf_alloc( | |||
236 | init_completion(&bp->b_iowait); | 236 | init_completion(&bp->b_iowait); |
237 | INIT_LIST_HEAD(&bp->b_lru); | 237 | INIT_LIST_HEAD(&bp->b_lru); |
238 | INIT_LIST_HEAD(&bp->b_list); | 238 | INIT_LIST_HEAD(&bp->b_list); |
239 | INIT_LIST_HEAD(&bp->b_li_list); | ||
239 | sema_init(&bp->b_sema, 0); /* held, no waiters */ | 240 | sema_init(&bp->b_sema, 0); /* held, no waiters */ |
240 | spin_lock_init(&bp->b_lock); | 241 | spin_lock_init(&bp->b_lock); |
241 | XB_SET_OWNER(bp); | 242 | XB_SET_OWNER(bp); |
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 6fcba7536d7e..2f4c91452861 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h | |||
@@ -177,7 +177,7 @@ typedef struct xfs_buf { | |||
177 | xfs_buf_iodone_t b_iodone; /* I/O completion function */ | 177 | xfs_buf_iodone_t b_iodone; /* I/O completion function */ |
178 | struct completion b_iowait; /* queue for I/O waiters */ | 178 | struct completion b_iowait; /* queue for I/O waiters */ |
179 | void *b_log_item; | 179 | void *b_log_item; |
180 | struct xfs_log_item *b_li_list; | 180 | struct list_head b_li_list; /* Log items list head */ |
181 | struct xfs_trans *b_transp; | 181 | struct xfs_trans *b_transp; |
182 | struct page **b_pages; /* array of page pointers */ | 182 | struct page **b_pages; /* array of page pointers */ |
183 | struct page *b_page_array[XB_PAGES]; /* inline pages */ | 183 | struct page *b_page_array[XB_PAGES]; /* inline pages */ |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 8354fab9796e..270ddb4d2313 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -457,7 +457,7 @@ xfs_buf_item_unpin( | |||
457 | if (bip->bli_flags & XFS_BLI_STALE_INODE) { | 457 | if (bip->bli_flags & XFS_BLI_STALE_INODE) { |
458 | xfs_buf_do_callbacks(bp); | 458 | xfs_buf_do_callbacks(bp); |
459 | bp->b_log_item = NULL; | 459 | bp->b_log_item = NULL; |
460 | bp->b_li_list = NULL; | 460 | list_del_init(&bp->b_li_list); |
461 | bp->b_iodone = NULL; | 461 | bp->b_iodone = NULL; |
462 | } else { | 462 | } else { |
463 | spin_lock(&ailp->xa_lock); | 463 | spin_lock(&ailp->xa_lock); |
@@ -955,13 +955,12 @@ xfs_buf_item_relse( | |||
955 | xfs_buf_t *bp) | 955 | xfs_buf_t *bp) |
956 | { | 956 | { |
957 | struct xfs_buf_log_item *bip = bp->b_log_item; | 957 | struct xfs_buf_log_item *bip = bp->b_log_item; |
958 | struct xfs_log_item *lip = bp->b_li_list; | ||
959 | 958 | ||
960 | trace_xfs_buf_item_relse(bp, _RET_IP_); | 959 | trace_xfs_buf_item_relse(bp, _RET_IP_); |
961 | ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL)); | 960 | ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL)); |
962 | 961 | ||
963 | bp->b_log_item = NULL; | 962 | bp->b_log_item = NULL; |
964 | if (lip == NULL) | 963 | if (list_empty(&bp->b_li_list)) |
965 | bp->b_iodone = NULL; | 964 | bp->b_iodone = NULL; |
966 | 965 | ||
967 | xfs_buf_rele(bp); | 966 | xfs_buf_rele(bp); |
@@ -982,18 +981,10 @@ xfs_buf_attach_iodone( | |||
982 | void (*cb)(xfs_buf_t *, xfs_log_item_t *), | 981 | void (*cb)(xfs_buf_t *, xfs_log_item_t *), |
983 | xfs_log_item_t *lip) | 982 | xfs_log_item_t *lip) |
984 | { | 983 | { |
985 | xfs_log_item_t *head_lip; | ||
986 | |||
987 | ASSERT(xfs_buf_islocked(bp)); | 984 | ASSERT(xfs_buf_islocked(bp)); |
988 | 985 | ||
989 | lip->li_cb = cb; | 986 | lip->li_cb = cb; |
990 | head_lip = bp->b_li_list; | 987 | list_add_tail(&lip->li_bio_list, &bp->b_li_list); |
991 | if (head_lip) { | ||
992 | lip->li_bio_list = head_lip->li_bio_list; | ||
993 | head_lip->li_bio_list = lip; | ||
994 | } else { | ||
995 | bp->b_li_list = lip; | ||
996 | } | ||
997 | 988 | ||
998 | ASSERT(bp->b_iodone == NULL || | 989 | ASSERT(bp->b_iodone == NULL || |
999 | bp->b_iodone == xfs_buf_iodone_callbacks); | 990 | bp->b_iodone == xfs_buf_iodone_callbacks); |
@@ -1003,12 +994,12 @@ xfs_buf_attach_iodone( | |||
1003 | /* | 994 | /* |
1004 | * We can have many callbacks on a buffer. Running the callbacks individually | 995 | * We can have many callbacks on a buffer. Running the callbacks individually |
1005 | * can cause a lot of contention on the AIL lock, so we allow for a single | 996 | * can cause a lot of contention on the AIL lock, so we allow for a single |
1006 | * callback to be able to scan the remaining lip->li_bio_list for other items | 997 | * callback to be able to scan the remaining items in bp->b_li_list for other |
1007 | * of the same type and callback to be processed in the first call. | 998 | * items of the same type and callback to be processed in the first call. |
1008 | * | 999 | * |
1009 | * As a result, the loop walking the callback list below will also modify the | 1000 | * As a result, the loop walking the callback list below will also modify the |
1010 | * list. it removes the first item from the list and then runs the callback. | 1001 | * list. it removes the first item from the list and then runs the callback. |
1011 | * The loop then restarts from the new head of the list. This allows the | 1002 | * The loop then restarts from the new first item int the list. This allows the |
1012 | * callback to scan and modify the list attached to the buffer and we don't | 1003 | * callback to scan and modify the list attached to the buffer and we don't |
1013 | * have to care about maintaining a next item pointer. | 1004 | * have to care about maintaining a next item pointer. |
1014 | */ | 1005 | */ |
@@ -1025,16 +1016,17 @@ xfs_buf_do_callbacks( | |||
1025 | lip->li_cb(bp, lip); | 1016 | lip->li_cb(bp, lip); |
1026 | } | 1017 | } |
1027 | 1018 | ||
1028 | while ((lip = bp->b_li_list) != NULL) { | 1019 | while (!list_empty(&bp->b_li_list)) { |
1029 | bp->b_li_list = lip->li_bio_list; | 1020 | lip = list_first_entry(&bp->b_li_list, struct xfs_log_item, |
1030 | ASSERT(lip->li_cb != NULL); | 1021 | li_bio_list); |
1022 | |||
1031 | /* | 1023 | /* |
1032 | * Clear the next pointer so we don't have any | 1024 | * Remove the item from the list, so we don't have any |
1033 | * confusion if the item is added to another buf. | 1025 | * confusion if the item is added to another buf. |
1034 | * Don't touch the log item after calling its | 1026 | * Don't touch the log item after calling its |
1035 | * callback, because it could have freed itself. | 1027 | * callback, because it could have freed itself. |
1036 | */ | 1028 | */ |
1037 | lip->li_bio_list = NULL; | 1029 | list_del_init(&lip->li_bio_list); |
1038 | lip->li_cb(bp, lip); | 1030 | lip->li_cb(bp, lip); |
1039 | } | 1031 | } |
1040 | } | 1032 | } |
@@ -1051,8 +1043,7 @@ STATIC void | |||
1051 | xfs_buf_do_callbacks_fail( | 1043 | xfs_buf_do_callbacks_fail( |
1052 | struct xfs_buf *bp) | 1044 | struct xfs_buf *bp) |
1053 | { | 1045 | { |
1054 | struct xfs_log_item *lip = bp->b_li_list; | 1046 | struct xfs_log_item *lip; |
1055 | struct xfs_log_item *next; | ||
1056 | struct xfs_ail *ailp; | 1047 | struct xfs_ail *ailp; |
1057 | 1048 | ||
1058 | /* | 1049 | /* |
@@ -1060,13 +1051,14 @@ xfs_buf_do_callbacks_fail( | |||
1060 | * and xfs_buf_iodone_callback_error, and they have no IO error | 1051 | * and xfs_buf_iodone_callback_error, and they have no IO error |
1061 | * callbacks. Check only for items in b_li_list. | 1052 | * callbacks. Check only for items in b_li_list. |
1062 | */ | 1053 | */ |
1063 | if (lip == NULL) | 1054 | if (list_empty(&bp->b_li_list)) |
1064 | return; | 1055 | return; |
1065 | 1056 | ||
1057 | lip = list_first_entry(&bp->b_li_list, struct xfs_log_item, | ||
1058 | li_bio_list); | ||
1066 | ailp = lip->li_ailp; | 1059 | ailp = lip->li_ailp; |
1067 | spin_lock(&ailp->xa_lock); | 1060 | spin_lock(&ailp->xa_lock); |
1068 | for (; lip; lip = next) { | 1061 | list_for_each_entry(lip, &bp->b_li_list, li_bio_list) { |
1069 | next = lip->li_bio_list; | ||
1070 | if (lip->li_ops->iop_error) | 1062 | if (lip->li_ops->iop_error) |
1071 | lip->li_ops->iop_error(lip, bp); | 1063 | lip->li_ops->iop_error(lip, bp); |
1072 | } | 1064 | } |
@@ -1078,7 +1070,7 @@ xfs_buf_iodone_callback_error( | |||
1078 | struct xfs_buf *bp) | 1070 | struct xfs_buf *bp) |
1079 | { | 1071 | { |
1080 | struct xfs_buf_log_item *bip = bp->b_log_item; | 1072 | struct xfs_buf_log_item *bip = bp->b_log_item; |
1081 | struct xfs_log_item *lip = bp->b_li_list; | 1073 | struct xfs_log_item *lip; |
1082 | struct xfs_mount *mp; | 1074 | struct xfs_mount *mp; |
1083 | static ulong lasttime; | 1075 | static ulong lasttime; |
1084 | static xfs_buftarg_t *lasttarg; | 1076 | static xfs_buftarg_t *lasttarg; |
@@ -1089,7 +1081,9 @@ xfs_buf_iodone_callback_error( | |||
1089 | * log_item list might be empty. Get the mp from the available | 1081 | * log_item list might be empty. Get the mp from the available |
1090 | * xfs_log_item | 1082 | * xfs_log_item |
1091 | */ | 1083 | */ |
1092 | mp = bip ? bip->bli_item.li_mountp : lip->li_mountp; | 1084 | lip = list_first_entry_or_null(&bp->b_li_list, struct xfs_log_item, |
1085 | li_bio_list); | ||
1086 | mp = lip ? lip->li_mountp : bip->bli_item.li_mountp; | ||
1093 | 1087 | ||
1094 | /* | 1088 | /* |
1095 | * If we've already decided to shutdown the filesystem because of | 1089 | * If we've already decided to shutdown the filesystem because of |
@@ -1200,7 +1194,7 @@ xfs_buf_iodone_callbacks( | |||
1200 | 1194 | ||
1201 | xfs_buf_do_callbacks(bp); | 1195 | xfs_buf_do_callbacks(bp); |
1202 | bp->b_log_item = NULL; | 1196 | bp->b_log_item = NULL; |
1203 | bp->b_li_list = NULL; | 1197 | list_del_init(&bp->b_li_list); |
1204 | bp->b_iodone = NULL; | 1198 | bp->b_iodone = NULL; |
1205 | xfs_buf_ioend(bp); | 1199 | xfs_buf_ioend(bp); |
1206 | } | 1200 | } |
@@ -1245,10 +1239,9 @@ xfs_buf_iodone( | |||
1245 | bool | 1239 | bool |
1246 | xfs_buf_resubmit_failed_buffers( | 1240 | xfs_buf_resubmit_failed_buffers( |
1247 | struct xfs_buf *bp, | 1241 | struct xfs_buf *bp, |
1248 | struct xfs_log_item *lip, | ||
1249 | struct list_head *buffer_list) | 1242 | struct list_head *buffer_list) |
1250 | { | 1243 | { |
1251 | struct xfs_log_item *next; | 1244 | struct xfs_log_item *lip; |
1252 | 1245 | ||
1253 | /* | 1246 | /* |
1254 | * Clear XFS_LI_FAILED flag from all items before resubmit | 1247 | * Clear XFS_LI_FAILED flag from all items before resubmit |
@@ -1256,10 +1249,8 @@ xfs_buf_resubmit_failed_buffers( | |||
1256 | * XFS_LI_FAILED set/clear is protected by xa_lock, caller this | 1249 | * XFS_LI_FAILED set/clear is protected by xa_lock, caller this |
1257 | * function already have it acquired | 1250 | * function already have it acquired |
1258 | */ | 1251 | */ |
1259 | for (; lip; lip = next) { | 1252 | list_for_each_entry(lip, &bp->b_li_list, li_bio_list) |
1260 | next = lip->li_bio_list; | ||
1261 | xfs_clear_li_failed(lip); | 1253 | xfs_clear_li_failed(lip); |
1262 | } | ||
1263 | 1254 | ||
1264 | /* Add this buffer back to the delayed write list */ | 1255 | /* Add this buffer back to the delayed write list */ |
1265 | return xfs_buf_delwri_queue(bp, buffer_list); | 1256 | return xfs_buf_delwri_queue(bp, buffer_list); |
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index 0febfbbf6ba9..643f53dcfe51 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h | |||
@@ -71,7 +71,6 @@ void xfs_buf_attach_iodone(struct xfs_buf *, | |||
71 | void xfs_buf_iodone_callbacks(struct xfs_buf *); | 71 | void xfs_buf_iodone_callbacks(struct xfs_buf *); |
72 | void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *); | 72 | void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *); |
73 | bool xfs_buf_resubmit_failed_buffers(struct xfs_buf *, | 73 | bool xfs_buf_resubmit_failed_buffers(struct xfs_buf *, |
74 | struct xfs_log_item *, | ||
75 | struct list_head *); | 74 | struct list_head *); |
76 | 75 | ||
77 | extern kmem_zone_t *xfs_buf_item_zone; | 76 | extern kmem_zone_t *xfs_buf_item_zone; |
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 51ee848a550e..96eaa6933709 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c | |||
@@ -176,7 +176,7 @@ xfs_qm_dquot_logitem_push( | |||
176 | if (!xfs_buf_trylock(bp)) | 176 | if (!xfs_buf_trylock(bp)) |
177 | return XFS_ITEM_LOCKED; | 177 | return XFS_ITEM_LOCKED; |
178 | 178 | ||
179 | if (!xfs_buf_resubmit_failed_buffers(bp, lip, buffer_list)) | 179 | if (!xfs_buf_resubmit_failed_buffers(bp, buffer_list)) |
180 | rval = XFS_ITEM_FLUSHING; | 180 | rval = XFS_ITEM_FLUSHING; |
181 | 181 | ||
182 | xfs_buf_unlock(bp); | 182 | xfs_buf_unlock(bp); |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8a3ff6343d91..c66effc8e7dd 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -2214,7 +2214,7 @@ xfs_ifree_cluster( | |||
2214 | xfs_buf_t *bp; | 2214 | xfs_buf_t *bp; |
2215 | xfs_inode_t *ip; | 2215 | xfs_inode_t *ip; |
2216 | xfs_inode_log_item_t *iip; | 2216 | xfs_inode_log_item_t *iip; |
2217 | xfs_log_item_t *lip; | 2217 | struct xfs_log_item *lip; |
2218 | struct xfs_perag *pag; | 2218 | struct xfs_perag *pag; |
2219 | xfs_ino_t inum; | 2219 | xfs_ino_t inum; |
2220 | 2220 | ||
@@ -2272,8 +2272,7 @@ xfs_ifree_cluster( | |||
2272 | * stale first, we will not attempt to lock them in the loop | 2272 | * stale first, we will not attempt to lock them in the loop |
2273 | * below as the XFS_ISTALE flag will be set. | 2273 | * below as the XFS_ISTALE flag will be set. |
2274 | */ | 2274 | */ |
2275 | lip = bp->b_li_list; | 2275 | list_for_each_entry(lip, &bp->b_li_list, li_bio_list) { |
2276 | while (lip) { | ||
2277 | if (lip->li_type == XFS_LI_INODE) { | 2276 | if (lip->li_type == XFS_LI_INODE) { |
2278 | iip = (xfs_inode_log_item_t *)lip; | 2277 | iip = (xfs_inode_log_item_t *)lip; |
2279 | ASSERT(iip->ili_logged == 1); | 2278 | ASSERT(iip->ili_logged == 1); |
@@ -2283,7 +2282,6 @@ xfs_ifree_cluster( | |||
2283 | &iip->ili_item.li_lsn); | 2282 | &iip->ili_item.li_lsn); |
2284 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | 2283 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); |
2285 | } | 2284 | } |
2286 | lip = lip->li_bio_list; | ||
2287 | } | 2285 | } |
2288 | 2286 | ||
2289 | 2287 | ||
@@ -3649,7 +3647,7 @@ xfs_iflush_int( | |||
3649 | /* generate the checksum. */ | 3647 | /* generate the checksum. */ |
3650 | xfs_dinode_calc_crc(mp, dip); | 3648 | xfs_dinode_calc_crc(mp, dip); |
3651 | 3649 | ||
3652 | ASSERT(bp->b_li_list != NULL); | 3650 | ASSERT(!list_empty(&bp->b_li_list)); |
3653 | ASSERT(bp->b_iodone != NULL); | 3651 | ASSERT(bp->b_iodone != NULL); |
3654 | return 0; | 3652 | return 0; |
3655 | 3653 | ||
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 993736032b4b..ddfc2c80af5e 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -521,7 +521,7 @@ xfs_inode_item_push( | |||
521 | if (!xfs_buf_trylock(bp)) | 521 | if (!xfs_buf_trylock(bp)) |
522 | return XFS_ITEM_LOCKED; | 522 | return XFS_ITEM_LOCKED; |
523 | 523 | ||
524 | if (!xfs_buf_resubmit_failed_buffers(bp, lip, buffer_list)) | 524 | if (!xfs_buf_resubmit_failed_buffers(bp, buffer_list)) |
525 | rval = XFS_ITEM_FLUSHING; | 525 | rval = XFS_ITEM_FLUSHING; |
526 | 526 | ||
527 | xfs_buf_unlock(bp); | 527 | xfs_buf_unlock(bp); |
@@ -712,37 +712,23 @@ xfs_iflush_done( | |||
712 | struct xfs_log_item *lip) | 712 | struct xfs_log_item *lip) |
713 | { | 713 | { |
714 | struct xfs_inode_log_item *iip; | 714 | struct xfs_inode_log_item *iip; |
715 | struct xfs_log_item *blip; | 715 | struct xfs_log_item *blip, *n; |
716 | struct xfs_log_item *next; | ||
717 | struct xfs_log_item *prev; | ||
718 | struct xfs_ail *ailp = lip->li_ailp; | 716 | struct xfs_ail *ailp = lip->li_ailp; |
719 | int need_ail = 0; | 717 | int need_ail = 0; |
718 | LIST_HEAD(tmp); | ||
720 | 719 | ||
721 | /* | 720 | /* |
722 | * Scan the buffer IO completions for other inodes being completed and | 721 | * Scan the buffer IO completions for other inodes being completed and |
723 | * attach them to the current inode log item. | 722 | * attach them to the current inode log item. |
724 | */ | 723 | */ |
725 | blip = bp->b_li_list; | ||
726 | prev = NULL; | ||
727 | while (blip != NULL) { | ||
728 | if (blip->li_cb != xfs_iflush_done) { | ||
729 | prev = blip; | ||
730 | blip = blip->li_bio_list; | ||
731 | continue; | ||
732 | } | ||
733 | 724 | ||
734 | /* remove from list */ | 725 | list_add_tail(&lip->li_bio_list, &tmp); |
735 | next = blip->li_bio_list; | ||
736 | if (!prev) { | ||
737 | bp->b_li_list = next; | ||
738 | } else { | ||
739 | prev->li_bio_list = next; | ||
740 | } | ||
741 | 726 | ||
742 | /* add to current list */ | 727 | list_for_each_entry_safe(blip, n, &bp->b_li_list, li_bio_list) { |
743 | blip->li_bio_list = lip->li_bio_list; | 728 | if (lip->li_cb != xfs_iflush_done) |
744 | lip->li_bio_list = blip; | 729 | continue; |
745 | 730 | ||
731 | list_move_tail(&blip->li_bio_list, &tmp); | ||
746 | /* | 732 | /* |
747 | * while we have the item, do the unlocked check for needing | 733 | * while we have the item, do the unlocked check for needing |
748 | * the AIL lock. | 734 | * the AIL lock. |
@@ -751,8 +737,6 @@ xfs_iflush_done( | |||
751 | if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) || | 737 | if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) || |
752 | (blip->li_flags & XFS_LI_FAILED)) | 738 | (blip->li_flags & XFS_LI_FAILED)) |
753 | need_ail++; | 739 | need_ail++; |
754 | |||
755 | blip = next; | ||
756 | } | 740 | } |
757 | 741 | ||
758 | /* make sure we capture the state of the initial inode. */ | 742 | /* make sure we capture the state of the initial inode. */ |
@@ -775,7 +759,7 @@ xfs_iflush_done( | |||
775 | 759 | ||
776 | /* this is an opencoded batch version of xfs_trans_ail_delete */ | 760 | /* this is an opencoded batch version of xfs_trans_ail_delete */ |
777 | spin_lock(&ailp->xa_lock); | 761 | spin_lock(&ailp->xa_lock); |
778 | for (blip = lip; blip; blip = blip->li_bio_list) { | 762 | list_for_each_entry(blip, &tmp, li_bio_list) { |
779 | if (INODE_ITEM(blip)->ili_logged && | 763 | if (INODE_ITEM(blip)->ili_logged && |
780 | blip->li_lsn == INODE_ITEM(blip)->ili_flush_lsn) | 764 | blip->li_lsn == INODE_ITEM(blip)->ili_flush_lsn) |
781 | mlip_changed |= xfs_ail_delete_one(ailp, blip); | 765 | mlip_changed |= xfs_ail_delete_one(ailp, blip); |
@@ -801,15 +785,14 @@ xfs_iflush_done( | |||
801 | * ili_last_fields bits now that we know that the data corresponding to | 785 | * ili_last_fields bits now that we know that the data corresponding to |
802 | * them is safely on disk. | 786 | * them is safely on disk. |
803 | */ | 787 | */ |
804 | for (blip = lip; blip; blip = next) { | 788 | list_for_each_entry_safe(blip, n, &tmp, li_bio_list) { |
805 | next = blip->li_bio_list; | 789 | list_del_init(&blip->li_bio_list); |
806 | blip->li_bio_list = NULL; | ||
807 | |||
808 | iip = INODE_ITEM(blip); | 790 | iip = INODE_ITEM(blip); |
809 | iip->ili_logged = 0; | 791 | iip->ili_logged = 0; |
810 | iip->ili_last_fields = 0; | 792 | iip->ili_last_fields = 0; |
811 | xfs_ifunlock(iip->ili_inode); | 793 | xfs_ifunlock(iip->ili_inode); |
812 | } | 794 | } |
795 | list_del(&tmp); | ||
813 | } | 796 | } |
814 | 797 | ||
815 | /* | 798 | /* |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 20483b654ef1..3e5ba1ecc080 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1047,6 +1047,7 @@ xfs_log_item_init( | |||
1047 | 1047 | ||
1048 | INIT_LIST_HEAD(&item->li_ail); | 1048 | INIT_LIST_HEAD(&item->li_ail); |
1049 | INIT_LIST_HEAD(&item->li_cil); | 1049 | INIT_LIST_HEAD(&item->li_cil); |
1050 | INIT_LIST_HEAD(&item->li_bio_list); | ||
1050 | } | 1051 | } |
1051 | 1052 | ||
1052 | /* | 1053 | /* |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 815b53d20e26..9d542dfe0052 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -50,7 +50,7 @@ typedef struct xfs_log_item { | |||
50 | uint li_type; /* item type */ | 50 | uint li_type; /* item type */ |
51 | uint li_flags; /* misc flags */ | 51 | uint li_flags; /* misc flags */ |
52 | struct xfs_buf *li_buf; /* real buffer pointer */ | 52 | struct xfs_buf *li_buf; /* real buffer pointer */ |
53 | struct xfs_log_item *li_bio_list; /* buffer item list */ | 53 | struct list_head li_bio_list; /* buffer item list */ |
54 | void (*li_cb)(struct xfs_buf *, | 54 | void (*li_cb)(struct xfs_buf *, |
55 | struct xfs_log_item *); | 55 | struct xfs_log_item *); |
56 | /* buffer item iodone */ | 56 | /* buffer item iodone */ |