scoutfs: specify btree root

The btree functions currently don't take a specific root argument.  They
assume, deep down in btree_walk, that there's only one btree in the
system.  We're going to be adding a few more to support richer
allocation.

To prepare for this we have the btree functions take an explicit btree
argument.  This should make no functional difference.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2016-09-21 10:04:07 -07:00
parent d2a696f4bd
commit 2bed78c269
8 changed files with 146 additions and 96 deletions
+36 -31
View File
@@ -840,13 +840,13 @@ out:
* the next block when they're done with the block this returns.
*/
static struct buffer_head *btree_walk(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key,
struct scoutfs_key *next_key,
unsigned int val_len, u64 seq, int op)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_btree_block *parent = NULL;
struct scoutfs_btree_root *root;
struct buffer_head *par_bh = NULL;
struct buffer_head *bh = NULL;
struct scoutfs_btree_item *item = NULL;
@@ -865,8 +865,6 @@ static struct buffer_head *btree_walk(struct super_block *sb,
lock_block(sbi, par_bh, dirty);
/* XXX one for now */
root = &sbi->super.btree_root;
ref = &root->ref;
level = root->height;
@@ -986,7 +984,9 @@ static void set_cursor(struct scoutfs_btree_cursor *curs,
* Point the caller's cursor at the item if it's found. It can't be
* modified. -ENOENT is returned if the key isn't found in the tree.
*/
int scoutfs_btree_lookup(struct super_block *sb, struct scoutfs_key *key,
int scoutfs_btree_lookup(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key,
struct scoutfs_btree_cursor *curs)
{
struct scoutfs_btree_block *bt;
@@ -997,7 +997,7 @@ int scoutfs_btree_lookup(struct super_block *sb, struct scoutfs_key *key,
BUG_ON(curs->bh);
bh = btree_walk(sb, key, NULL, 0, 0, 0);
bh = btree_walk(sb, root, key, NULL, 0, 0, 0);
if (IS_ERR(bh))
return PTR_ERR(bh);
bt = bh_data(bh);
@@ -1023,8 +1023,9 @@ int scoutfs_btree_lookup(struct super_block *sb, struct scoutfs_key *key,
*
* XXX this walks the treap twice, which isn't great
*/
int scoutfs_btree_insert(struct super_block *sb, struct scoutfs_key *key,
unsigned int val_len,
int scoutfs_btree_insert(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key, unsigned int val_len,
struct scoutfs_btree_cursor *curs)
{
struct scoutfs_btree_block *bt;
@@ -1035,7 +1036,7 @@ int scoutfs_btree_insert(struct super_block *sb, struct scoutfs_key *key,
BUG_ON(curs->bh);
bh = btree_walk(sb, key, NULL, val_len, 0, WALK_INSERT);
bh = btree_walk(sb, root, key, NULL, val_len, 0, WALK_INSERT);
if (IS_ERR(bh))
return PTR_ERR(bh);
bt = bh_data(bh);
@@ -1058,17 +1059,17 @@ int scoutfs_btree_insert(struct super_block *sb, struct scoutfs_key *key,
* Delete an item from the tree. -ENOENT is returned if the key isn't
* found.
*/
int scoutfs_btree_delete(struct super_block *sb, struct scoutfs_key *key)
int scoutfs_btree_delete(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_btree_root *root;
struct scoutfs_btree_block *bt;
struct buffer_head *bh;
int pos;
int cmp;
int ret;
bh = btree_walk(sb, key, NULL, 0, 0, WALK_DELETE);
bh = btree_walk(sb, root, key, NULL, 0, 0, WALK_DELETE);
if (IS_ERR(bh)) {
ret = PTR_ERR(bh);
goto out;
@@ -1084,8 +1085,6 @@ int scoutfs_btree_delete(struct super_block *sb, struct scoutfs_key *key)
/* delete the final block in the tree */
if (bt->nr_items == 0) {
root = &sbi->super.btree_root;
root->height = 0;
root->ref.blkno = 0;
root->ref.seq = 0;
@@ -1119,9 +1118,9 @@ out:
*
* Returns > 0 when the cursor has an item, 0 when done, and -errno on error.
*/
static int btree_next(struct super_block *sb, struct scoutfs_key *first,
struct scoutfs_key *last, u64 seq, int op,
struct scoutfs_btree_cursor *curs)
static int btree_next(struct super_block *sb, struct scoutfs_btree_root *root,
struct scoutfs_key *first, struct scoutfs_key *last,
u64 seq, int op, struct scoutfs_btree_cursor *curs)
{
struct scoutfs_btree_block *bt;
struct buffer_head *bh;
@@ -1148,7 +1147,7 @@ static int btree_next(struct super_block *sb, struct scoutfs_key *first,
/* find the leaf that contains the next item after the key */
while (!curs->bh && scoutfs_key_cmp(&key, last) <= 0) {
bh = btree_walk(sb, &key, &next_key, 0, seq, op);
bh = btree_walk(sb, root, &key, &next_key, 0, seq, op);
/* next seq walks can terminate in parents with old seqs */
if (op == WALK_NEXT_SEQ && bh == ERR_PTR(-ENOENT)) {
@@ -1187,18 +1186,19 @@ static int btree_next(struct super_block *sb, struct scoutfs_key *first,
return ret;
}
int scoutfs_btree_next(struct super_block *sb, struct scoutfs_key *first,
struct scoutfs_key *last,
int scoutfs_btree_next(struct super_block *sb, struct scoutfs_btree_root *root,
struct scoutfs_key *first, struct scoutfs_key *last,
struct scoutfs_btree_cursor *curs)
{
return btree_next(sb, first, last, 0, WALK_NEXT, curs);
return btree_next(sb, root, first, last, 0, WALK_NEXT, curs);
}
int scoutfs_btree_since(struct super_block *sb, struct scoutfs_key *first,
struct scoutfs_key *last, u64 seq,
struct scoutfs_btree_cursor *curs)
int scoutfs_btree_since(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *first, struct scoutfs_key *last,
u64 seq, struct scoutfs_btree_cursor *curs)
{
return btree_next(sb, first, last, seq, WALK_NEXT_SEQ, curs);
return btree_next(sb, root, first, last, seq, WALK_NEXT_SEQ, curs);
}
/*
@@ -1208,14 +1208,16 @@ int scoutfs_btree_since(struct super_block *sb, struct scoutfs_key *first,
*
* <0 is returned on error, including -ENOENT if the key isn't present.
*/
int scoutfs_btree_dirty(struct super_block *sb, struct scoutfs_key *key)
int scoutfs_btree_dirty(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key)
{
struct scoutfs_btree_block *bt;
struct buffer_head *bh;
int cmp;
int ret;
bh = btree_walk(sb, key, NULL, 0, 0, WALK_DIRTY);
bh = btree_walk(sb, root, key, NULL, 0, 0, WALK_DIRTY);
if (IS_ERR(bh))
return PTR_ERR(bh);
bt = bh_data(bh);
@@ -1237,7 +1239,9 @@ int scoutfs_btree_dirty(struct super_block *sb, struct scoutfs_key *key)
* This is guaranteed not to fail if the caller has already dirtied the
* block that contains the item in the current transaction.
*/
int scoutfs_btree_update(struct super_block *sb, struct scoutfs_key *key,
int scoutfs_btree_update(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key,
struct scoutfs_btree_cursor *curs)
{
struct scoutfs_btree_item *item;
@@ -1249,7 +1253,7 @@ int scoutfs_btree_update(struct super_block *sb, struct scoutfs_key *key,
BUG_ON(curs->bh);
bh = btree_walk(sb, key, NULL, 0, 0, WALK_DIRTY);
bh = btree_walk(sb, root, key, NULL, 0, 0, WALK_DIRTY);
if (IS_ERR(bh))
return PTR_ERR(bh);
bt = bh_data(bh);
@@ -1286,14 +1290,15 @@ void scoutfs_btree_release(struct scoutfs_btree_cursor *curs)
* 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,
int scoutfs_btree_hole(struct super_block *sb, struct scoutfs_btree_root *root,
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) {
while ((ret = scoutfs_btree_next(sb, root, first, last, &curs)) > 0) {
/* return our expected hole if we skipped it */
if (scoutfs_key_cmp(hole, curs.key) < 0)
break;
+24 -13
View File
@@ -17,23 +17,34 @@ struct scoutfs_btree_cursor {
#define DECLARE_SCOUTFS_BTREE_CURSOR(name) \
struct scoutfs_btree_cursor name = {NULL,}
int scoutfs_btree_lookup(struct super_block *sb, struct scoutfs_key *key,
int scoutfs_btree_lookup(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key,
struct scoutfs_btree_cursor *curs);
int scoutfs_btree_insert(struct super_block *sb, struct scoutfs_key *key,
unsigned int val_len,
int scoutfs_btree_insert(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key, unsigned int val_len,
struct scoutfs_btree_cursor *curs);
int scoutfs_btree_delete(struct super_block *sb, struct scoutfs_key *key);
int scoutfs_btree_next(struct super_block *sb, struct scoutfs_key *first,
struct scoutfs_key *last,
int scoutfs_btree_delete(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key);
int scoutfs_btree_next(struct super_block *sb, struct scoutfs_btree_root *root,
struct scoutfs_key *first, struct scoutfs_key *last,
struct scoutfs_btree_cursor *curs);
int scoutfs_btree_dirty(struct super_block *sb, struct scoutfs_key *key);
int 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,
int scoutfs_btree_dirty(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key);
int scoutfs_btree_update(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *key,
struct scoutfs_btree_cursor *curs);
int scoutfs_btree_hole(struct super_block *sb, struct scoutfs_btree_root *root,
struct scoutfs_key *first,
struct scoutfs_key *last, struct scoutfs_key *hole);
int scoutfs_btree_since(struct super_block *sb, struct scoutfs_key *first,
struct scoutfs_key *last, u64 seq,
struct scoutfs_btree_cursor *curs);
int scoutfs_btree_since(struct super_block *sb,
struct scoutfs_btree_root *root,
struct scoutfs_key *first, struct scoutfs_key *last,
u64 seq, struct scoutfs_btree_cursor *curs);
void scoutfs_btree_release(struct scoutfs_btree_cursor *curs);
+26 -17
View File
@@ -192,6 +192,7 @@ static struct dentry *scoutfs_lookup(struct inode *dir, struct dentry *dentry,
struct scoutfs_inode_info *si = SCOUTFS_I(dir);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct super_block *sb = dir->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_dirent *dent;
struct dentry_info *di;
struct scoutfs_key first;
@@ -219,7 +220,7 @@ static struct dentry *scoutfs_lookup(struct inode *dir, struct dentry *dentry,
scoutfs_set_key(&last, scoutfs_ino(dir), SCOUTFS_DIRENT_KEY,
last_dirent_key_offset(h));
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
/* XXX verify */
@@ -279,6 +280,7 @@ static int scoutfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
struct inode *inode = file_inode(file);
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_dirent *dent;
struct scoutfs_key first;
@@ -295,7 +297,7 @@ static int scoutfs_readdir(struct file *file, void *dirent, filldir_t filldir)
scoutfs_set_key(&last, scoutfs_ino(inode), SCOUTFS_DIRENT_KEY,
SCOUTFS_DIRENT_LAST_POS);
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
dent = curs.val;
name_len = item_name_len(&curs);
pos = scoutfs_key_offset(curs.key);
@@ -322,14 +324,15 @@ static void set_lref_key(struct scoutfs_key *key, u64 ino, u64 ctr)
static int update_lref_item(struct super_block *sb, struct scoutfs_key *key,
u64 dir_ino, u64 dir_off, bool update)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_link_backref *lref;
int ret;
if (update)
ret = scoutfs_btree_update(sb, key, &curs);
ret = scoutfs_btree_update(sb, meta, key, &curs);
else
ret = scoutfs_btree_insert(sb, key, sizeof(*lref), &curs);
ret = scoutfs_btree_insert(sb, meta, key, sizeof(*lref), &curs);
/* XXX verify size */
if (ret == 0) {
@@ -347,6 +350,7 @@ static int add_entry_items(struct inode *dir, struct dentry *dentry,
{
struct dentry_info *di = dentry->d_fsdata;
struct super_block *sb = dir->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_inode_info *si = SCOUTFS_I(dir);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_dirent *dent;
@@ -375,7 +379,7 @@ static int add_entry_items(struct inode *dir, struct dentry *dentry,
scoutfs_set_key(&last, scoutfs_ino(dir), SCOUTFS_DIRENT_KEY,
last_dirent_key_offset(h));
ret = scoutfs_btree_hole(sb, &first, &last, &key);
ret = scoutfs_btree_hole(sb, meta, &first, &last, &key);
if (ret)
goto out;
@@ -386,9 +390,9 @@ static int add_entry_items(struct inode *dir, struct dentry *dentry,
if (ret)
goto out;
ret = scoutfs_btree_insert(sb, &key, bytes, &curs);
ret = scoutfs_btree_insert(sb, meta, &key, bytes, &curs);
if (ret) {
scoutfs_btree_delete(sb, &lref_key);
scoutfs_btree_delete(sb, meta, &lref_key);
goto out;
}
@@ -509,6 +513,7 @@ out:
static int scoutfs_unlink(struct inode *dir, struct dentry *dentry)
{
struct super_block *sb = dir->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct inode *inode = dentry->d_inode;
struct timespec ts = current_kernel_time();
struct dentry_info *di;
@@ -531,17 +536,17 @@ static int scoutfs_unlink(struct inode *dir, struct dentry *dentry)
ret = scoutfs_dirty_inode_item(dir) ?:
scoutfs_dirty_inode_item(inode) ?:
scoutfs_btree_dirty(sb, &lref_key);
scoutfs_btree_dirty(sb, meta, &lref_key);
if (ret)
goto out;
scoutfs_set_key(&key, scoutfs_ino(dir), SCOUTFS_DIRENT_KEY, di->hash);
ret = scoutfs_btree_delete(sb, &key);
ret = scoutfs_btree_delete(sb, meta, &key);
if (ret)
goto out;
scoutfs_btree_delete(sb, &lref_key);
scoutfs_btree_delete(sb, meta, &lref_key);
dir->i_ctime = ts;
dir->i_mtime = ts;
@@ -573,6 +578,7 @@ static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
loff_t size = i_size_read(inode);
struct scoutfs_key first;
@@ -599,7 +605,7 @@ static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd)
off = 0;
k = 0;
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
if (scoutfs_key_offset(curs.key) != k ||
off + curs.val_len > size) {
/* XXX corruption */
@@ -654,6 +660,7 @@ static int scoutfs_symlink(struct inode *dir, struct dentry *dentry,
const char *symname)
{
struct super_block *sb = dir->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct inode *inode = NULL;
struct scoutfs_key key;
@@ -687,7 +694,7 @@ static int scoutfs_symlink(struct inode *dir, struct dentry *dentry,
k);
bytes = min(name_len, SCOUTFS_MAX_ITEM_LEN);
ret = scoutfs_btree_insert(sb, &key, bytes, &curs);
ret = scoutfs_btree_insert(sb, meta, &key, bytes, &curs);
if (ret)
goto out;
@@ -719,7 +726,7 @@ out:
while (k--) {
scoutfs_set_key(&key, scoutfs_ino(inode),
SCOUTFS_SYMLINK_KEY, k);
scoutfs_btree_delete(sb, &key);
scoutfs_btree_delete(sb, meta, &key);
}
}
@@ -733,6 +740,7 @@ out:
*/
int scoutfs_symlink_drop(struct super_block *sb, u64 ino)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_key first;
struct scoutfs_key last;
@@ -742,13 +750,13 @@ int scoutfs_symlink_drop(struct super_block *sb, u64 ino)
scoutfs_set_key(&first, ino, SCOUTFS_SYMLINK_KEY, 0);
scoutfs_set_key(&last, ino, SCOUTFS_SYMLINK_KEY, ~0ULL);
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
key = *curs.key;
first = *curs.key;
scoutfs_inc_key(&first);
scoutfs_btree_release(&curs);
ret = scoutfs_btree_delete(sb, &key);
ret = scoutfs_btree_delete(sb, meta, &key);
if (ret)
break;
}
@@ -777,6 +785,7 @@ int scoutfs_symlink_drop(struct super_block *sb, u64 ino)
static int add_linkref_name(struct super_block *sb, u64 *dir_ino, u64 ino,
u64 *ctr, struct list_head *list)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_path_component *comp;
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_link_backref *lref;
@@ -798,7 +807,7 @@ retry:
scoutfs_set_key(&first, ino, SCOUTFS_LINK_BACKREF_KEY, *ctr);
scoutfs_set_key(&last, ino, SCOUTFS_LINK_BACKREF_KEY, ~0ULL);
ret = scoutfs_btree_next(sb, &first, &last, &curs);
ret = scoutfs_btree_next(sb, meta, &first, &last, &curs);
if (ret <= 0)
goto out;
@@ -844,7 +853,7 @@ retry:
scoutfs_set_key(&key, *dir_ino, SCOUTFS_DIRENT_KEY, off);
ret = scoutfs_btree_lookup(sb, &key, &curs);
ret = scoutfs_btree_lookup(sb, meta, &key, &curs);
if (ret < 0) {
/* XXX corruption, should always have dirent for backref */
if (ret == -ENOENT)
+11 -7
View File
@@ -202,6 +202,7 @@ static bool bmap_has_blocks(struct scoutfs_block_map *bmap)
*/
int scoutfs_truncate_block_items(struct super_block *sb, u64 ino, u64 size)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_block_map *bmap;
struct scoutfs_key first;
@@ -222,13 +223,13 @@ int scoutfs_truncate_block_items(struct super_block *sb, u64 ino, u64 size)
trace_printk("iblock %llu i %d\n", iblock, i);
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
key = *curs.key;
first = *curs.key;
scoutfs_inc_key(&first);
scoutfs_btree_release(&curs);
ret = scoutfs_btree_update(sb, &key, &curs);
ret = scoutfs_btree_update(sb, meta, &key, &curs);
if (ret)
break;
@@ -255,7 +256,7 @@ int scoutfs_truncate_block_items(struct super_block *sb, u64 ino, u64 size)
i = 0;
if (delete) {
ret = scoutfs_btree_delete(sb, &key);
ret = scoutfs_btree_delete(sb, meta, &key);
if (ret)
break;
}
@@ -301,6 +302,7 @@ static void set_bmap_key(struct scoutfs_key *key, struct inode *inode,
static int contig_mapped_blocks(struct inode *inode, u64 iblock, u64 *blkno)
{
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_block_map *bmap;
struct scoutfs_key key;
@@ -310,7 +312,7 @@ static int contig_mapped_blocks(struct inode *inode, u64 iblock, u64 *blkno)
*blkno = 0;
set_bmap_key(&key, inode, iblock);
ret = scoutfs_btree_lookup(sb, &key, &curs);
ret = scoutfs_btree_lookup(sb, meta, &key, &curs);
if (!ret) {
bmap = curs.val;
@@ -347,6 +349,7 @@ static int contig_mapped_blocks(struct inode *inode, u64 iblock, u64 *blkno)
static int map_writable_block(struct inode *inode, u64 iblock, u64 *blkno_ret)
{
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_block_map *bmap;
struct scoutfs_key key;
@@ -360,13 +363,14 @@ static int map_writable_block(struct inode *inode, u64 iblock, u64 *blkno_ret)
set_bmap_key(&key, inode, iblock);
/* we always need a writable block map item */
ret = scoutfs_btree_update(sb, &key, &curs);
ret = scoutfs_btree_update(sb, meta, &key, &curs);
if (ret < 0 && ret != -ENOENT)
goto out;
/* might need to create a new item and delete it after errors */
if (ret == -ENOENT) {
ret = scoutfs_btree_insert(sb, &key, sizeof(*bmap), &curs);
ret = scoutfs_btree_insert(sb, meta, &key, sizeof(*bmap),
&curs);
if (ret < 0)
goto out;
memset(curs.val, 0, sizeof(*bmap));
@@ -412,7 +416,7 @@ out:
if (new_blkno)
return_file_block(sb, new_blkno);
if (inserted) {
err = scoutfs_btree_delete(sb, &key);
err = scoutfs_btree_delete(sb, meta, &key);
BUG_ON(err); /* always succeeds */
}
}
+11 -6
View File
@@ -127,12 +127,13 @@ static int scoutfs_read_locked_inode(struct inode *inode)
{
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_key key;
int ret;
scoutfs_set_key(&key, scoutfs_ino(inode), SCOUTFS_INODE_KEY, 0);
ret = scoutfs_btree_lookup(sb, &key, &curs);
ret = scoutfs_btree_lookup(sb, meta, &key, &curs);
if (!ret) {
load_inode(inode, curs.val);
scoutfs_btree_release(&curs);
@@ -228,12 +229,13 @@ static void store_inode(struct scoutfs_inode *cinode, struct inode *inode)
int scoutfs_dirty_inode_item(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_key key;
int ret;
scoutfs_set_key(&key, scoutfs_ino(inode), SCOUTFS_INODE_KEY, 0);
ret = scoutfs_btree_dirty(sb, &key);
ret = scoutfs_btree_dirty(sb, meta, &key);
if (!ret)
trace_scoutfs_dirty_inode(inode);
return ret;
@@ -252,12 +254,13 @@ void scoutfs_update_inode_item(struct inode *inode)
{
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_key key;
int err;
scoutfs_set_key(&key, scoutfs_ino(inode), SCOUTFS_INODE_KEY, 0);
err = scoutfs_btree_update(sb, &key, &curs);
err = scoutfs_btree_update(sb, meta, &key, &curs);
BUG_ON(err);
store_inode(curs.val, inode);
@@ -309,6 +312,7 @@ static int alloc_ino(struct super_block *sb, u64 *ino)
struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
umode_t mode, dev_t rdev)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_inode_info *ci;
struct scoutfs_key key;
@@ -338,7 +342,7 @@ struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
scoutfs_set_key(&key, scoutfs_ino(inode), SCOUTFS_INODE_KEY, 0);
ret = scoutfs_btree_insert(inode->i_sb, &key,
ret = scoutfs_btree_insert(inode->i_sb, meta, &key,
sizeof(struct scoutfs_inode), &curs);
if (ret) {
iput(inode);
@@ -354,6 +358,7 @@ struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
*/
static void drop_inode_items(struct super_block *sb, u64 ino)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_inode *sinode;
struct scoutfs_key key;
@@ -363,7 +368,7 @@ static void drop_inode_items(struct super_block *sb, u64 ino)
/* sample the inode mode */
scoutfs_set_key(&key, ino, SCOUTFS_INODE_KEY, 0);
ret = scoutfs_btree_lookup(sb, &key, &curs);
ret = scoutfs_btree_lookup(sb, meta, &key, &curs);
if (ret)
goto out;
@@ -387,7 +392,7 @@ static void drop_inode_items(struct super_block *sb, u64 ino)
if (ret)
goto out;
ret = scoutfs_btree_delete(sb, &key);
ret = scoutfs_btree_delete(sb, meta, &key);
out:
if (ret)
trace_printk("drop items failed ret %d ino %llu\n", ret, ino);
+5 -2
View File
@@ -23,6 +23,7 @@
#include "dir.h"
#include "name.h"
#include "ioctl.h"
#include "super.h"
/*
* Find all the inodes in the given inode range that have changed since
@@ -33,6 +34,7 @@
static long scoutfs_ioc_inodes_since(struct file *file, unsigned long arg)
{
struct super_block *sb = file_inode(file)->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_ioctl_inodes_since __user *uargs = (void __user *)arg;
struct scoutfs_ioctl_inodes_since args;
struct scoutfs_ioctl_ino_seq __user *uiseq;
@@ -54,7 +56,7 @@ static long scoutfs_ioc_inodes_since(struct file *file, unsigned long arg)
scoutfs_set_key(&last, args.last_ino, SCOUTFS_INODE_KEY, 0);
bytes = 0;
while ((ret = scoutfs_btree_since(sb, &first, &last,
while ((ret = scoutfs_btree_since(sb, meta, &first, &last,
args.seq, &curs)) > 0) {
iseq.ino = scoutfs_key_inode(curs.key);
@@ -215,6 +217,7 @@ static long scoutfs_ioc_find_xattr(struct file *file, unsigned long arg,
bool find_name)
{
struct super_block *sb = file_inode(file)->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_ioctl_find_xattr args;
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_key first;
@@ -264,7 +267,7 @@ static long scoutfs_ioc_find_xattr(struct file *file, unsigned long arg,
while (copied < args.ino_count) {
while ((ret = scoutfs_btree_next(sb, &first, &last,
while ((ret = scoutfs_btree_next(sb, meta, &first, &last,
&curs)) > 0) {
inos[nr_inos++] = scoutfs_key_offset(curs.key);
+6
View File
@@ -56,6 +56,12 @@ static inline struct scoutfs_sb_info *SCOUTFS_SB(struct super_block *sb)
return sb->s_fs_info;
}
/* The root of the metadata btree */
static inline struct scoutfs_btree_root *SCOUTFS_META(struct super_block *sb)
{
return &SCOUTFS_SB(sb)->super.btree_root;
}
void scoutfs_advance_dirty_super(struct super_block *sb);
int scoutfs_write_dirty_super(struct super_block *sb);
+27 -20
View File
@@ -114,6 +114,7 @@ static int search_xattr_items(struct inode *inode, const char *name,
struct xattr_search_results *res)
{
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_key first;
struct scoutfs_key last;
@@ -127,7 +128,7 @@ static int search_xattr_items(struct inode *inode, const char *name,
res->found_hole = false;
res->hole_key = first;
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
xat = curs.val;
/* found a hole when we skip past next expected key */
@@ -176,6 +177,7 @@ static int insert_xattr(struct inode *inode, const char *name,
u64 val_hash)
{
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
bool inserted_name_hash_item = false;
__le64 * __packed refcount;
@@ -186,7 +188,8 @@ static int insert_xattr(struct inode *inode, const char *name,
set_name_val_keys(&name_key, &val_key, key, val_hash);
ret = scoutfs_btree_insert(sb, key, xat_bytes(name_len, size), &curs);
ret = scoutfs_btree_insert(sb, meta, key,
xat_bytes(name_len, size), &curs);
if (ret)
return ret;
@@ -200,7 +203,7 @@ static int insert_xattr(struct inode *inode, const char *name,
/* insert the name hash item for find_xattr if we're first */
if (!other_coll) {
ret = scoutfs_btree_insert(sb, &name_key, 0, &curs);
ret = scoutfs_btree_insert(sb, meta, &name_key, 0, &curs);
/* XXX eexist would be corruption */
if (ret)
goto out;
@@ -209,10 +212,10 @@ static int insert_xattr(struct inode *inode, const char *name,
}
/* increment the val hash item for find_xattr, inserting if first */
ret = scoutfs_btree_update(sb, &val_key, &curs);
ret = scoutfs_btree_update(sb, meta, &val_key, &curs);
if (ret == -ENOENT) {
ret = scoutfs_btree_insert(sb, &val_key, sizeof(*refcount),
&curs);
ret = scoutfs_btree_insert(sb, meta, &val_key,
sizeof(*refcount), &curs);
if (ret == 0) {
/* XXX test sane item size */
refcount = curs.val;
@@ -227,9 +230,9 @@ static int insert_xattr(struct inode *inode, const char *name,
out:
if (ret) {
scoutfs_btree_delete(sb, key);
scoutfs_btree_delete(sb, meta, key);
if (inserted_name_hash_item)
scoutfs_btree_delete(sb, &name_key);
scoutfs_btree_delete(sb, meta, &name_key);
}
return ret;
}
@@ -243,6 +246,7 @@ out:
static int delete_xattr(struct super_block *sb, struct scoutfs_key *key,
bool other_coll, u64 val_hash)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_key name_key;
struct scoutfs_key val_key;
@@ -253,22 +257,22 @@ static int delete_xattr(struct super_block *sb, struct scoutfs_key *key,
set_name_val_keys(&name_key, &val_key, key, val_hash);
if (!other_coll) {
ret = scoutfs_btree_dirty(sb, &name_key);
ret = scoutfs_btree_dirty(sb, meta, &name_key);
if (ret)
goto out;
}
ret = scoutfs_btree_dirty(sb, &val_key);
ret = scoutfs_btree_dirty(sb, meta, &val_key);
if (ret)
goto out;
ret = scoutfs_btree_delete(sb, key);
ret = scoutfs_btree_delete(sb, meta, key);
if (ret)
goto out;
if (!other_coll)
scoutfs_btree_delete(sb, &name_key);
scoutfs_btree_delete(sb, meta, &name_key);
scoutfs_btree_update(sb, &val_key, &curs);
scoutfs_btree_update(sb, meta, &val_key, &curs);
refcount = curs.val;
le64_add_cpu(refcount, -1ULL);
if (*refcount == 0)
@@ -276,7 +280,7 @@ static int delete_xattr(struct super_block *sb, struct scoutfs_key *key,
scoutfs_btree_release(&curs);
if (del_val)
scoutfs_btree_delete(sb, &val_key);
scoutfs_btree_delete(sb, meta, &val_key);
ret = 0;
out:
return ret;
@@ -296,6 +300,7 @@ ssize_t scoutfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
{
struct inode *inode = dentry->d_inode;
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
size_t name_len = strlen(name);
@@ -312,7 +317,7 @@ ssize_t scoutfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
down_read(&si->xattr_rwsem);
ret = -ENODATA;
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
xat = curs.val;
if (!scoutfs_names_equal(name, name_len, xat->name,
@@ -452,6 +457,7 @@ ssize_t scoutfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct inode *inode = dentry->d_inode;
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
struct super_block *sb = inode->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_xattr *xat;
struct scoutfs_key first;
@@ -465,7 +471,7 @@ ssize_t scoutfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
down_read(&si->xattr_rwsem);
total = 0;
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
xat = curs.val;
total += xat->name_len + 1;
@@ -504,6 +510,7 @@ ssize_t scoutfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
*/
int scoutfs_xattr_drop(struct super_block *sb, u64 ino)
{
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct scoutfs_xattr *xat;
struct scoutfs_key first;
@@ -521,7 +528,7 @@ int scoutfs_xattr_drop(struct super_block *sb, u64 ino)
scoutfs_set_key(&last, ino, SCOUTFS_XATTR_KEY, ~0ULL);
have_last = false;
while ((ret = scoutfs_btree_next(sb, &first, &last, &curs)) > 0) {
while ((ret = scoutfs_btree_next(sb, meta, &first, &last, &curs)) > 0) {
xat = curs.val;
key = *curs.key;
val_hash = scoutfs_name_hash(xat_value(xat), xat->value_len);
@@ -532,14 +539,14 @@ int scoutfs_xattr_drop(struct super_block *sb, u64 ino)
scoutfs_btree_release(&curs);
if (!have_last || last_name != name_key.inode) {
ret = scoutfs_btree_delete(sb, &name_key);
ret = scoutfs_btree_delete(sb, meta, &name_key);
if (ret && ret != -ENOENT)
break;
last_name = name_key.inode;
}
if (!have_last || last_val != val_key.inode) {
ret = scoutfs_btree_delete(sb, &val_key);
ret = scoutfs_btree_delete(sb, meta, &val_key);
if (ret && ret != -ENOENT)
break;
last_val = val_key.inode;
@@ -547,7 +554,7 @@ int scoutfs_xattr_drop(struct super_block *sb, u64 ino)
have_last = true;
ret = scoutfs_btree_delete(sb, &key);
ret = scoutfs_btree_delete(sb, meta, &key);
if (ret && ret != -ENOENT)
break;
}