aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf_item.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-06-22 04:50:12 -0400
committerBen Myers <bpm@sgi.com>2012-07-01 15:50:06 -0400
commit372cc85ec6820c91b4eeff303880f25cb5a00ab5 (patch)
treef35125a854ebc54c64d46c37fde9e91cc68ed991 /fs/xfs/xfs_buf_item.c
parentde2a4f59190303ff5b82ead2969968a325e61230 (diff)
xfs: support discontiguous buffers in the xfs_buf_log_item
discontigous buffer in separate buffer format structures. This means log recovery will recover all the changes on a per segment basis without requiring any knowledge of the fact that it was logged from a compound buffer. To do this, we need to be able to determine what buffer segment any given offset into the compound buffer sits over. This enables us to translate the dirty bitmap in the number of separate buffer format structures required. We also need to be able to determine the number of bitmap elements that a given buffer segment has, as this determines the size of the buffer format structure. Hence we need to be able to determine the both the start offset into the buffer and the length of a given segment to be able to calculate this. With this information, we can preallocate, build and format the correct log vector array for each segment in a compound buffer to appear exactly the same as individually logged buffers in the log. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_buf_item.c')
-rw-r--r--fs/xfs/xfs_buf_item.c335
1 files changed, 242 insertions, 93 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 52cd8f89ee72..e4a6e4b6fa03 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -153,33 +153,25 @@ STATIC void xfs_buf_do_callbacks(struct xfs_buf *bp);
153 * If the XFS_BLI_STALE flag has been set, then log nothing. 153 * If the XFS_BLI_STALE flag has been set, then log nothing.
154 */ 154 */
155STATIC uint 155STATIC uint
156xfs_buf_item_size( 156xfs_buf_item_size_segment(
157 struct xfs_log_item *lip) 157 struct xfs_buf_log_item *bip,
158 struct xfs_buf_log_format *blfp)
158{ 159{
159 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
160 struct xfs_buf *bp = bip->bli_buf; 160 struct xfs_buf *bp = bip->bli_buf;
161 uint nvecs; 161 uint nvecs;
162 int next_bit; 162 int next_bit;
163 int last_bit; 163 int last_bit;
164 164
165 ASSERT(atomic_read(&bip->bli_refcount) > 0); 165 last_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0);
166 if (bip->bli_flags & XFS_BLI_STALE) { 166 if (last_bit == -1)
167 /* 167 return 0;
168 * The buffer is stale, so all we need to log 168
169 * is the buf log format structure with the 169 /*
170 * cancel flag in it. 170 * initial count for a dirty buffer is 2 vectors - the format structure
171 */ 171 * and the first dirty region.
172 trace_xfs_buf_item_size_stale(bip); 172 */
173 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); 173 nvecs = 2;
174 return 1;
175 }
176 174
177 ASSERT(bip->bli_flags & XFS_BLI_LOGGED);
178 nvecs = 1;
179 last_bit = xfs_next_bit(bip->bli_format.blf_data_map,
180 bip->bli_format.blf_map_size, 0);
181 ASSERT(last_bit != -1);
182 nvecs++;
183 while (last_bit != -1) { 175 while (last_bit != -1) {
184 /* 176 /*
185 * This takes the bit number to start looking from and 177 * This takes the bit number to start looking from and
@@ -187,16 +179,15 @@ xfs_buf_item_size(
187 * if there are no more bits set or the start bit is 179 * if there are no more bits set or the start bit is
188 * beyond the end of the bitmap. 180 * beyond the end of the bitmap.
189 */ 181 */
190 next_bit = xfs_next_bit(bip->bli_format.blf_data_map, 182 next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size,
191 bip->bli_format.blf_map_size, 183 last_bit + 1);
192 last_bit + 1);
193 /* 184 /*
194 * If we run out of bits, leave the loop, 185 * If we run out of bits, leave the loop,
195 * else if we find a new set of bits bump the number of vecs, 186 * else if we find a new set of bits bump the number of vecs,
196 * else keep scanning the current set of bits. 187 * else keep scanning the current set of bits.
197 */ 188 */
198 if (next_bit == -1) { 189 if (next_bit == -1) {
199 last_bit = -1; 190 break;
200 } else if (next_bit != last_bit + 1) { 191 } else if (next_bit != last_bit + 1) {
201 last_bit = next_bit; 192 last_bit = next_bit;
202 nvecs++; 193 nvecs++;
@@ -210,22 +201,73 @@ xfs_buf_item_size(
210 } 201 }
211 } 202 }
212 203
213 trace_xfs_buf_item_size(bip);
214 return nvecs; 204 return nvecs;
215} 205}
216 206
217/* 207/*
218 * This is called to fill in the vector of log iovecs for the 208 * This returns the number of log iovecs needed to log the given buf log item.
219 * given log buf item. It fills the first entry with a buf log 209 *
220 * format structure, and the rest point to contiguous chunks 210 * It calculates this as 1 iovec for the buf log format structure and 1 for each
221 * within the buffer. 211 * stretch of non-contiguous chunks to be logged. Contiguous chunks are logged
212 * in a single iovec.
213 *
214 * Discontiguous buffers need a format structure per region that that is being
215 * logged. This makes the changes in the buffer appear to log recovery as though
216 * they came from separate buffers, just like would occur if multiple buffers
217 * were used instead of a single discontiguous buffer. This enables
218 * discontiguous buffers to be in-memory constructs, completely transparent to
219 * what ends up on disk.
220 *
221 * If the XFS_BLI_STALE flag has been set, then log nothing but the buf log
222 * format structures.
222 */ 223 */
223STATIC void 224STATIC uint
224xfs_buf_item_format( 225xfs_buf_item_size(
225 struct xfs_log_item *lip, 226 struct xfs_log_item *lip)
226 struct xfs_log_iovec *vecp)
227{ 227{
228 struct xfs_buf_log_item *bip = BUF_ITEM(lip); 228 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
229 uint nvecs;
230 int i;
231
232 ASSERT(atomic_read(&bip->bli_refcount) > 0);
233 if (bip->bli_flags & XFS_BLI_STALE) {
234 /*
235 * The buffer is stale, so all we need to log
236 * is the buf log format structure with the
237 * cancel flag in it.
238 */
239 trace_xfs_buf_item_size_stale(bip);
240 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
241 return bip->bli_format_count;
242 }
243
244 ASSERT(bip->bli_flags & XFS_BLI_LOGGED);
245
246 /*
247 * the vector count is based on the number of buffer vectors we have
248 * dirty bits in. This will only be greater than one when we have a
249 * compound buffer with more than one segment dirty. Hence for compound
250 * buffers we need to track which segment the dirty bits correspond to,
251 * and when we move from one segment to the next increment the vector
252 * count for the extra buf log format structure that will need to be
253 * written.
254 */
255 nvecs = 0;
256 for (i = 0; i < bip->bli_format_count; i++) {
257 nvecs += xfs_buf_item_size_segment(bip, &bip->bli_formats[i]);
258 }
259
260 trace_xfs_buf_item_size(bip);
261 return nvecs;
262}
263
264static struct xfs_log_iovec *
265xfs_buf_item_format_segment(
266 struct xfs_buf_log_item *bip,
267 struct xfs_log_iovec *vecp,
268 uint offset,
269 struct xfs_buf_log_format *blfp)
270{
229 struct xfs_buf *bp = bip->bli_buf; 271 struct xfs_buf *bp = bip->bli_buf;
230 uint base_size; 272 uint base_size;
231 uint nvecs; 273 uint nvecs;
@@ -235,9 +277,8 @@ xfs_buf_item_format(
235 uint nbits; 277 uint nbits;
236 uint buffer_offset; 278 uint buffer_offset;
237 279
238 ASSERT(atomic_read(&bip->bli_refcount) > 0); 280 /* copy the flags across from the base format item */
239 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || 281 blfp->blf_flags = bip->bli_format.blf_flags;
240 (bip->bli_flags & XFS_BLI_STALE));
241 282
242 /* 283 /*
243 * Base size is the actual size of the ondisk structure - it reflects 284 * Base size is the actual size of the ondisk structure - it reflects
@@ -245,28 +286,13 @@ xfs_buf_item_format(
245 * memory structure. 286 * memory structure.
246 */ 287 */
247 base_size = offsetof(struct xfs_buf_log_format, blf_data_map) + 288 base_size = offsetof(struct xfs_buf_log_format, blf_data_map) +
248 (bip->bli_format.blf_map_size * 289 (blfp->blf_map_size * sizeof(blfp->blf_data_map[0]));
249 sizeof(bip->bli_format.blf_data_map[0])); 290 vecp->i_addr = blfp;
250 vecp->i_addr = &bip->bli_format;
251 vecp->i_len = base_size; 291 vecp->i_len = base_size;
252 vecp->i_type = XLOG_REG_TYPE_BFORMAT; 292 vecp->i_type = XLOG_REG_TYPE_BFORMAT;
253 vecp++; 293 vecp++;
254 nvecs = 1; 294 nvecs = 1;
255 295
256 /*
257 * If it is an inode buffer, transfer the in-memory state to the
258 * format flags and clear the in-memory state. We do not transfer
259 * this state if the inode buffer allocation has not yet been committed
260 * to the log as setting the XFS_BLI_INODE_BUF flag will prevent
261 * correct replay of the inode allocation.
262 */
263 if (bip->bli_flags & XFS_BLI_INODE_BUF) {
264 if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
265 xfs_log_item_in_current_chkpt(lip)))
266 bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF;
267 bip->bli_flags &= ~XFS_BLI_INODE_BUF;
268 }
269
270 if (bip->bli_flags & XFS_BLI_STALE) { 296 if (bip->bli_flags & XFS_BLI_STALE) {
271 /* 297 /*
272 * The buffer is stale, so all we need to log 298 * The buffer is stale, so all we need to log
@@ -274,16 +300,15 @@ xfs_buf_item_format(
274 * cancel flag in it. 300 * cancel flag in it.
275 */ 301 */
276 trace_xfs_buf_item_format_stale(bip); 302 trace_xfs_buf_item_format_stale(bip);
277 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); 303 ASSERT(blfp->blf_flags & XFS_BLF_CANCEL);
278 bip->bli_format.blf_size = nvecs; 304 blfp->blf_size = nvecs;
279 return; 305 return vecp;
280 } 306 }
281 307
282 /* 308 /*
283 * Fill in an iovec for each set of contiguous chunks. 309 * Fill in an iovec for each set of contiguous chunks.
284 */ 310 */
285 first_bit = xfs_next_bit(bip->bli_format.blf_data_map, 311 first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0);
286 bip->bli_format.blf_map_size, 0);
287 ASSERT(first_bit != -1); 312 ASSERT(first_bit != -1);
288 last_bit = first_bit; 313 last_bit = first_bit;
289 nbits = 1; 314 nbits = 1;
@@ -294,9 +319,8 @@ xfs_buf_item_format(
294 * if there are no more bits set or the start bit is 319 * if there are no more bits set or the start bit is
295 * beyond the end of the bitmap. 320 * beyond the end of the bitmap.
296 */ 321 */
297 next_bit = xfs_next_bit(bip->bli_format.blf_data_map, 322 next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size,
298 bip->bli_format.blf_map_size, 323 (uint)last_bit + 1);
299 (uint)last_bit + 1);
300 /* 324 /*
301 * If we run out of bits fill in the last iovec and get 325 * If we run out of bits fill in the last iovec and get
302 * out of the loop. 326 * out of the loop.
@@ -307,14 +331,14 @@ xfs_buf_item_format(
307 * keep counting and scanning. 331 * keep counting and scanning.
308 */ 332 */
309 if (next_bit == -1) { 333 if (next_bit == -1) {
310 buffer_offset = first_bit * XFS_BLF_CHUNK; 334 buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
311 vecp->i_addr = xfs_buf_offset(bp, buffer_offset); 335 vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
312 vecp->i_len = nbits * XFS_BLF_CHUNK; 336 vecp->i_len = nbits * XFS_BLF_CHUNK;
313 vecp->i_type = XLOG_REG_TYPE_BCHUNK; 337 vecp->i_type = XLOG_REG_TYPE_BCHUNK;
314 nvecs++; 338 nvecs++;
315 break; 339 break;
316 } else if (next_bit != last_bit + 1) { 340 } else if (next_bit != last_bit + 1) {
317 buffer_offset = first_bit * XFS_BLF_CHUNK; 341 buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
318 vecp->i_addr = xfs_buf_offset(bp, buffer_offset); 342 vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
319 vecp->i_len = nbits * XFS_BLF_CHUNK; 343 vecp->i_len = nbits * XFS_BLF_CHUNK;
320 vecp->i_type = XLOG_REG_TYPE_BCHUNK; 344 vecp->i_type = XLOG_REG_TYPE_BCHUNK;
@@ -323,14 +347,17 @@ xfs_buf_item_format(
323 first_bit = next_bit; 347 first_bit = next_bit;
324 last_bit = next_bit; 348 last_bit = next_bit;
325 nbits = 1; 349 nbits = 1;
326 } else if (xfs_buf_offset(bp, next_bit << XFS_BLF_SHIFT) != 350 } else if (xfs_buf_offset(bp, offset +
327 (xfs_buf_offset(bp, last_bit << XFS_BLF_SHIFT) + 351 (next_bit << XFS_BLF_SHIFT)) !=
352 (xfs_buf_offset(bp, offset +
353 (last_bit << XFS_BLF_SHIFT)) +
328 XFS_BLF_CHUNK)) { 354 XFS_BLF_CHUNK)) {
329 buffer_offset = first_bit * XFS_BLF_CHUNK; 355 buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
330 vecp->i_addr = xfs_buf_offset(bp, buffer_offset); 356 vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
331 vecp->i_len = nbits * XFS_BLF_CHUNK; 357 vecp->i_len = nbits * XFS_BLF_CHUNK;
332 vecp->i_type = XLOG_REG_TYPE_BCHUNK; 358 vecp->i_type = XLOG_REG_TYPE_BCHUNK;
333/* You would think we need to bump the nvecs here too, but we do not 359/*
360 * You would think we need to bump the nvecs here too, but we do not
334 * this number is used by recovery, and it gets confused by the boundary 361 * this number is used by recovery, and it gets confused by the boundary
335 * split here 362 * split here
336 * nvecs++; 363 * nvecs++;
@@ -345,6 +372,48 @@ xfs_buf_item_format(
345 } 372 }
346 } 373 }
347 bip->bli_format.blf_size = nvecs; 374 bip->bli_format.blf_size = nvecs;
375 return vecp;
376}
377
378/*
379 * This is called to fill in the vector of log iovecs for the
380 * given log buf item. It fills the first entry with a buf log
381 * format structure, and the rest point to contiguous chunks
382 * within the buffer.
383 */
384STATIC void
385xfs_buf_item_format(
386 struct xfs_log_item *lip,
387 struct xfs_log_iovec *vecp)
388{
389 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
390 struct xfs_buf *bp = bip->bli_buf;
391 uint offset = 0;
392 int i;
393
394 ASSERT(atomic_read(&bip->bli_refcount) > 0);
395 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
396 (bip->bli_flags & XFS_BLI_STALE));
397
398 /*
399 * If it is an inode buffer, transfer the in-memory state to the
400 * format flags and clear the in-memory state. We do not transfer
401 * this state if the inode buffer allocation has not yet been committed
402 * to the log as setting the XFS_BLI_INODE_BUF flag will prevent
403 * correct replay of the inode allocation.
404 */
405 if (bip->bli_flags & XFS_BLI_INODE_BUF) {
406 if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
407 xfs_log_item_in_current_chkpt(lip)))
408 bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF;
409 bip->bli_flags &= ~XFS_BLI_INODE_BUF;
410 }
411
412 for (i = 0; i < bip->bli_format_count; i++) {
413 vecp = xfs_buf_item_format_segment(bip, vecp, offset,
414 &bip->bli_formats[i]);
415 offset += bp->b_maps[i].bm_len;
416 }
348 417
349 /* 418 /*
350 * Check to make sure everything is consistent. 419 * Check to make sure everything is consistent.
@@ -620,6 +689,35 @@ static const struct xfs_item_ops xfs_buf_item_ops = {
620 .iop_committing = xfs_buf_item_committing 689 .iop_committing = xfs_buf_item_committing
621}; 690};
622 691
692STATIC int
693xfs_buf_item_get_format(
694 struct xfs_buf_log_item *bip,
695 int count)
696{
697 ASSERT(bip->bli_formats == NULL);
698 bip->bli_format_count = count;
699
700 if (count == 1) {
701 bip->bli_formats = &bip->bli_format;
702 return 0;
703 }
704
705 bip->bli_formats = kmem_zalloc(count * sizeof(struct xfs_buf_log_format),
706 KM_SLEEP);
707 if (!bip->bli_formats)
708 return ENOMEM;
709 return 0;
710}
711
712STATIC void
713xfs_buf_item_free_format(
714 struct xfs_buf_log_item *bip)
715{
716 if (bip->bli_formats != &bip->bli_format) {
717 kmem_free(bip->bli_formats);
718 bip->bli_formats = NULL;
719 }
720}
623 721
624/* 722/*
625 * Allocate a new buf log item to go with the given buffer. 723 * Allocate a new buf log item to go with the given buffer.
@@ -637,6 +735,8 @@ xfs_buf_item_init(
637 xfs_buf_log_item_t *bip; 735 xfs_buf_log_item_t *bip;
638 int chunks; 736 int chunks;
639 int map_size; 737 int map_size;
738 int error;
739 int i;
640 740
641 /* 741 /*
642 * Check to see if there is already a buf log item for 742 * Check to see if there is already a buf log item for
@@ -648,25 +748,33 @@ xfs_buf_item_init(
648 if (lip != NULL && lip->li_type == XFS_LI_BUF) 748 if (lip != NULL && lip->li_type == XFS_LI_BUF)
649 return; 749 return;
650 750
651 /* 751 bip = kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP);
652 * chunks is the number of XFS_BLF_CHUNK size pieces
653 * the buffer can be divided into. Make sure not to
654 * truncate any pieces. map_size is the size of the
655 * bitmap needed to describe the chunks of the buffer.
656 */
657 chunks = (int)((BBTOB(bp->b_length) + (XFS_BLF_CHUNK - 1)) >>
658 XFS_BLF_SHIFT);
659 map_size = (int)((chunks + NBWORD) >> BIT_TO_WORD_SHIFT);
660
661 bip = (xfs_buf_log_item_t*)kmem_zone_zalloc(xfs_buf_item_zone,
662 KM_SLEEP);
663 xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops); 752 xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops);
664 bip->bli_buf = bp; 753 bip->bli_buf = bp;
665 xfs_buf_hold(bp); 754 xfs_buf_hold(bp);
666 bip->bli_format.blf_type = XFS_LI_BUF; 755
667 bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); 756 /*
668 bip->bli_format.blf_len = (ushort)bp->b_length; 757 * chunks is the number of XFS_BLF_CHUNK size pieces the buffer
669 bip->bli_format.blf_map_size = map_size; 758 * can be divided into. Make sure not to truncate any pieces.
759 * map_size is the size of the bitmap needed to describe the
760 * chunks of the buffer.
761 *
762 * Discontiguous buffer support follows the layout of the underlying
763 * buffer. This makes the implementation as simple as possible.
764 */
765 error = xfs_buf_item_get_format(bip, bp->b_map_count);
766 ASSERT(error == 0);
767
768 for (i = 0; i < bip->bli_format_count; i++) {
769 chunks = DIV_ROUND_UP(BBTOB(bp->b_maps[i].bm_len),
770 XFS_BLF_CHUNK);
771 map_size = DIV_ROUND_UP(chunks, NBWORD);
772
773 bip->bli_formats[i].blf_type = XFS_LI_BUF;
774 bip->bli_formats[i].blf_blkno = bp->b_maps[i].bm_bn;
775 bip->bli_formats[i].blf_len = bp->b_maps[i].bm_len;
776 bip->bli_formats[i].blf_map_size = map_size;
777 }
670 778
671#ifdef XFS_TRANS_DEBUG 779#ifdef XFS_TRANS_DEBUG
672 /* 780 /*
@@ -697,10 +805,11 @@ xfs_buf_item_init(
697 * item's bitmap. 805 * item's bitmap.
698 */ 806 */
699void 807void
700xfs_buf_item_log( 808xfs_buf_item_log_segment(
701 xfs_buf_log_item_t *bip, 809 struct xfs_buf_log_item *bip,
702 uint first, 810 uint first,
703 uint last) 811 uint last,
812 uint *map)
704{ 813{
705 uint first_bit; 814 uint first_bit;
706 uint last_bit; 815 uint last_bit;
@@ -713,12 +822,6 @@ xfs_buf_item_log(
713 uint mask; 822 uint mask;
714 823
715 /* 824 /*
716 * Mark the item as having some dirty data for
717 * quick reference in xfs_buf_item_dirty.
718 */
719 bip->bli_flags |= XFS_BLI_DIRTY;
720
721 /*
722 * Convert byte offsets to bit numbers. 825 * Convert byte offsets to bit numbers.
723 */ 826 */
724 first_bit = first >> XFS_BLF_SHIFT; 827 first_bit = first >> XFS_BLF_SHIFT;
@@ -734,7 +837,7 @@ xfs_buf_item_log(
734 * to set a bit in. 837 * to set a bit in.
735 */ 838 */
736 word_num = first_bit >> BIT_TO_WORD_SHIFT; 839 word_num = first_bit >> BIT_TO_WORD_SHIFT;
737 wordp = &(bip->bli_format.blf_data_map[word_num]); 840 wordp = &map[word_num];
738 841
739 /* 842 /*
740 * Calculate the starting bit in the first word. 843 * Calculate the starting bit in the first word.
@@ -781,6 +884,51 @@ xfs_buf_item_log(
781 xfs_buf_item_log_debug(bip, first, last); 884 xfs_buf_item_log_debug(bip, first, last);
782} 885}
783 886
887/*
888 * Mark bytes first through last inclusive as dirty in the buf
889 * item's bitmap.
890 */
891void
892xfs_buf_item_log(
893 xfs_buf_log_item_t *bip,
894 uint first,
895 uint last)
896{
897 int i;
898 uint start;
899 uint end;
900 struct xfs_buf *bp = bip->bli_buf;
901
902 /*
903 * Mark the item as having some dirty data for
904 * quick reference in xfs_buf_item_dirty.
905 */
906 bip->bli_flags |= XFS_BLI_DIRTY;
907
908 /*
909 * walk each buffer segment and mark them dirty appropriately.
910 */
911 start = 0;
912 for (i = 0; i < bip->bli_format_count; i++) {
913 if (start > last)
914 break;
915 end = start + BBTOB(bp->b_maps[i].bm_len);
916 if (first > end) {
917 start += BBTOB(bp->b_maps[i].bm_len);
918 continue;
919 }
920 if (first < start)
921 first = start;
922 if (end > last)
923 end = last;
924
925 xfs_buf_item_log_segment(bip, first, end,
926 &bip->bli_formats[i].blf_data_map[0]);
927
928 start += bp->b_maps[i].bm_len;
929 }
930}
931
784 932
785/* 933/*
786 * Return 1 if the buffer has some data that has been logged (at any 934 * Return 1 if the buffer has some data that has been logged (at any
@@ -802,6 +950,7 @@ xfs_buf_item_free(
802 kmem_free(bip->bli_logged); 950 kmem_free(bip->bli_logged);
803#endif /* XFS_TRANS_DEBUG */ 951#endif /* XFS_TRANS_DEBUG */
804 952
953 xfs_buf_item_free_format(bip);
805 kmem_zone_free(xfs_buf_item_zone, bip); 954 kmem_zone_free(xfs_buf_item_zone, bip);
806} 955}
807 956