diff options
Diffstat (limited to 'fs/xfs/xfs_trans_buf.c')
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 187 |
1 files changed, 47 insertions, 140 deletions
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index fb586360d1c9..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); |
@@ -696,7 +712,6 @@ xfs_trans_log_buf(xfs_trans_t *tp, | |||
696 | 712 | ||
697 | tp->t_flags |= XFS_TRANS_DIRTY; | 713 | tp->t_flags |= XFS_TRANS_DIRTY; |
698 | lidp->lid_flags |= XFS_LID_DIRTY; | 714 | lidp->lid_flags |= XFS_LID_DIRTY; |
699 | lidp->lid_flags &= ~XFS_LID_BUF_STALE; | ||
700 | bip->bli_flags |= XFS_BLI_LOGGED; | 715 | bip->bli_flags |= XFS_BLI_LOGGED; |
701 | xfs_buf_item_log(bip, first, last); | 716 | xfs_buf_item_log(bip, first, last); |
702 | } | 717 | } |
@@ -782,7 +797,7 @@ xfs_trans_binval( | |||
782 | bip->bli_format.blf_flags |= XFS_BLI_CANCEL; | 797 | bip->bli_format.blf_flags |= XFS_BLI_CANCEL; |
783 | memset((char *)(bip->bli_format.blf_data_map), 0, | 798 | memset((char *)(bip->bli_format.blf_data_map), 0, |
784 | (bip->bli_format.blf_map_size * sizeof(uint))); | 799 | (bip->bli_format.blf_map_size * sizeof(uint))); |
785 | lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE; | 800 | lidp->lid_flags |= XFS_LID_DIRTY; |
786 | tp->t_flags |= XFS_TRANS_DIRTY; | 801 | tp->t_flags |= XFS_TRANS_DIRTY; |
787 | } | 802 | } |
788 | 803 | ||
@@ -902,111 +917,3 @@ xfs_trans_dquot_buf( | |||
902 | 917 | ||
903 | bip->bli_format.blf_flags |= type; | 918 | bip->bli_format.blf_flags |= type; |
904 | } | 919 | } |
905 | |||
906 | /* | ||
907 | * Check to see if a buffer matching the given parameters is already | ||
908 | * a part of the given transaction. Only check the first, embedded | ||
909 | * chunk, since we don't want to spend all day scanning large transactions. | ||
910 | */ | ||
911 | STATIC xfs_buf_t * | ||
912 | xfs_trans_buf_item_match( | ||
913 | xfs_trans_t *tp, | ||
914 | xfs_buftarg_t *target, | ||
915 | xfs_daddr_t blkno, | ||
916 | int len) | ||
917 | { | ||
918 | xfs_log_item_chunk_t *licp; | ||
919 | xfs_log_item_desc_t *lidp; | ||
920 | xfs_buf_log_item_t *blip; | ||
921 | xfs_buf_t *bp; | ||
922 | int i; | ||
923 | |||
924 | bp = NULL; | ||
925 | len = BBTOB(len); | ||
926 | licp = &tp->t_items; | ||
927 | if (!xfs_lic_are_all_free(licp)) { | ||
928 | for (i = 0; i < licp->lic_unused; i++) { | ||
929 | /* | ||
930 | * Skip unoccupied slots. | ||
931 | */ | ||
932 | if (xfs_lic_isfree(licp, i)) { | ||
933 | continue; | ||
934 | } | ||
935 | |||
936 | lidp = xfs_lic_slot(licp, i); | ||
937 | blip = (xfs_buf_log_item_t *)lidp->lid_item; | ||
938 | if (blip->bli_item.li_type != XFS_LI_BUF) { | ||
939 | continue; | ||
940 | } | ||
941 | |||
942 | bp = blip->bli_buf; | ||
943 | if ((XFS_BUF_TARGET(bp) == target) && | ||
944 | (XFS_BUF_ADDR(bp) == blkno) && | ||
945 | (XFS_BUF_COUNT(bp) == len)) { | ||
946 | /* | ||
947 | * We found it. Break out and | ||
948 | * return the pointer to the buffer. | ||
949 | */ | ||
950 | break; | ||
951 | } else { | ||
952 | bp = NULL; | ||
953 | } | ||
954 | } | ||
955 | } | ||
956 | return bp; | ||
957 | } | ||
958 | |||
959 | /* | ||
960 | * Check to see if a buffer matching the given parameters is already | ||
961 | * a part of the given transaction. Check all the chunks, we | ||
962 | * want to be thorough. | ||
963 | */ | ||
964 | STATIC xfs_buf_t * | ||
965 | xfs_trans_buf_item_match_all( | ||
966 | xfs_trans_t *tp, | ||
967 | xfs_buftarg_t *target, | ||
968 | xfs_daddr_t blkno, | ||
969 | int len) | ||
970 | { | ||
971 | xfs_log_item_chunk_t *licp; | ||
972 | xfs_log_item_desc_t *lidp; | ||
973 | xfs_buf_log_item_t *blip; | ||
974 | xfs_buf_t *bp; | ||
975 | int i; | ||
976 | |||
977 | bp = NULL; | ||
978 | len = BBTOB(len); | ||
979 | for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) { | ||
980 | if (xfs_lic_are_all_free(licp)) { | ||
981 | ASSERT(licp == &tp->t_items); | ||
982 | ASSERT(licp->lic_next == NULL); | ||
983 | return NULL; | ||
984 | } | ||
985 | for (i = 0; i < licp->lic_unused; i++) { | ||
986 | /* | ||
987 | * Skip unoccupied slots. | ||
988 | */ | ||
989 | if (xfs_lic_isfree(licp, i)) { | ||
990 | continue; | ||
991 | } | ||
992 | |||
993 | lidp = xfs_lic_slot(licp, i); | ||
994 | blip = (xfs_buf_log_item_t *)lidp->lid_item; | ||
995 | if (blip->bli_item.li_type != XFS_LI_BUF) { | ||
996 | continue; | ||
997 | } | ||
998 | |||
999 | bp = blip->bli_buf; | ||
1000 | if ((XFS_BUF_TARGET(bp) == target) && | ||
1001 | (XFS_BUF_ADDR(bp) == blkno) && | ||
1002 | (XFS_BUF_COUNT(bp) == len)) { | ||
1003 | /* | ||
1004 | * We found it. Break out and | ||
1005 | * return the pointer to the buffer. | ||
1006 | */ | ||
1007 | return bp; | ||
1008 | } | ||
1009 | } | ||
1010 | } | ||
1011 | return NULL; | ||
1012 | } | ||