mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 14:42:08 +02:00
xfs: refactor rtbitmap/summary accessors [v1.2]
Since the rtbitmap and rtsummary accessor functions have proven more
controversial than the rest of the macro refactoring, split the patchset
into two to make review easier.
v1.1: various cleanups suggested by hch
v1.2: rework the accessor functions to reduce the amount of cursor
tracking required, and create explicit bitmap/summary logging
functions
With a bit of luck, this should all go splendidly.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQQ2qTKExjcn+O1o2YRKO3ySh0YRpgUCZTFTEQAKCRBKO3ySh0YR
prDOAQD5497tQO1iiA8bdO/kHGHwUWZub45q6+AwZRjzzc5BdAD8CgvZ/8F14hGC
i80DF+GsmFL95mNHwlB1FS+lhJMF8wk=
=R0rf
-----END PGP SIGNATURE-----
Merge tag 'refactor-rtbitmap-accessors-6.7_2023-10-19' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.7-mergeA
xfs: refactor rtbitmap/summary accessors [v1.2]
Since the rtbitmap and rtsummary accessor functions have proven more
controversial than the rest of the macro refactoring, split the patchset
into two to make review easier.
v1.1: various cleanups suggested by hch
v1.2: rework the accessor functions to reduce the amount of cursor
tracking required, and create explicit bitmap/summary logging
functions
With a bit of luck, this should all go splendidly.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
* tag 'refactor-rtbitmap-accessors-6.7_2023-10-19' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
xfs: use accessor functions for summary info words
xfs: create helpers for rtsummary block/wordcount computations
xfs: use accessor functions for bitmap words
xfs: create a helper to handle logging parts of rt bitmap/summary blocks
This commit is contained in:
commit
830b4abfe2
|
|
@ -690,6 +690,22 @@ struct xfs_agfl {
|
|||
ASSERT(xfs_daddr_to_agno(mp, d) == \
|
||||
xfs_daddr_to_agno(mp, (d) + (len) - 1)))
|
||||
|
||||
/*
|
||||
* Realtime bitmap information is accessed by the word, which is currently
|
||||
* stored in host-endian format.
|
||||
*/
|
||||
union xfs_rtword_raw {
|
||||
__u32 old;
|
||||
};
|
||||
|
||||
/*
|
||||
* Realtime summary counts are accessed by the word, which is currently
|
||||
* stored in host-endian format.
|
||||
*/
|
||||
union xfs_suminfo_raw {
|
||||
__u32 old;
|
||||
};
|
||||
|
||||
/*
|
||||
* XFS Timestamps
|
||||
* ==============
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ xfs_rtfind_back(
|
|||
xfs_rtxnum_t limit, /* last rtext to look at */
|
||||
xfs_rtxnum_t *rtx) /* out: start rtext found */
|
||||
{
|
||||
xfs_rtword_t *b; /* current word in buffer */
|
||||
int bit; /* bit number in the word */
|
||||
xfs_fileoff_t block; /* bitmap block number */
|
||||
struct xfs_buf *bp; /* buf for the block */
|
||||
|
|
@ -110,6 +109,7 @@ xfs_rtfind_back(
|
|||
xfs_rtword_t mask; /* mask of relevant bits for value */
|
||||
xfs_rtword_t want; /* mask for "good" values */
|
||||
xfs_rtword_t wdiff; /* difference from wanted value */
|
||||
xfs_rtword_t incore;
|
||||
unsigned int word; /* word number in the buffer */
|
||||
|
||||
/*
|
||||
|
|
@ -125,14 +125,14 @@ xfs_rtfind_back(
|
|||
* Get the first word's index & point to it.
|
||||
*/
|
||||
word = xfs_rtx_to_rbmword(mp, start);
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
bit = (int)(start & (XFS_NBWORD - 1));
|
||||
len = start - limit + 1;
|
||||
/*
|
||||
* Compute match value, based on the bit at start: if 1 (free)
|
||||
* then all-ones, else all-zeroes.
|
||||
*/
|
||||
want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
|
||||
/*
|
||||
* If the starting position is not word-aligned, deal with the
|
||||
* partial word.
|
||||
|
|
@ -149,7 +149,7 @@ xfs_rtfind_back(
|
|||
* Calculate the difference between the value there
|
||||
* and what we're looking for.
|
||||
*/
|
||||
if ((wdiff = (*b ^ want) & mask)) {
|
||||
if ((wdiff = (incore ^ want) & mask)) {
|
||||
/*
|
||||
* Different. Mark where we are and return.
|
||||
*/
|
||||
|
|
@ -174,12 +174,6 @@ xfs_rtfind_back(
|
|||
}
|
||||
|
||||
word = mp->m_blockwsize - 1;
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the previous word in the buffer.
|
||||
*/
|
||||
b--;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -195,7 +189,8 @@ xfs_rtfind_back(
|
|||
/*
|
||||
* Compute difference between actual and desired value.
|
||||
*/
|
||||
if ((wdiff = *b ^ want)) {
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if ((wdiff = incore ^ want)) {
|
||||
/*
|
||||
* Different, mark where we are and return.
|
||||
*/
|
||||
|
|
@ -220,12 +215,6 @@ xfs_rtfind_back(
|
|||
}
|
||||
|
||||
word = mp->m_blockwsize - 1;
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the previous word in the buffer.
|
||||
*/
|
||||
b--;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
@ -242,7 +231,8 @@ xfs_rtfind_back(
|
|||
/*
|
||||
* Compute difference between actual and desired value.
|
||||
*/
|
||||
if ((wdiff = (*b ^ want) & mask)) {
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if ((wdiff = (incore ^ want) & mask)) {
|
||||
/*
|
||||
* Different, mark where we are and return.
|
||||
*/
|
||||
|
|
@ -273,7 +263,6 @@ xfs_rtfind_forw(
|
|||
xfs_rtxnum_t limit, /* last rtext to look at */
|
||||
xfs_rtxnum_t *rtx) /* out: start rtext found */
|
||||
{
|
||||
xfs_rtword_t *b; /* current word in buffer */
|
||||
int bit; /* bit number in the word */
|
||||
xfs_fileoff_t block; /* bitmap block number */
|
||||
struct xfs_buf *bp; /* buf for the block */
|
||||
|
|
@ -284,6 +273,7 @@ xfs_rtfind_forw(
|
|||
xfs_rtword_t mask; /* mask of relevant bits for value */
|
||||
xfs_rtword_t want; /* mask for "good" values */
|
||||
xfs_rtword_t wdiff; /* difference from wanted value */
|
||||
xfs_rtword_t incore;
|
||||
unsigned int word; /* word number in the buffer */
|
||||
|
||||
/*
|
||||
|
|
@ -299,14 +289,14 @@ xfs_rtfind_forw(
|
|||
* Get the first word's index & point to it.
|
||||
*/
|
||||
word = xfs_rtx_to_rbmword(mp, start);
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
bit = (int)(start & (XFS_NBWORD - 1));
|
||||
len = limit - start + 1;
|
||||
/*
|
||||
* Compute match value, based on the bit at start: if 1 (free)
|
||||
* then all-ones, else all-zeroes.
|
||||
*/
|
||||
want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
|
||||
/*
|
||||
* If the starting position is not word-aligned, deal with the
|
||||
* partial word.
|
||||
|
|
@ -322,7 +312,7 @@ xfs_rtfind_forw(
|
|||
* Calculate the difference between the value there
|
||||
* and what we're looking for.
|
||||
*/
|
||||
if ((wdiff = (*b ^ want) & mask)) {
|
||||
if ((wdiff = (incore ^ want) & mask)) {
|
||||
/*
|
||||
* Different. Mark where we are and return.
|
||||
*/
|
||||
|
|
@ -347,12 +337,6 @@ xfs_rtfind_forw(
|
|||
}
|
||||
|
||||
word = 0;
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the previous word in the buffer.
|
||||
*/
|
||||
b++;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -368,7 +352,8 @@ xfs_rtfind_forw(
|
|||
/*
|
||||
* Compute difference between actual and desired value.
|
||||
*/
|
||||
if ((wdiff = *b ^ want)) {
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if ((wdiff = incore ^ want)) {
|
||||
/*
|
||||
* Different, mark where we are and return.
|
||||
*/
|
||||
|
|
@ -393,12 +378,6 @@ xfs_rtfind_forw(
|
|||
}
|
||||
|
||||
word = 0;
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the next word in the buffer.
|
||||
*/
|
||||
b++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
@ -413,7 +392,8 @@ xfs_rtfind_forw(
|
|||
/*
|
||||
* Compute difference between actual and desired value.
|
||||
*/
|
||||
if ((wdiff = (*b ^ want) & mask)) {
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if ((wdiff = (incore ^ want) & mask)) {
|
||||
/*
|
||||
* Different, mark where we are and return.
|
||||
*/
|
||||
|
|
@ -432,6 +412,21 @@ xfs_rtfind_forw(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Log rtsummary counter at @infoword. */
|
||||
static inline void
|
||||
xfs_trans_log_rtsummary(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_buf *bp,
|
||||
unsigned int infoword)
|
||||
{
|
||||
size_t first, last;
|
||||
|
||||
first = (void *)xfs_rsumblock_infoptr(bp, infoword) - bp->b_addr;
|
||||
last = first + sizeof(xfs_suminfo_t) - 1;
|
||||
|
||||
xfs_trans_log_buf(tp, bp, first, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read and/or modify the summary information for a given extent size,
|
||||
* bitmap block combination.
|
||||
|
|
@ -456,7 +451,6 @@ xfs_rtmodify_summary_int(
|
|||
int error; /* error value */
|
||||
xfs_fileoff_t sb; /* summary fsblock */
|
||||
xfs_rtsumoff_t so; /* index into the summary file */
|
||||
xfs_suminfo_t *sp; /* pointer to returned data */
|
||||
unsigned int infoword;
|
||||
|
||||
/*
|
||||
|
|
@ -495,21 +489,21 @@ xfs_rtmodify_summary_int(
|
|||
* Point to the summary information, modify/log it, and/or copy it out.
|
||||
*/
|
||||
infoword = xfs_rtsumoffs_to_infoword(mp, so);
|
||||
sp = xfs_rsumblock_infoptr(bp, infoword);
|
||||
if (delta) {
|
||||
uint first = (uint)((char *)sp - (char *)bp->b_addr);
|
||||
xfs_suminfo_t val = xfs_suminfo_add(bp, infoword, delta);
|
||||
|
||||
*sp += delta;
|
||||
if (mp->m_rsum_cache) {
|
||||
if (*sp == 0 && log == mp->m_rsum_cache[bbno])
|
||||
if (val == 0 && log == mp->m_rsum_cache[bbno])
|
||||
mp->m_rsum_cache[bbno]++;
|
||||
if (*sp != 0 && log < mp->m_rsum_cache[bbno])
|
||||
if (val != 0 && log < mp->m_rsum_cache[bbno])
|
||||
mp->m_rsum_cache[bbno] = log;
|
||||
}
|
||||
xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
|
||||
xfs_trans_log_rtsummary(tp, bp, infoword);
|
||||
if (sum)
|
||||
*sum = val;
|
||||
} else if (sum) {
|
||||
*sum = xfs_suminfo_get(bp, infoword);
|
||||
}
|
||||
if (sum)
|
||||
*sum = *sp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -527,6 +521,22 @@ xfs_rtmodify_summary(
|
|||
delta, rbpp, rsb, NULL);
|
||||
}
|
||||
|
||||
/* Log rtbitmap block from the word @from to the byte before @next. */
|
||||
static inline void
|
||||
xfs_trans_log_rtbitmap(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_buf *bp,
|
||||
unsigned int from,
|
||||
unsigned int next)
|
||||
{
|
||||
size_t first, last;
|
||||
|
||||
first = (void *)xfs_rbmblock_wordptr(bp, from) - bp->b_addr;
|
||||
last = ((void *)xfs_rbmblock_wordptr(bp, next) - 1) - bp->b_addr;
|
||||
|
||||
xfs_trans_log_buf(tp, bp, first, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the given range of bitmap bits to the given value.
|
||||
* Do whatever I/O and logging is required.
|
||||
|
|
@ -539,15 +549,15 @@ xfs_rtmodify_range(
|
|||
xfs_rtxlen_t len, /* length of extent to modify */
|
||||
int val) /* 1 for free, 0 for allocated */
|
||||
{
|
||||
xfs_rtword_t *b; /* current word in buffer */
|
||||
int bit; /* bit number in the word */
|
||||
xfs_fileoff_t block; /* bitmap block number */
|
||||
struct xfs_buf *bp; /* buf for the block */
|
||||
int error; /* error value */
|
||||
xfs_rtword_t *first; /* first used word in the buffer */
|
||||
int i; /* current bit number rel. to start */
|
||||
int lastbit; /* last useful bit in word */
|
||||
xfs_rtword_t mask; /* mask o frelevant bits for value */
|
||||
xfs_rtword_t incore;
|
||||
unsigned int firstword; /* first word used in the buffer */
|
||||
unsigned int word; /* word number in the buffer */
|
||||
|
||||
/*
|
||||
|
|
@ -565,8 +575,7 @@ xfs_rtmodify_range(
|
|||
/*
|
||||
* Compute the starting word's address, and starting bit.
|
||||
*/
|
||||
word = xfs_rtx_to_rbmword(mp, start);
|
||||
first = b = xfs_rbmblock_wordptr(bp, word);
|
||||
firstword = word = xfs_rtx_to_rbmword(mp, start);
|
||||
bit = (int)(start & (XFS_NBWORD - 1));
|
||||
/*
|
||||
* 0 (allocated) => all zeroes; 1 (free) => all ones.
|
||||
|
|
@ -585,10 +594,12 @@ xfs_rtmodify_range(
|
|||
/*
|
||||
* Set/clear the active bits.
|
||||
*/
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if (val)
|
||||
*b |= mask;
|
||||
incore |= mask;
|
||||
else
|
||||
*b &= ~mask;
|
||||
incore &= ~mask;
|
||||
xfs_rtbitmap_setword(bp, word, incore);
|
||||
i = lastbit - bit;
|
||||
/*
|
||||
* Go on to the next block if that's where the next word is
|
||||
|
|
@ -599,21 +610,13 @@ xfs_rtmodify_range(
|
|||
* Log the changed part of this block.
|
||||
* Get the next one.
|
||||
*/
|
||||
xfs_trans_log_buf(tp, bp,
|
||||
(uint)((char *)first - (char *)bp->b_addr),
|
||||
(uint)((char *)b - (char *)bp->b_addr));
|
||||
xfs_trans_log_rtbitmap(tp, bp, firstword, word);
|
||||
error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
word = 0;
|
||||
first = b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the next word in the buffer
|
||||
*/
|
||||
b++;
|
||||
firstword = word = 0;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -629,7 +632,7 @@ xfs_rtmodify_range(
|
|||
/*
|
||||
* Set the word value correctly.
|
||||
*/
|
||||
*b = val;
|
||||
xfs_rtbitmap_setword(bp, word, val);
|
||||
i += XFS_NBWORD;
|
||||
/*
|
||||
* Go on to the next block if that's where the next word is
|
||||
|
|
@ -640,21 +643,13 @@ xfs_rtmodify_range(
|
|||
* Log the changed part of this block.
|
||||
* Get the next one.
|
||||
*/
|
||||
xfs_trans_log_buf(tp, bp,
|
||||
(uint)((char *)first - (char *)bp->b_addr),
|
||||
(uint)((char *)b - (char *)bp->b_addr));
|
||||
xfs_trans_log_rtbitmap(tp, bp, firstword, word);
|
||||
error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
word = 0;
|
||||
first = b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the next word in the buffer
|
||||
*/
|
||||
b++;
|
||||
firstword = word = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
@ -669,19 +664,19 @@ xfs_rtmodify_range(
|
|||
/*
|
||||
* Set/clear the active bits.
|
||||
*/
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if (val)
|
||||
*b |= mask;
|
||||
incore |= mask;
|
||||
else
|
||||
*b &= ~mask;
|
||||
b++;
|
||||
incore &= ~mask;
|
||||
xfs_rtbitmap_setword(bp, word, incore);
|
||||
word++;
|
||||
}
|
||||
/*
|
||||
* Log any remaining changed bytes.
|
||||
*/
|
||||
if (b > first)
|
||||
xfs_trans_log_buf(tp, bp,
|
||||
(uint)((char *)first - (char *)bp->b_addr),
|
||||
(uint)((char *)b - (char *)bp->b_addr - 1));
|
||||
if (word > firstword)
|
||||
xfs_trans_log_rtbitmap(tp, bp, firstword, word);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -775,7 +770,6 @@ xfs_rtcheck_range(
|
|||
xfs_rtxnum_t *new, /* out: first rtext not matching */
|
||||
int *stat) /* out: 1 for matches, 0 for not */
|
||||
{
|
||||
xfs_rtword_t *b; /* current word in buffer */
|
||||
int bit; /* bit number in the word */
|
||||
xfs_fileoff_t block; /* bitmap block number */
|
||||
struct xfs_buf *bp; /* buf for the block */
|
||||
|
|
@ -784,6 +778,7 @@ xfs_rtcheck_range(
|
|||
xfs_rtxnum_t lastbit; /* last useful bit in word */
|
||||
xfs_rtword_t mask; /* mask of relevant bits for value */
|
||||
xfs_rtword_t wdiff; /* difference from wanted value */
|
||||
xfs_rtword_t incore;
|
||||
unsigned int word; /* word number in the buffer */
|
||||
|
||||
/*
|
||||
|
|
@ -802,7 +797,6 @@ xfs_rtcheck_range(
|
|||
* Compute the starting word's address, and starting bit.
|
||||
*/
|
||||
word = xfs_rtx_to_rbmword(mp, start);
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
bit = (int)(start & (XFS_NBWORD - 1));
|
||||
/*
|
||||
* 0 (allocated) => all zero's; 1 (free) => all one's.
|
||||
|
|
@ -824,7 +818,8 @@ xfs_rtcheck_range(
|
|||
/*
|
||||
* Compute difference between actual and desired value.
|
||||
*/
|
||||
if ((wdiff = (*b ^ val) & mask)) {
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if ((wdiff = (incore ^ val) & mask)) {
|
||||
/*
|
||||
* Different, compute first wrong bit and return.
|
||||
*/
|
||||
|
|
@ -850,12 +845,6 @@ xfs_rtcheck_range(
|
|||
}
|
||||
|
||||
word = 0;
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the next word in the buffer.
|
||||
*/
|
||||
b++;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -871,7 +860,8 @@ xfs_rtcheck_range(
|
|||
/*
|
||||
* Compute difference between actual and desired value.
|
||||
*/
|
||||
if ((wdiff = *b ^ val)) {
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if ((wdiff = incore ^ val)) {
|
||||
/*
|
||||
* Different, compute first wrong bit and return.
|
||||
*/
|
||||
|
|
@ -897,12 +887,6 @@ xfs_rtcheck_range(
|
|||
}
|
||||
|
||||
word = 0;
|
||||
b = xfs_rbmblock_wordptr(bp, word);
|
||||
} else {
|
||||
/*
|
||||
* Go on to the next word in the buffer.
|
||||
*/
|
||||
b++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
@ -917,7 +901,8 @@ xfs_rtcheck_range(
|
|||
/*
|
||||
* Compute difference between actual and desired value.
|
||||
*/
|
||||
if ((wdiff = (*b ^ val) & mask)) {
|
||||
incore = xfs_rtbitmap_getword(bp, word);
|
||||
if ((wdiff = (incore ^ val) & mask)) {
|
||||
/*
|
||||
* Different, compute first wrong bit and return.
|
||||
*/
|
||||
|
|
@ -1162,3 +1147,32 @@ xfs_rtbitmap_wordcount(
|
|||
blocks = xfs_rtbitmap_blockcount(mp, rtextents);
|
||||
return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
|
||||
}
|
||||
|
||||
/* Compute the number of rtsummary blocks needed to track the given rt space. */
|
||||
xfs_filblks_t
|
||||
xfs_rtsummary_blockcount(
|
||||
struct xfs_mount *mp,
|
||||
unsigned int rsumlevels,
|
||||
xfs_extlen_t rbmblocks)
|
||||
{
|
||||
unsigned long long rsumwords;
|
||||
|
||||
rsumwords = (unsigned long long)rsumlevels * rbmblocks;
|
||||
return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the number of rtsummary info words needed to populate every block of
|
||||
* a summary file that is large enough to track the given rt space.
|
||||
*/
|
||||
unsigned long long
|
||||
xfs_rtsummary_wordcount(
|
||||
struct xfs_mount *mp,
|
||||
unsigned int rsumlevels,
|
||||
xfs_extlen_t rbmblocks)
|
||||
{
|
||||
xfs_filblks_t blocks;
|
||||
|
||||
blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks);
|
||||
return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,16 +159,39 @@ xfs_rbmblock_to_rtx(
|
|||
}
|
||||
|
||||
/* Return a pointer to a bitmap word within a rt bitmap block. */
|
||||
static inline xfs_rtword_t *
|
||||
static inline union xfs_rtword_raw *
|
||||
xfs_rbmblock_wordptr(
|
||||
struct xfs_buf *bp,
|
||||
unsigned int index)
|
||||
{
|
||||
xfs_rtword_t *words = bp->b_addr;
|
||||
union xfs_rtword_raw *words = bp->b_addr;
|
||||
|
||||
return words + index;
|
||||
}
|
||||
|
||||
/* Convert an ondisk bitmap word to its incore representation. */
|
||||
static inline xfs_rtword_t
|
||||
xfs_rtbitmap_getword(
|
||||
struct xfs_buf *bp,
|
||||
unsigned int index)
|
||||
{
|
||||
union xfs_rtword_raw *word = xfs_rbmblock_wordptr(bp, index);
|
||||
|
||||
return word->old;
|
||||
}
|
||||
|
||||
/* Set an ondisk bitmap word from an incore representation. */
|
||||
static inline void
|
||||
xfs_rtbitmap_setword(
|
||||
struct xfs_buf *bp,
|
||||
unsigned int index,
|
||||
xfs_rtword_t value)
|
||||
{
|
||||
union xfs_rtword_raw *word = xfs_rbmblock_wordptr(bp, index);
|
||||
|
||||
word->old = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t
|
||||
* offset within the rt summary file.
|
||||
|
|
@ -209,16 +232,40 @@ xfs_rtsumoffs_to_infoword(
|
|||
}
|
||||
|
||||
/* Return a pointer to a summary info word within a rt summary block. */
|
||||
static inline xfs_suminfo_t *
|
||||
static inline union xfs_suminfo_raw *
|
||||
xfs_rsumblock_infoptr(
|
||||
struct xfs_buf *bp,
|
||||
unsigned int index)
|
||||
{
|
||||
xfs_suminfo_t *info = bp->b_addr;
|
||||
union xfs_suminfo_raw *info = bp->b_addr;
|
||||
|
||||
return info + index;
|
||||
}
|
||||
|
||||
/* Get the current value of a summary counter. */
|
||||
static inline xfs_suminfo_t
|
||||
xfs_suminfo_get(
|
||||
struct xfs_buf *bp,
|
||||
unsigned int index)
|
||||
{
|
||||
union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(bp, index);
|
||||
|
||||
return info->old;
|
||||
}
|
||||
|
||||
/* Add to the current value of a summary counter and return the new value. */
|
||||
static inline xfs_suminfo_t
|
||||
xfs_suminfo_add(
|
||||
struct xfs_buf *bp,
|
||||
unsigned int index,
|
||||
int delta)
|
||||
{
|
||||
union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(bp, index);
|
||||
|
||||
info->old += delta;
|
||||
return info->old;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions for walking free space rtextents in the realtime bitmap.
|
||||
*/
|
||||
|
|
@ -285,6 +332,11 @@ xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t
|
|||
rtextents);
|
||||
unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp,
|
||||
xfs_rtbxlen_t rtextents);
|
||||
|
||||
xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
|
||||
unsigned int rsumlevels, xfs_extlen_t rbmblocks);
|
||||
unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp,
|
||||
unsigned int rsumlevels, xfs_extlen_t rbmblocks);
|
||||
#else /* CONFIG_XFS_RT */
|
||||
# define xfs_rtfree_extent(t,b,l) (-ENOSYS)
|
||||
# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS)
|
||||
|
|
@ -299,6 +351,8 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
|
|||
return 0;
|
||||
}
|
||||
# define xfs_rtbitmap_wordcount(mp, r) (0)
|
||||
# define xfs_rtsummary_blockcount(mp, l, b) (0)
|
||||
# define xfs_rtsummary_wordcount(mp, l, b) (0)
|
||||
#endif /* CONFIG_XFS_RT */
|
||||
|
||||
#endif /* __XFS_RTBITMAP_H__ */
|
||||
|
|
|
|||
|
|
@ -82,9 +82,10 @@ static inline int
|
|||
xfsum_load(
|
||||
struct xfs_scrub *sc,
|
||||
xfs_rtsumoff_t sumoff,
|
||||
xfs_suminfo_t *info)
|
||||
union xfs_suminfo_raw *rawinfo)
|
||||
{
|
||||
return xfile_obj_load(sc->xfile, info, sizeof(xfs_suminfo_t),
|
||||
return xfile_obj_load(sc->xfile, rawinfo,
|
||||
sizeof(union xfs_suminfo_raw),
|
||||
sumoff << XFS_WORDLOG);
|
||||
}
|
||||
|
||||
|
|
@ -92,9 +93,10 @@ static inline int
|
|||
xfsum_store(
|
||||
struct xfs_scrub *sc,
|
||||
xfs_rtsumoff_t sumoff,
|
||||
const xfs_suminfo_t info)
|
||||
const union xfs_suminfo_raw rawinfo)
|
||||
{
|
||||
return xfile_obj_store(sc->xfile, &info, sizeof(xfs_suminfo_t),
|
||||
return xfile_obj_store(sc->xfile, &rawinfo,
|
||||
sizeof(union xfs_suminfo_raw),
|
||||
sumoff << XFS_WORDLOG);
|
||||
}
|
||||
|
||||
|
|
@ -102,13 +104,22 @@ static inline int
|
|||
xfsum_copyout(
|
||||
struct xfs_scrub *sc,
|
||||
xfs_rtsumoff_t sumoff,
|
||||
xfs_suminfo_t *info,
|
||||
union xfs_suminfo_raw *rawinfo,
|
||||
unsigned int nr_words)
|
||||
{
|
||||
return xfile_obj_load(sc->xfile, info, nr_words << XFS_WORDLOG,
|
||||
return xfile_obj_load(sc->xfile, rawinfo, nr_words << XFS_WORDLOG,
|
||||
sumoff << XFS_WORDLOG);
|
||||
}
|
||||
|
||||
static inline xfs_suminfo_t
|
||||
xchk_rtsum_inc(
|
||||
struct xfs_mount *mp,
|
||||
union xfs_suminfo_raw *v)
|
||||
{
|
||||
v->old += 1;
|
||||
return v->old;
|
||||
}
|
||||
|
||||
/* Update the summary file to reflect the free extent that we've accumulated. */
|
||||
STATIC int
|
||||
xchk_rtsum_record_free(
|
||||
|
|
@ -123,7 +134,8 @@ xchk_rtsum_record_free(
|
|||
xfs_filblks_t rtlen;
|
||||
xfs_rtsumoff_t offs;
|
||||
unsigned int lenlog;
|
||||
xfs_suminfo_t v = 0;
|
||||
union xfs_suminfo_raw v;
|
||||
xfs_suminfo_t value;
|
||||
int error = 0;
|
||||
|
||||
if (xchk_should_terminate(sc, &error))
|
||||
|
|
@ -147,9 +159,9 @@ xchk_rtsum_record_free(
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
v++;
|
||||
value = xchk_rtsum_inc(sc->mp, &v);
|
||||
trace_xchk_rtsum_record_free(mp, rec->ar_startext, rec->ar_extcount,
|
||||
lenlog, offs, v);
|
||||
lenlog, offs, value);
|
||||
|
||||
return xfsum_store(sc, offs, v);
|
||||
}
|
||||
|
|
@ -184,7 +196,7 @@ xchk_rtsum_compare(
|
|||
int nmap;
|
||||
|
||||
for (off = 0; off < XFS_B_TO_FSB(mp, mp->m_rsumsize); off++) {
|
||||
xfs_suminfo_t *ondisk_info;
|
||||
union xfs_suminfo_raw *ondisk_info;
|
||||
int error = 0;
|
||||
|
||||
if (xchk_should_terminate(sc, &error))
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "xfs_inode.h"
|
||||
#include "xfs_btree.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
#include "scrub/scrub.h"
|
||||
#include "scrub/xfile.h"
|
||||
#include "scrub/xfarray.h"
|
||||
|
|
|
|||
|
|
@ -1038,8 +1038,8 @@ TRACE_EVENT(xfarray_sort_stats,
|
|||
TRACE_EVENT(xchk_rtsum_record_free,
|
||||
TP_PROTO(struct xfs_mount *mp, xfs_rtxnum_t start,
|
||||
xfs_rtbxlen_t len, unsigned int log, loff_t pos,
|
||||
xfs_suminfo_t v),
|
||||
TP_ARGS(mp, start, len, log, pos, v),
|
||||
xfs_suminfo_t value),
|
||||
TP_ARGS(mp, start, len, log, pos, value),
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(dev_t, rtdev)
|
||||
|
|
@ -1047,7 +1047,7 @@ TRACE_EVENT(xchk_rtsum_record_free,
|
|||
__field(unsigned long long, len)
|
||||
__field(unsigned int, log)
|
||||
__field(loff_t, pos)
|
||||
__field(xfs_suminfo_t, v)
|
||||
__field(xfs_suminfo_t, value)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->dev = mp->m_super->s_dev;
|
||||
|
|
@ -1056,7 +1056,7 @@ TRACE_EVENT(xchk_rtsum_record_free,
|
|||
__entry->len = len;
|
||||
__entry->log = log;
|
||||
__entry->pos = pos;
|
||||
__entry->v = v;
|
||||
__entry->value = value;
|
||||
),
|
||||
TP_printk("dev %d:%d rtdev %d:%d rtx 0x%llx rtxcount 0x%llx log %u rsumpos 0x%llx sumcount %u",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
|
|
@ -1065,7 +1065,7 @@ TRACE_EVENT(xchk_rtsum_record_free,
|
|||
__entry->len,
|
||||
__entry->log,
|
||||
__entry->pos,
|
||||
__entry->v)
|
||||
__entry->value)
|
||||
);
|
||||
#endif /* CONFIG_XFS_RT */
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ xfs_check_ondisk_structs(void)
|
|||
XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_map_t, 4);
|
||||
XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_name_local_t, 4);
|
||||
|
||||
/* realtime structures */
|
||||
XFS_CHECK_STRUCT_SIZE(union xfs_rtword_raw, 4);
|
||||
XFS_CHECK_STRUCT_SIZE(union xfs_suminfo_raw, 4);
|
||||
|
||||
/*
|
||||
* m68k has problems with xfs_attr_leaf_name_remote_t, but we pad it to
|
||||
* 4 bytes anyway so it's not obviously a problem. Hence for the moment
|
||||
|
|
|
|||
|
|
@ -1001,8 +1001,7 @@ xfs_growfs_rt(
|
|||
nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents);
|
||||
nrextslog = xfs_highbit32(nrextents);
|
||||
nrsumlevels = nrextslog + 1;
|
||||
nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
|
||||
nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
|
||||
nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, nrbmblocks);
|
||||
nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
|
||||
/*
|
||||
* New summary size can't be more than half the size of
|
||||
|
|
@ -1063,10 +1062,8 @@ xfs_growfs_rt(
|
|||
ASSERT(nsbp->sb_rextents != 0);
|
||||
nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
|
||||
nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
|
||||
nrsumsize =
|
||||
(uint)sizeof(xfs_suminfo_t) * nrsumlevels *
|
||||
nsbp->sb_rbmblocks;
|
||||
nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
|
||||
nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels,
|
||||
nsbp->sb_rbmblocks);
|
||||
nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
|
||||
/*
|
||||
* Start a transaction, get the log reservation.
|
||||
|
|
@ -1272,6 +1269,7 @@ xfs_rtmount_init(
|
|||
struct xfs_buf *bp; /* buffer for last block of subvolume */
|
||||
struct xfs_sb *sbp; /* filesystem superblock copy in mount */
|
||||
xfs_daddr_t d; /* address of last block of subvolume */
|
||||
unsigned int rsumblocks;
|
||||
int error;
|
||||
|
||||
sbp = &mp->m_sb;
|
||||
|
|
@ -1283,10 +1281,9 @@ xfs_rtmount_init(
|
|||
return -ENODEV;
|
||||
}
|
||||
mp->m_rsumlevels = sbp->sb_rextslog + 1;
|
||||
mp->m_rsumsize =
|
||||
(uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels *
|
||||
sbp->sb_rbmblocks;
|
||||
mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize);
|
||||
rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels,
|
||||
mp->m_sb.sb_rbmblocks);
|
||||
mp->m_rsumsize = XFS_FSB_TO_B(mp, rsumblocks);
|
||||
mp->m_rbmip = mp->m_rsumip = NULL;
|
||||
/*
|
||||
* Check that the realtime section is an ok size.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user