@@ -47,6 +47,23 @@ const struct xfs_buf_ops xfs_rtbuf_ops = {
4747 .verify_write = xfs_rtbuf_verify_write ,
4848};
4949
50+ /* Release cached rt bitmap and summary buffers. */
51+ void
52+ xfs_rtbuf_cache_relse (
53+ struct xfs_rtalloc_args * args )
54+ {
55+ if (args -> rbmbp ) {
56+ xfs_trans_brelse (args -> tp , args -> rbmbp );
57+ args -> rbmbp = NULL ;
58+ args -> rbmoff = NULLFILEOFF ;
59+ }
60+ if (args -> sumbp ) {
61+ xfs_trans_brelse (args -> tp , args -> sumbp );
62+ args -> sumbp = NULL ;
63+ args -> sumoff = NULLFILEOFF ;
64+ }
65+ }
66+
5067/*
5168 * Get a buffer for the bitmap or summary file block specified.
5269 * The buffer is returned read and locked.
@@ -59,13 +76,42 @@ xfs_rtbuf_get(
5976 struct xfs_buf * * bpp ) /* output: buffer for the block */
6077{
6178 struct xfs_mount * mp = args -> mp ;
79+ struct xfs_buf * * cbpp ; /* cached block buffer */
80+ xfs_fileoff_t * coffp ; /* cached block number */
6281 struct xfs_buf * bp ; /* block buffer, result */
6382 struct xfs_inode * ip ; /* bitmap or summary inode */
6483 struct xfs_bmbt_irec map ;
84+ enum xfs_blft type ;
6585 int nmap = 1 ;
6686 int error ;
6787
68- ip = issum ? mp -> m_rsumip : mp -> m_rbmip ;
88+ if (issum ) {
89+ cbpp = & args -> sumbp ;
90+ coffp = & args -> sumoff ;
91+ ip = mp -> m_rsumip ;
92+ type = XFS_BLFT_RTSUMMARY_BUF ;
93+ } else {
94+ cbpp = & args -> rbmbp ;
95+ coffp = & args -> rbmoff ;
96+ ip = mp -> m_rbmip ;
97+ type = XFS_BLFT_RTBITMAP_BUF ;
98+ }
99+
100+ /*
101+ * If we have a cached buffer, and the block number matches, use that.
102+ */
103+ if (* cbpp && * coffp == block ) {
104+ * bpp = * cbpp ;
105+ return 0 ;
106+ }
107+ /*
108+ * Otherwise we have to have to get the buffer. If there was an old
109+ * one, get rid of it first.
110+ */
111+ if (* cbpp ) {
112+ xfs_trans_brelse (args -> tp , * cbpp );
113+ * cbpp = NULL ;
114+ }
69115
70116 error = xfs_bmapi_read (ip , block , 1 , & map , & nmap , 0 );
71117 if (error )
@@ -81,9 +127,9 @@ xfs_rtbuf_get(
81127 if (error )
82128 return error ;
83129
84- xfs_trans_buf_set_type (args -> tp , bp , issum ? XFS_BLFT_RTSUMMARY_BUF
85- : XFS_BLFT_RTBITMAP_BUF ) ;
86- * bpp = bp ;
130+ xfs_trans_buf_set_type (args -> tp , bp , type );
131+ * cbpp = * bpp = bp ;
132+ * coffp = block ;
87133 return 0 ;
88134}
89135
@@ -153,7 +199,6 @@ xfs_rtfind_back(
153199 /*
154200 * Different. Mark where we are and return.
155201 */
156- xfs_trans_brelse (args -> tp , bp );
157202 i = bit - XFS_RTHIBIT (wdiff );
158203 * rtx = start - i + 1 ;
159204 return 0 ;
@@ -167,7 +212,6 @@ xfs_rtfind_back(
167212 /*
168213 * If done with this block, get the previous one.
169214 */
170- xfs_trans_brelse (args -> tp , bp );
171215 error = xfs_rtbuf_get (args , -- block , 0 , & bp );
172216 if (error ) {
173217 return error ;
@@ -194,7 +238,6 @@ xfs_rtfind_back(
194238 /*
195239 * Different, mark where we are and return.
196240 */
197- xfs_trans_brelse (args -> tp , bp );
198241 i += XFS_NBWORD - 1 - XFS_RTHIBIT (wdiff );
199242 * rtx = start - i + 1 ;
200243 return 0 ;
@@ -208,7 +251,6 @@ xfs_rtfind_back(
208251 /*
209252 * If done with this block, get the previous one.
210253 */
211- xfs_trans_brelse (args -> tp , bp );
212254 error = xfs_rtbuf_get (args , -- block , 0 , & bp );
213255 if (error ) {
214256 return error ;
@@ -236,7 +278,6 @@ xfs_rtfind_back(
236278 /*
237279 * Different, mark where we are and return.
238280 */
239- xfs_trans_brelse (args -> tp , bp );
240281 i += XFS_NBWORD - 1 - XFS_RTHIBIT (wdiff );
241282 * rtx = start - i + 1 ;
242283 return 0 ;
@@ -246,7 +287,6 @@ xfs_rtfind_back(
246287 /*
247288 * No match, return that we scanned the whole area.
248289 */
249- xfs_trans_brelse (args -> tp , bp );
250290 * rtx = start - i + 1 ;
251291 return 0 ;
252292}
@@ -316,7 +356,6 @@ xfs_rtfind_forw(
316356 /*
317357 * Different. Mark where we are and return.
318358 */
319- xfs_trans_brelse (args -> tp , bp );
320359 i = XFS_RTLOBIT (wdiff ) - bit ;
321360 * rtx = start + i - 1 ;
322361 return 0 ;
@@ -330,7 +369,6 @@ xfs_rtfind_forw(
330369 /*
331370 * If done with this block, get the previous one.
332371 */
333- xfs_trans_brelse (args -> tp , bp );
334372 error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
335373 if (error ) {
336374 return error ;
@@ -357,7 +395,6 @@ xfs_rtfind_forw(
357395 /*
358396 * Different, mark where we are and return.
359397 */
360- xfs_trans_brelse (args -> tp , bp );
361398 i += XFS_RTLOBIT (wdiff );
362399 * rtx = start + i - 1 ;
363400 return 0 ;
@@ -371,7 +408,6 @@ xfs_rtfind_forw(
371408 /*
372409 * If done with this block, get the next one.
373410 */
374- xfs_trans_brelse (args -> tp , bp );
375411 error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
376412 if (error ) {
377413 return error ;
@@ -397,7 +433,6 @@ xfs_rtfind_forw(
397433 /*
398434 * Different, mark where we are and return.
399435 */
400- xfs_trans_brelse (args -> tp , bp );
401436 i += XFS_RTLOBIT (wdiff );
402437 * rtx = start + i - 1 ;
403438 return 0 ;
@@ -407,7 +442,6 @@ xfs_rtfind_forw(
407442 /*
408443 * No match, return that we scanned the whole area.
409444 */
410- xfs_trans_brelse (args -> tp , bp );
411445 * rtx = start + i - 1 ;
412446 return 0 ;
413447}
@@ -442,8 +476,6 @@ xfs_rtmodify_summary_int(
442476 int log , /* log2 of extent size */
443477 xfs_fileoff_t bbno , /* bitmap block number */
444478 int delta , /* change to make to summary info */
445- struct xfs_buf * * rbpp , /* in/out: summary block buffer */
446- xfs_fileoff_t * rsb , /* in/out: summary block number */
447479 xfs_suminfo_t * sum ) /* out: summary info for this block */
448480{
449481 struct xfs_mount * mp = args -> mp ;
@@ -461,30 +493,11 @@ xfs_rtmodify_summary_int(
461493 * Compute the block number in the summary file.
462494 */
463495 sb = xfs_rtsumoffs_to_block (mp , so );
464- /*
465- * If we have an old buffer, and the block number matches, use that.
466- */
467- if (* rbpp && * rsb == sb )
468- bp = * rbpp ;
469- /*
470- * Otherwise we have to get the buffer.
471- */
472- else {
473- /*
474- * If there was an old one, get rid of it first.
475- */
476- if (* rbpp )
477- xfs_trans_brelse (args -> tp , * rbpp );
478- error = xfs_rtbuf_get (args , sb , 1 , & bp );
479- if (error ) {
480- return error ;
481- }
482- /*
483- * Remember this buffer and block for the next call.
484- */
485- * rbpp = bp ;
486- * rsb = sb ;
487- }
496+
497+ error = xfs_rtbuf_get (args , sb , 1 , & bp );
498+ if (error )
499+ return error ;
500+
488501 /*
489502 * Point to the summary information, modify/log it, and/or copy it out.
490503 */
@@ -512,11 +525,9 @@ xfs_rtmodify_summary(
512525 struct xfs_rtalloc_args * args ,
513526 int log , /* log2 of extent size */
514527 xfs_fileoff_t bbno , /* bitmap block number */
515- int delta , /* change to make to summary info */
516- struct xfs_buf * * rbpp , /* in/out: summary block buffer */
517- xfs_fileoff_t * rsb ) /* in/out: summary block number */
528+ int delta ) /* in/out: summary block number */
518529{
519- return xfs_rtmodify_summary_int (args , log , bbno , delta , rbpp , rsb , NULL );
530+ return xfs_rtmodify_summary_int (args , log , bbno , delta , NULL );
520531}
521532
522533/* Log rtbitmap block from the word @from to the byte before @next. */
687698xfs_rtfree_range (
688699 struct xfs_rtalloc_args * args ,
689700 xfs_rtxnum_t start , /* starting rtext to free */
690- xfs_rtxlen_t len , /* length to free */
691- struct xfs_buf * * rbpp , /* in/out: summary block buffer */
692- xfs_fileoff_t * rsb ) /* in/out: summary block number */
701+ xfs_rtxlen_t len ) /* in/out: summary block number */
693702{
694703 struct xfs_mount * mp = args -> mp ;
695704 xfs_rtxnum_t end ; /* end of the freed extent */
@@ -718,7 +727,7 @@ xfs_rtfree_range(
718727 * Find the next allocated block (end of allocated extent).
719728 */
720729 error = xfs_rtfind_forw (args , end , mp -> m_sb .sb_rextents - 1 ,
721- & postblock );
730+ & postblock );
722731 if (error )
723732 return error ;
724733 /*
@@ -727,8 +736,8 @@ xfs_rtfree_range(
727736 */
728737 if (preblock < start ) {
729738 error = xfs_rtmodify_summary (args ,
730- XFS_RTBLOCKLOG (start - preblock ),
731- xfs_rtx_to_rbmblock (mp , preblock ), -1 , rbpp , rsb );
739+ XFS_RTBLOCKLOG (start - preblock ),
740+ xfs_rtx_to_rbmblock (mp , preblock ), -1 );
732741 if (error ) {
733742 return error ;
734743 }
@@ -739,8 +748,8 @@ xfs_rtfree_range(
739748 */
740749 if (postblock > end ) {
741750 error = xfs_rtmodify_summary (args ,
742- XFS_RTBLOCKLOG (postblock - end ),
743- xfs_rtx_to_rbmblock (mp , end + 1 ), -1 , rbpp , rsb );
751+ XFS_RTBLOCKLOG (postblock - end ),
752+ xfs_rtx_to_rbmblock (mp , end + 1 ), -1 );
744753 if (error ) {
745754 return error ;
746755 }
@@ -749,10 +758,9 @@ xfs_rtfree_range(
749758 * Increment the summary information corresponding to the entire
750759 * (new) free extent.
751760 */
752- error = xfs_rtmodify_summary (args ,
753- XFS_RTBLOCKLOG (postblock + 1 - preblock ),
754- xfs_rtx_to_rbmblock (mp , preblock ), 1 , rbpp , rsb );
755- return error ;
761+ return xfs_rtmodify_summary (args ,
762+ XFS_RTBLOCKLOG (postblock + 1 - preblock ),
763+ xfs_rtx_to_rbmblock (mp , preblock ), 1 );
756764}
757765
758766/*
@@ -822,7 +830,6 @@ xfs_rtcheck_range(
822830 /*
823831 * Different, compute first wrong bit and return.
824832 */
825- xfs_trans_brelse (args -> tp , bp );
826833 i = XFS_RTLOBIT (wdiff ) - bit ;
827834 * new = start + i ;
828835 * stat = 0 ;
@@ -837,7 +844,6 @@ xfs_rtcheck_range(
837844 /*
838845 * If done with this block, get the next one.
839846 */
840- xfs_trans_brelse (args -> tp , bp );
841847 error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
842848 if (error ) {
843849 return error ;
@@ -864,7 +870,6 @@ xfs_rtcheck_range(
864870 /*
865871 * Different, compute first wrong bit and return.
866872 */
867- xfs_trans_brelse (args -> tp , bp );
868873 i += XFS_RTLOBIT (wdiff );
869874 * new = start + i ;
870875 * stat = 0 ;
@@ -879,7 +884,6 @@ xfs_rtcheck_range(
879884 /*
880885 * If done with this block, get the next one.
881886 */
882- xfs_trans_brelse (args -> tp , bp );
883887 error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
884888 if (error ) {
885889 return error ;
@@ -905,7 +909,6 @@ xfs_rtcheck_range(
905909 /*
906910 * Different, compute first wrong bit and return.
907911 */
908- xfs_trans_brelse (args -> tp , bp );
909912 i += XFS_RTLOBIT (wdiff );
910913 * new = start + i ;
911914 * stat = 0 ;
@@ -916,7 +919,6 @@ xfs_rtcheck_range(
916919 /*
917920 * Successful, return.
918921 */
919- xfs_trans_brelse (args -> tp , bp );
920922 * new = start + i ;
921923 * stat = 1 ;
922924 return 0 ;
@@ -961,8 +963,6 @@ xfs_rtfree_extent(
961963 .tp = tp ,
962964 };
963965 int error ;
964- xfs_fsblock_t sb ; /* summary file block number */
965- struct xfs_buf * sumbp = NULL ; /* summary file block buffer */
966966
967967 ASSERT (mp -> m_rbmip -> i_itemp != NULL );
968968 ASSERT (xfs_isilocked (mp -> m_rbmip , XFS_ILOCK_EXCL ));
@@ -974,10 +974,10 @@ xfs_rtfree_extent(
974974 /*
975975 * Free the range of realtime blocks.
976976 */
977- error = xfs_rtfree_range (& args , start , len , & sumbp , & sb );
978- if (error ) {
979- return error ;
980- }
977+ error = xfs_rtfree_range (& args , start , len );
978+ if (error )
979+ goto out ;
980+
981981 /*
982982 * Mark more blocks free in the superblock.
983983 */
@@ -993,7 +993,10 @@ xfs_rtfree_extent(
993993 * (uint64_t * )& VFS_I (mp -> m_rbmip )-> i_atime = 0 ;
994994 xfs_trans_log_inode (tp , mp -> m_rbmip , XFS_ILOG_CORE );
995995 }
996- return 0 ;
996+ error = 0 ;
997+ out :
998+ xfs_rtbuf_cache_relse (& args );
999+ return error ;
9971000}
9981001
9991002/*
@@ -1084,6 +1087,7 @@ xfs_rtalloc_query_range(
10841087 rtstart = rtend + 1 ;
10851088 }
10861089
1090+ xfs_rtbuf_cache_relse (& args );
10871091 return error ;
10881092}
10891093
@@ -1122,6 +1126,7 @@ xfs_rtalloc_extent_is_free(
11221126 int error ;
11231127
11241128 error = xfs_rtcheck_range (& args , start , len , 1 , & end , & matches );
1129+ xfs_rtbuf_cache_relse (& args );
11251130 if (error )
11261131 return error ;
11271132
0 commit comments