[Ocfs2-tools-devel] [PATCH 05/23] libocfs2: Fill out the ocfs2_XXX_to_YYY() conversion APIs.
Joel Becker
joel.becker at oracle.com
Mon Aug 11 17:31:57 PDT 2008
ocfs2 often needs to convert sizes from clusters to blocks to bytes. We
only provided a few of these functions in ocfs2.h. This adds the
complete set:
ocfs2_clusters_to_blocks()
ocfs2_blocks_to_clusters()
ocfs2_clusters_to_bytes()
ocfs2_bytes_to_clusters()
ocfs2_blocks_to_bytes()
ocfs2_bytes_to_blocks()
ocfs2_clusters_in_blocks()
ocfs2_clusters_in_bytes()
ocfs2_blocks_in_bytes()
The container functions (ocfs2_XXX_in_YYY()) only go one direction; the
other direction is answered correctly by ocfs2_YYY_to_XXX().
While we're here, we standardize the handling of value overflows. Some
of the existing functions would cast an uint64_t to uint32_t without
checking. The caller just gets the lower 32bits, regardless of how they
wrapped. All functions now return UINTxx_MAX on overflow. This is not
a value that can be checked - UINTxx_MAX could have been the exact
answer - but it is a safer return than the lower 32bits. Users of this
function should prevent overflow by checking bounds before calling the
conversion.
Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
include/ocfs2/ocfs2.h | 86 +++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 79 insertions(+), 7 deletions(-)
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index d69223e..fbc3146 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -676,6 +676,11 @@ errcode_t ocfs2_set_backup_super(ocfs2_filesys *fs,
*
* ${foo}_in_${bar} is a ceiling function. clusters_in_blocks will give
* the number of clusters needed to hold a given number of blocks.
+ *
+ * These functions return UINTxx_MAX when they overflow, but UINTxx_MAX
+ * cannot be used to check overflow. UINTxx_MAX is a valid value in much
+ * of ocfs2. The caller is responsible for preventing overflow before
+ * using these functions.
*/
static inline uint64_t ocfs2_clusters_to_blocks(ocfs2_filesys *fs,
@@ -694,18 +699,54 @@ static inline uint32_t ocfs2_blocks_to_clusters(ocfs2_filesys *fs,
int b_to_c_bits =
OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits -
OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+ uint64_t ret = blocks >> b_to_c_bits;
+
+ if (ret > UINT32_MAX)
+ ret = UINT32_MAX;
- return (uint32_t)(blocks >> b_to_c_bits);
+ return (uint32_t)ret;
}
-static inline uint64_t ocfs2_blocks_in_bytes(ocfs2_filesys *fs, uint64_t bytes)
+static inline uint64_t ocfs2_clusters_to_bytes(ocfs2_filesys *fs,
+ uint32_t clusters)
{
- uint64_t ret = bytes + fs->fs_blocksize - 1;
+ uint64_t ret = clusters;
- if (ret < bytes) /* deal with wrapping */
- return UINT64_MAX;
+ ret = ret << OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
+ if (ret < clusters)
+ ret = UINT64_MAX;
- return ret >> OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+ return ret;
+}
+
+static inline uint32_t ocfs2_bytes_to_clusters(ocfs2_filesys *fs,
+ uint64_t bytes)
+{
+ uint64_t ret =
+ bytes >> OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
+
+ if (ret > UINT32_MAX)
+ ret = UINT32_MAX;
+
+ return (uint32_t)ret;
+}
+
+static inline uint64_t ocfs2_blocks_to_bytes(ocfs2_filesys *fs,
+ uint64_t blocks)
+{
+ uint64_t ret =
+ blocks << OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+
+ if (ret < blocks)
+ ret = UINT64_MAX;
+
+ return ret;
+}
+
+static inline uint64_t ocfs2_bytes_to_blocks(ocfs2_filesys *fs,
+ uint64_t bytes)
+{
+ return bytes >> OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
}
static inline uint32_t ocfs2_clusters_in_blocks(ocfs2_filesys *fs,
@@ -718,9 +759,40 @@ static inline uint32_t ocfs2_clusters_in_blocks(ocfs2_filesys *fs,
if (ret < blocks) /* deal with wrapping */
ret = UINT64_MAX;
- return (uint32_t)(ret >> c_to_b_bits);
+ ret = ret >> c_to_b_bits;
+ if (ret > UINT32_MAX)
+ ret = UINT32_MAX;
+
+ return (uint32_t)ret;
+}
+
+static inline uint32_t ocfs2_clusters_in_bytes(ocfs2_filesys *fs,
+ uint64_t bytes)
+{
+ uint64_t ret = bytes + fs->fs_clustersize - 1;
+
+ if (ret < bytes) /* deal with wrapping */
+ ret = UINT64_MAX;
+
+ ret = ret >> OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
+ if (ret > UINT32_MAX)
+ ret = UINT32_MAX;
+
+ return (uint32_t)ret;
}
+static inline uint64_t ocfs2_blocks_in_bytes(ocfs2_filesys *fs,
+ uint64_t bytes)
+{
+ uint64_t ret = bytes + fs->fs_blocksize - 1;
+
+ if (ret < bytes) /* deal with wrapping */
+ return UINT64_MAX;
+
+ return ret >> OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+}
+
+
/* given a cluster offset, calculate which block group it belongs to
* and return that block offset. */
static inline uint64_t ocfs2_which_cluster_group(ocfs2_filesys *fs,
--
1.5.6.3
More information about the Ocfs2-tools-devel
mailing list