aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_trans_buf.c184
1 files changed, 46 insertions, 138 deletions
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 4e1b6892c106..9cd809025f3a 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -40,11 +40,51 @@
40#include "xfs_rw.h" 40#include "xfs_rw.h"
41#include "xfs_trace.h" 41#include "xfs_trace.h"
42 42
43/*
44 * Check to see if a buffer matching the given parameters is already
45 * a part of the given transaction.
46 */
47STATIC struct xfs_buf *
48xfs_trans_buf_item_match(
49 struct xfs_trans *tp,
50 struct xfs_buftarg *target,
51 xfs_daddr_t blkno,
52 int len)
53{
54 xfs_log_item_chunk_t *licp;
55 xfs_log_item_desc_t *lidp;
56 xfs_buf_log_item_t *blip;
57 int i;
43 58
44STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *, 59 len = BBTOB(len);
45 xfs_daddr_t, int); 60 for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) {
46STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *, 61 if (xfs_lic_are_all_free(licp)) {
47 xfs_daddr_t, int); 62 ASSERT(licp == &tp->t_items);
63 ASSERT(licp->lic_next == NULL);
64 return NULL;
65 }
66
67 for (i = 0; i < licp->lic_unused; i++) {
68 /*
69 * Skip unoccupied slots.
70 */
71 if (xfs_lic_isfree(licp, i))
72 continue;
73
74 lidp = xfs_lic_slot(licp, i);
75 blip = (xfs_buf_log_item_t *)lidp->lid_item;
76 if (blip->bli_item.li_type != XFS_LI_BUF)
77 continue;
78
79 if (XFS_BUF_TARGET(blip->bli_buf) == target &&
80 XFS_BUF_ADDR(blip->bli_buf) == blkno &&
81 XFS_BUF_COUNT(blip->bli_buf) == len)
82 return blip->bli_buf;
83 }
84 }
85
86 return NULL;
87}
48 88
49/* 89/*
50 * Add the locked buffer to the transaction. 90 * Add the locked buffer to the transaction.
@@ -112,14 +152,6 @@ xfs_trans_bjoin(
112 * within the transaction, just increment its lock recursion count 152 * within the transaction, just increment its lock recursion count
113 * and return a pointer to it. 153 * and return a pointer to it.
114 * 154 *
115 * Use the fast path function xfs_trans_buf_item_match() or the buffer
116 * cache routine incore_match() to find the buffer
117 * if it is already owned by this transaction.
118 *
119 * If we don't already own the buffer, use get_buf() to get it.
120 * If it doesn't yet have an associated xfs_buf_log_item structure,
121 * then allocate one and add the item to this transaction.
122 *
123 * If the transaction pointer is NULL, make this just a normal 155 * If the transaction pointer is NULL, make this just a normal
124 * get_buf() call. 156 * get_buf() call.
125 */ 157 */
@@ -149,11 +181,7 @@ xfs_trans_get_buf(xfs_trans_t *tp,
149 * have it locked. In this case we just increment the lock 181 * have it locked. In this case we just increment the lock
150 * recursion count and return the buffer to the caller. 182 * recursion count and return the buffer to the caller.
151 */ 183 */
152 if (tp->t_items.lic_next == NULL) { 184 bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len);
153 bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len);
154 } else {
155 bp = xfs_trans_buf_item_match_all(tp, target_dev, blkno, len);
156 }
157 if (bp != NULL) { 185 if (bp != NULL) {
158 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); 186 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
159 if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) 187 if (XFS_FORCED_SHUTDOWN(tp->t_mountp))
@@ -259,14 +287,6 @@ int xfs_error_mod = 33;
259 * within the transaction and already read in, just increment its 287 * within the transaction and already read in, just increment its
260 * lock recursion count and return a pointer to it. 288 * lock recursion count and return a pointer to it.
261 * 289 *
262 * Use the fast path function xfs_trans_buf_item_match() or the buffer
263 * cache routine incore_match() to find the buffer
264 * if it is already owned by this transaction.
265 *
266 * If we don't already own the buffer, use read_buf() to get it.
267 * If it doesn't yet have an associated xfs_buf_log_item structure,
268 * then allocate one and add the item to this transaction.
269 *
270 * If the transaction pointer is NULL, make this just a normal 290 * If the transaction pointer is NULL, make this just a normal
271 * read_buf() call. 291 * read_buf() call.
272 */ 292 */
@@ -328,11 +348,7 @@ xfs_trans_read_buf(
328 * If the buffer is not yet read in, then we read it in, increment 348 * If the buffer is not yet read in, then we read it in, increment
329 * the lock recursion count, and return it to the caller. 349 * the lock recursion count, and return it to the caller.
330 */ 350 */
331 if (tp->t_items.lic_next == NULL) { 351 bp = xfs_trans_buf_item_match(tp, target, blkno, len);
332 bp = xfs_trans_buf_item_match(tp, target, blkno, len);
333 } else {
334 bp = xfs_trans_buf_item_match_all(tp, target, blkno, len);
335 }
336 if (bp != NULL) { 352 if (bp != NULL) {
337 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); 353 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
338 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 354 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
@@ -901,111 +917,3 @@ xfs_trans_dquot_buf(
901 917
902 bip->bli_format.blf_flags |= type; 918 bip->bli_format.blf_flags |= type;
903} 919}
904
905/*
906 * Check to see if a buffer matching the given parameters is already
907 * a part of the given transaction. Only check the first, embedded
908 * chunk, since we don't want to spend all day scanning large transactions.
909 */
910STATIC xfs_buf_t *
911xfs_trans_buf_item_match(
912 xfs_trans_t *tp,
913 xfs_buftarg_t *target,
914 xfs_daddr_t blkno,
915 int len)
916{
917 xfs_log_item_chunk_t *licp;
918 xfs_log_item_desc_t *lidp;
919 xfs_buf_log_item_t *blip;
920 xfs_buf_t *bp;
921 int i;
922
923 bp = NULL;
924 len = BBTOB(len);
925 licp = &tp->t_items;
926 if (!xfs_lic_are_all_free(licp)) {
927 for (i = 0; i < licp->lic_unused; i++) {
928 /*
929 * Skip unoccupied slots.
930 */
931 if (xfs_lic_isfree(licp, i)) {
932 continue;
933 }
934
935 lidp = xfs_lic_slot(licp, i);
936 blip = (xfs_buf_log_item_t *)lidp->lid_item;
937 if (blip->bli_item.li_type != XFS_LI_BUF) {
938 continue;
939 }
940
941 bp = blip->bli_buf;
942 if ((XFS_BUF_TARGET(bp) == target) &&
943 (XFS_BUF_ADDR(bp) == blkno) &&
944 (XFS_BUF_COUNT(bp) == len)) {
945 /*
946 * We found it. Break out and
947 * return the pointer to the buffer.
948 */
949 break;
950 } else {
951 bp = NULL;
952 }
953 }
954 }
955 return bp;
956}
957
958/*
959 * Check to see if a buffer matching the given parameters is already
960 * a part of the given transaction. Check all the chunks, we
961 * want to be thorough.
962 */
963STATIC xfs_buf_t *
964xfs_trans_buf_item_match_all(
965 xfs_trans_t *tp,
966 xfs_buftarg_t *target,
967 xfs_daddr_t blkno,
968 int len)
969{
970 xfs_log_item_chunk_t *licp;
971 xfs_log_item_desc_t *lidp;
972 xfs_buf_log_item_t *blip;
973 xfs_buf_t *bp;
974 int i;
975
976 bp = NULL;
977 len = BBTOB(len);
978 for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) {
979 if (xfs_lic_are_all_free(licp)) {
980 ASSERT(licp == &tp->t_items);
981 ASSERT(licp->lic_next == NULL);
982 return NULL;
983 }
984 for (i = 0; i < licp->lic_unused; i++) {
985 /*
986 * Skip unoccupied slots.
987 */
988 if (xfs_lic_isfree(licp, i)) {
989 continue;
990 }
991
992 lidp = xfs_lic_slot(licp, i);
993 blip = (xfs_buf_log_item_t *)lidp->lid_item;
994 if (blip->bli_item.li_type != XFS_LI_BUF) {
995 continue;
996 }
997
998 bp = blip->bli_buf;
999 if ((XFS_BUF_TARGET(bp) == target) &&
1000 (XFS_BUF_ADDR(bp) == blkno) &&
1001 (XFS_BUF_COUNT(bp) == len)) {
1002 /*
1003 * We found it. Break out and
1004 * return the pointer to the buffer.
1005 */
1006 return bp;
1007 }
1008 }
1009 }
1010 return NULL;
1011}