mirror of
https://github.com/versity/scoutfs.git
synced 2025-12-23 13:35:18 +00:00
Add scoutfs_block_data_from_contents()
The btree code needs to get a pointer to a whole block from just pointers to elements that it's sorting. It had some manual code that assumed details of the blocks. Let's give it a real block interface to do what it wants and make it the block API's problem to figure out how to do it. Signed-off-by: Zach Brown <zab@versity.com> Reviewed-by: Mark Fasheh <mfasheh@versity.com>
This commit is contained in:
@@ -573,6 +573,13 @@ void *scoutfs_block_data(struct scoutfs_block *bl)
|
||||
return (void *)bh->b_data;
|
||||
}
|
||||
|
||||
void *scoutfs_block_data_from_contents(const void *ptr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)ptr;
|
||||
|
||||
return (void *)(addr & ~((unsigned long)SCOUTFS_BLOCK_MASK));
|
||||
}
|
||||
|
||||
void scoutfs_block_put(struct scoutfs_block *bl)
|
||||
{
|
||||
struct buffer_head *bh = (void *)bl;
|
||||
|
||||
@@ -29,6 +29,7 @@ void scoutfs_block_unlock(struct scoutfs_block *bl, bool write);
|
||||
void scoutfs_block_forget(struct super_block *sb, u64 blkno);
|
||||
|
||||
void *scoutfs_block_data(struct scoutfs_block *bl);
|
||||
void *scoutfs_block_data_from_contents(const void *ptr);
|
||||
void scoutfs_block_put(struct scoutfs_block *bl);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -335,16 +335,9 @@ static void move_items(struct scoutfs_btree_block *dst,
|
||||
}
|
||||
}
|
||||
|
||||
static struct scoutfs_btree_block *aligned_bt(const void *ptr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)ptr;
|
||||
|
||||
return (void *)(addr & ~((unsigned long)SCOUTFS_BLOCK_MASK));
|
||||
}
|
||||
|
||||
static int sort_key_cmp(const void *A, const void *B)
|
||||
{
|
||||
struct scoutfs_btree_block *bt = aligned_bt(A);
|
||||
struct scoutfs_btree_block *bt = scoutfs_block_data_from_contents(A);
|
||||
const __le16 * __packed a = A;
|
||||
const __le16 * __packed b = B;
|
||||
|
||||
@@ -507,21 +500,6 @@ static void unlock_tree_block(struct super_block *sb,
|
||||
}
|
||||
}
|
||||
|
||||
/* sorting relies on masking pointers to find the containing block */
|
||||
static inline struct scoutfs_block *check_bl_alignment(struct scoutfs_block *bl)
|
||||
{
|
||||
if (!IS_ERR_OR_NULL(bl)) {
|
||||
struct scoutfs_btree_block *bt = scoutfs_block_data(bl);
|
||||
|
||||
if (WARN_ON_ONCE(aligned_bt(bt) != bt)) {
|
||||
scoutfs_block_put(bl);
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
}
|
||||
|
||||
return bl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize a new tree block. The caller adds references
|
||||
* to it.
|
||||
@@ -540,7 +518,7 @@ static struct scoutfs_block *alloc_tree_block(struct super_block *sb)
|
||||
bt->nr_items = 0;
|
||||
}
|
||||
|
||||
return check_bl_alignment(bl);
|
||||
return bl;
|
||||
}
|
||||
|
||||
/* the caller has ensured that the free must succeed */
|
||||
@@ -591,7 +569,7 @@ static struct scoutfs_block *get_block_ref(struct super_block *sb, int level,
|
||||
if (!IS_ERR(bl))
|
||||
set_block_lock_class(bl, level);
|
||||
|
||||
return check_bl_alignment(bl);
|
||||
return bl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user