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:
Zach Brown
2016-11-07 11:53:03 -08:00
parent 3d66a4b3dd
commit 03787f23d3
3 changed files with 11 additions and 25 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}
/*