@@ -47,6 +47,23 @@ const struct xfs_buf_ops xfs_rtbuf_ops = {
47
47
.verify_write = xfs_rtbuf_verify_write ,
48
48
};
49
49
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
+
50
67
/*
51
68
* Get a buffer for the bitmap or summary file block specified.
52
69
* The buffer is returned read and locked.
@@ -59,13 +76,42 @@ xfs_rtbuf_get(
59
76
struct xfs_buf * * bpp ) /* output: buffer for the block */
60
77
{
61
78
struct xfs_mount * mp = args -> mp ;
79
+ struct xfs_buf * * cbpp ; /* cached block buffer */
80
+ xfs_fileoff_t * coffp ; /* cached block number */
62
81
struct xfs_buf * bp ; /* block buffer, result */
63
82
struct xfs_inode * ip ; /* bitmap or summary inode */
64
83
struct xfs_bmbt_irec map ;
84
+ enum xfs_blft type ;
65
85
int nmap = 1 ;
66
86
int error ;
67
87
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
+ }
69
115
70
116
error = xfs_bmapi_read (ip , block , 1 , & map , & nmap , 0 );
71
117
if (error )
@@ -81,9 +127,9 @@ xfs_rtbuf_get(
81
127
if (error )
82
128
return error ;
83
129
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 ;
87
133
return 0 ;
88
134
}
89
135
@@ -153,7 +199,6 @@ xfs_rtfind_back(
153
199
/*
154
200
* Different. Mark where we are and return.
155
201
*/
156
- xfs_trans_brelse (args -> tp , bp );
157
202
i = bit - XFS_RTHIBIT (wdiff );
158
203
* rtx = start - i + 1 ;
159
204
return 0 ;
@@ -167,7 +212,6 @@ xfs_rtfind_back(
167
212
/*
168
213
* If done with this block, get the previous one.
169
214
*/
170
- xfs_trans_brelse (args -> tp , bp );
171
215
error = xfs_rtbuf_get (args , -- block , 0 , & bp );
172
216
if (error ) {
173
217
return error ;
@@ -194,7 +238,6 @@ xfs_rtfind_back(
194
238
/*
195
239
* Different, mark where we are and return.
196
240
*/
197
- xfs_trans_brelse (args -> tp , bp );
198
241
i += XFS_NBWORD - 1 - XFS_RTHIBIT (wdiff );
199
242
* rtx = start - i + 1 ;
200
243
return 0 ;
@@ -208,7 +251,6 @@ xfs_rtfind_back(
208
251
/*
209
252
* If done with this block, get the previous one.
210
253
*/
211
- xfs_trans_brelse (args -> tp , bp );
212
254
error = xfs_rtbuf_get (args , -- block , 0 , & bp );
213
255
if (error ) {
214
256
return error ;
@@ -236,7 +278,6 @@ xfs_rtfind_back(
236
278
/*
237
279
* Different, mark where we are and return.
238
280
*/
239
- xfs_trans_brelse (args -> tp , bp );
240
281
i += XFS_NBWORD - 1 - XFS_RTHIBIT (wdiff );
241
282
* rtx = start - i + 1 ;
242
283
return 0 ;
@@ -246,7 +287,6 @@ xfs_rtfind_back(
246
287
/*
247
288
* No match, return that we scanned the whole area.
248
289
*/
249
- xfs_trans_brelse (args -> tp , bp );
250
290
* rtx = start - i + 1 ;
251
291
return 0 ;
252
292
}
@@ -316,7 +356,6 @@ xfs_rtfind_forw(
316
356
/*
317
357
* Different. Mark where we are and return.
318
358
*/
319
- xfs_trans_brelse (args -> tp , bp );
320
359
i = XFS_RTLOBIT (wdiff ) - bit ;
321
360
* rtx = start + i - 1 ;
322
361
return 0 ;
@@ -330,7 +369,6 @@ xfs_rtfind_forw(
330
369
/*
331
370
* If done with this block, get the previous one.
332
371
*/
333
- xfs_trans_brelse (args -> tp , bp );
334
372
error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
335
373
if (error ) {
336
374
return error ;
@@ -357,7 +395,6 @@ xfs_rtfind_forw(
357
395
/*
358
396
* Different, mark where we are and return.
359
397
*/
360
- xfs_trans_brelse (args -> tp , bp );
361
398
i += XFS_RTLOBIT (wdiff );
362
399
* rtx = start + i - 1 ;
363
400
return 0 ;
@@ -371,7 +408,6 @@ xfs_rtfind_forw(
371
408
/*
372
409
* If done with this block, get the next one.
373
410
*/
374
- xfs_trans_brelse (args -> tp , bp );
375
411
error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
376
412
if (error ) {
377
413
return error ;
@@ -397,7 +433,6 @@ xfs_rtfind_forw(
397
433
/*
398
434
* Different, mark where we are and return.
399
435
*/
400
- xfs_trans_brelse (args -> tp , bp );
401
436
i += XFS_RTLOBIT (wdiff );
402
437
* rtx = start + i - 1 ;
403
438
return 0 ;
@@ -407,7 +442,6 @@ xfs_rtfind_forw(
407
442
/*
408
443
* No match, return that we scanned the whole area.
409
444
*/
410
- xfs_trans_brelse (args -> tp , bp );
411
445
* rtx = start + i - 1 ;
412
446
return 0 ;
413
447
}
@@ -442,8 +476,6 @@ xfs_rtmodify_summary_int(
442
476
int log , /* log2 of extent size */
443
477
xfs_fileoff_t bbno , /* bitmap block number */
444
478
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 */
447
479
xfs_suminfo_t * sum ) /* out: summary info for this block */
448
480
{
449
481
struct xfs_mount * mp = args -> mp ;
@@ -461,30 +493,11 @@ xfs_rtmodify_summary_int(
461
493
* Compute the block number in the summary file.
462
494
*/
463
495
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
+
488
501
/*
489
502
* Point to the summary information, modify/log it, and/or copy it out.
490
503
*/
@@ -512,11 +525,9 @@ xfs_rtmodify_summary(
512
525
struct xfs_rtalloc_args * args ,
513
526
int log , /* log2 of extent size */
514
527
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 */
518
529
{
519
- return xfs_rtmodify_summary_int (args , log , bbno , delta , rbpp , rsb , NULL );
530
+ return xfs_rtmodify_summary_int (args , log , bbno , delta , NULL );
520
531
}
521
532
522
533
/* Log rtbitmap block from the word @from to the byte before @next. */
687
698
xfs_rtfree_range (
688
699
struct xfs_rtalloc_args * args ,
689
700
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 */
693
702
{
694
703
struct xfs_mount * mp = args -> mp ;
695
704
xfs_rtxnum_t end ; /* end of the freed extent */
@@ -718,7 +727,7 @@ xfs_rtfree_range(
718
727
* Find the next allocated block (end of allocated extent).
719
728
*/
720
729
error = xfs_rtfind_forw (args , end , mp -> m_sb .sb_rextents - 1 ,
721
- & postblock );
730
+ & postblock );
722
731
if (error )
723
732
return error ;
724
733
/*
@@ -727,8 +736,8 @@ xfs_rtfree_range(
727
736
*/
728
737
if (preblock < start ) {
729
738
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 );
732
741
if (error ) {
733
742
return error ;
734
743
}
@@ -739,8 +748,8 @@ xfs_rtfree_range(
739
748
*/
740
749
if (postblock > end ) {
741
750
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 );
744
753
if (error ) {
745
754
return error ;
746
755
}
@@ -749,10 +758,9 @@ xfs_rtfree_range(
749
758
* Increment the summary information corresponding to the entire
750
759
* (new) free extent.
751
760
*/
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 );
756
764
}
757
765
758
766
/*
@@ -822,7 +830,6 @@ xfs_rtcheck_range(
822
830
/*
823
831
* Different, compute first wrong bit and return.
824
832
*/
825
- xfs_trans_brelse (args -> tp , bp );
826
833
i = XFS_RTLOBIT (wdiff ) - bit ;
827
834
* new = start + i ;
828
835
* stat = 0 ;
@@ -837,7 +844,6 @@ xfs_rtcheck_range(
837
844
/*
838
845
* If done with this block, get the next one.
839
846
*/
840
- xfs_trans_brelse (args -> tp , bp );
841
847
error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
842
848
if (error ) {
843
849
return error ;
@@ -864,7 +870,6 @@ xfs_rtcheck_range(
864
870
/*
865
871
* Different, compute first wrong bit and return.
866
872
*/
867
- xfs_trans_brelse (args -> tp , bp );
868
873
i += XFS_RTLOBIT (wdiff );
869
874
* new = start + i ;
870
875
* stat = 0 ;
@@ -879,7 +884,6 @@ xfs_rtcheck_range(
879
884
/*
880
885
* If done with this block, get the next one.
881
886
*/
882
- xfs_trans_brelse (args -> tp , bp );
883
887
error = xfs_rtbuf_get (args , ++ block , 0 , & bp );
884
888
if (error ) {
885
889
return error ;
@@ -905,7 +909,6 @@ xfs_rtcheck_range(
905
909
/*
906
910
* Different, compute first wrong bit and return.
907
911
*/
908
- xfs_trans_brelse (args -> tp , bp );
909
912
i += XFS_RTLOBIT (wdiff );
910
913
* new = start + i ;
911
914
* stat = 0 ;
@@ -916,7 +919,6 @@ xfs_rtcheck_range(
916
919
/*
917
920
* Successful, return.
918
921
*/
919
- xfs_trans_brelse (args -> tp , bp );
920
922
* new = start + i ;
921
923
* stat = 1 ;
922
924
return 0 ;
@@ -961,8 +963,6 @@ xfs_rtfree_extent(
961
963
.tp = tp ,
962
964
};
963
965
int error ;
964
- xfs_fsblock_t sb ; /* summary file block number */
965
- struct xfs_buf * sumbp = NULL ; /* summary file block buffer */
966
966
967
967
ASSERT (mp -> m_rbmip -> i_itemp != NULL );
968
968
ASSERT (xfs_isilocked (mp -> m_rbmip , XFS_ILOCK_EXCL ));
@@ -974,10 +974,10 @@ xfs_rtfree_extent(
974
974
/*
975
975
* Free the range of realtime blocks.
976
976
*/
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
+
981
981
/*
982
982
* Mark more blocks free in the superblock.
983
983
*/
@@ -993,7 +993,10 @@ xfs_rtfree_extent(
993
993
* (uint64_t * )& VFS_I (mp -> m_rbmip )-> i_atime = 0 ;
994
994
xfs_trans_log_inode (tp , mp -> m_rbmip , XFS_ILOG_CORE );
995
995
}
996
- return 0 ;
996
+ error = 0 ;
997
+ out :
998
+ xfs_rtbuf_cache_relse (& args );
999
+ return error ;
997
1000
}
998
1001
999
1002
/*
@@ -1084,6 +1087,7 @@ xfs_rtalloc_query_range(
1084
1087
rtstart = rtend + 1 ;
1085
1088
}
1086
1089
1090
+ xfs_rtbuf_cache_relse (& args );
1087
1091
return error ;
1088
1092
}
1089
1093
@@ -1122,6 +1126,7 @@ xfs_rtalloc_extent_is_free(
1122
1126
int error ;
1123
1127
1124
1128
error = xfs_rtcheck_range (& args , start , len , 1 , & end , & matches );
1129
+ xfs_rtbuf_cache_relse (& args );
1125
1130
if (error )
1126
1131
return error ;
1127
1132
0 commit comments