mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-09 13:23:14 +00:00
scoutfs: add scoutfs_btree_hole() for finding keys
Directory entries found a hole in the key range between the first and last possible hash value for a new entry's key. The xattrs want to do the same thing so let's extract this into a proper function. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -953,3 +953,38 @@ void scoutfs_btree_release(struct scoutfs_btree_cursor *curs)
|
||||
}
|
||||
curs->bl = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first missing key between the caller's keys, inclusive. Set
|
||||
* the caller's hole key and return 0 if we find a missing key. Return
|
||||
* -ENOSPC if all the keys in the range were present or -errno on errors.
|
||||
*
|
||||
* The caller ensures that it's safe for us to be walking this region
|
||||
* of the tree.
|
||||
*/
|
||||
int scoutfs_btree_hole(struct super_block *sb, struct scoutfs_key *first,
|
||||
struct scoutfs_key *last, struct scoutfs_key *hole)
|
||||
{
|
||||
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
|
||||
int ret;
|
||||
|
||||
*hole = *first;
|
||||
while ((ret = scoutfs_btree_next(sb, first, last, &curs)) > 0) {
|
||||
/* return our expected hole if we skipped it */
|
||||
if (scoutfs_key_cmp(hole, curs.key) < 0)
|
||||
break;
|
||||
|
||||
*hole = *curs.key;
|
||||
scoutfs_inc_key(hole);
|
||||
}
|
||||
scoutfs_btree_release(&curs);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (scoutfs_key_cmp(hole, last) <= 0)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -ENOSPC;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ int scoutfs_btree_next(struct super_block *sb, struct scoutfs_key *first,
|
||||
int scoutfs_btree_dirty(struct super_block *sb, struct scoutfs_key *key);
|
||||
void scoutfs_btree_update(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct scoutfs_btree_cursor *curs);
|
||||
int scoutfs_btree_hole(struct super_block *sb, struct scoutfs_key *first,
|
||||
struct scoutfs_key *last, struct scoutfs_key *hole);
|
||||
|
||||
void scoutfs_btree_release(struct scoutfs_btree_cursor *curs);
|
||||
|
||||
|
||||
@@ -341,21 +341,10 @@ static int scoutfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
scoutfs_set_key(&last, scoutfs_ino(dir), SCOUTFS_DIRENT_KEY,
|
||||
last_dirent_key_offset(h));
|
||||
|
||||
/* find the first unoccupied key offset after the hashed name */
|
||||
key = first;
|
||||
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
|
||||
key = *curs.key;
|
||||
scoutfs_inc_key(&key);
|
||||
}
|
||||
scoutfs_btree_release(&curs);
|
||||
if (ret < 0)
|
||||
ret = scoutfs_btree_hole(sb, &first, &last, &key);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (scoutfs_key_cmp(&key, &last) > 0) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = scoutfs_btree_insert(sb, &key, bytes, &curs);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
Reference in New Issue
Block a user