diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 184 |
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 | */ | ||
47 | STATIC struct xfs_buf * | ||
48 | xfs_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 | ||
44 | STATIC 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) { |
46 | STATIC 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 | */ | ||
910 | STATIC xfs_buf_t * | ||
911 | xfs_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 | */ | ||
963 | STATIC xfs_buf_t * | ||
964 | xfs_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 | } | ||