summaryrefslogtreecommitdiff
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_format.h8
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.c109
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.h27
-rw-r--r--fs/xfs/xfs_ondisk.h3
4 files changed, 70 insertions, 77 deletions
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index d48e3a395bd9..2af891d5d171 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -691,6 +691,14 @@ struct xfs_agfl {
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;
+};
+
+/*
* XFS Timestamps
* ==============
*
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 4f096348d4b2..b81e4ffa1f44 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -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.
*/
@@ -568,15 +548,14 @@ 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 */
@@ -596,7 +575,6 @@ xfs_rtmodify_range(
* Compute the starting word's address, and starting bit.
*/
firstword = word = xfs_rtx_to_rbmword(mp, start);
- first = b = xfs_rbmblock_wordptr(bp, word);
bit = (int)(start & (XFS_NBWORD - 1));
/*
* 0 (allocated) => all zeroes; 1 (free) => all ones.
@@ -615,10 +593,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
@@ -636,12 +616,6 @@ xfs_rtmodify_range(
}
firstword = word = 0;
- first = b = xfs_rbmblock_wordptr(bp, word);
- } else {
- /*
- * Go on to the next word in the buffer
- */
- b++;
}
} else {
/*
@@ -657,7 +631,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
@@ -675,12 +649,6 @@ xfs_rtmodify_range(
}
firstword = word = 0;
- first = b = xfs_rbmblock_wordptr(bp, word);
- } else {
- /*
- * Go on to the next word in the buffer
- */
- b++;
}
}
/*
@@ -695,17 +663,18 @@ 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);
word++;
- b++;
}
/*
* Log any remaining changed bytes.
*/
- if (b > first)
+ if (word > firstword)
xfs_trans_log_rtbitmap(tp, bp, firstword, word);
return 0;
}
@@ -800,7 +769,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 */
@@ -809,6 +777,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 */
/*
@@ -827,7 +796,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.
@@ -849,7 +817,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.
*/
@@ -875,12 +844,6 @@ xfs_rtcheck_range(
}
word = 0;
- b = xfs_rbmblock_wordptr(bp, word);
- } else {
- /*
- * Go on to the next word in the buffer.
- */
- b++;
}
} else {
/*
@@ -896,7 +859,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.
*/
@@ -922,12 +886,6 @@ xfs_rtcheck_range(
}
word = 0;
- b = xfs_rbmblock_wordptr(bp, word);
- } else {
- /*
- * Go on to the next word in the buffer.
- */
- b++;
}
}
/*
@@ -942,7 +900,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.
*/
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index 01eabb9b5516..ede24de74620 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -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.
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
index c4cc99b70dd3..14d455f768d3 100644
--- a/fs/xfs/xfs_ondisk.h
+++ b/fs/xfs/xfs_ondisk.h
@@ -72,6 +72,9 @@ 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);
+
/*
* 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