diff --git a/kmod/src/btree.c b/kmod/src/btree.c index e29070da..90493967 100644 --- a/kmod/src/btree.c +++ b/kmod/src/btree.c @@ -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; diff --git a/kmod/src/btree.h b/kmod/src/btree.h index 60d4a0b5..a7a200fd 100644 --- a/kmod/src/btree.h +++ b/kmod/src/btree.h @@ -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); diff --git a/kmod/src/dir.c b/kmod/src/dir.c index 0e0b1ab4..2b70dbee 100644 --- a/kmod/src/dir.c +++ b/kmod/src/dir.c @@ -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) diff --git a/kmod/src/filerw.c b/kmod/src/filerw.c index e42a485f..75faacc0 100644 --- a/kmod/src/filerw.c +++ b/kmod/src/filerw.c @@ -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 */ } } diff --git a/kmod/src/inode.c b/kmod/src/inode.c index 93d68202..779dee62 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -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); diff --git a/kmod/src/ioctl.c b/kmod/src/ioctl.c index 752c665f..4f5c20e7 100644 --- a/kmod/src/ioctl.c +++ b/kmod/src/ioctl.c @@ -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); diff --git a/kmod/src/super.h b/kmod/src/super.h index 4e7d8723..79c2168f 100644 --- a/kmod/src/super.h +++ b/kmod/src/super.h @@ -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); diff --git a/kmod/src/xattr.c b/kmod/src/xattr.c index 82d92961..97ad19d7 100644 --- a/kmod/src/xattr.c +++ b/kmod/src/xattr.c @@ -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; }