diff options
| -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 | } | ||
