scoutfs: have btree_update return errors

We can certainly have btree update callers that haven't yet dirtied the
blocks but who can deal with errors.  So make it return errors and have
its only current caller freak out if it fails.  This will let the file
data block mapping code attempt to get a dirty item without first
dirtying.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2016-08-09 17:01:00 -07:00
parent 8a6715ff02
commit 198ec2ed5b
3 changed files with 24 additions and 12 deletions

View File

@@ -1114,30 +1114,39 @@ int scoutfs_btree_dirty(struct super_block *sb, struct scoutfs_key *key)
}
/*
* For this to be safe the caller has to have pinned the dirty blocks
* for the item in their transaction.
* This is guaranteed not to fail if the caller has already dirtied the
* block that contains the item in the current transaction.
*/
void scoutfs_btree_update(struct super_block *sb, struct scoutfs_key *key,
struct scoutfs_btree_cursor *curs)
int scoutfs_btree_update(struct super_block *sb, struct scoutfs_key *key,
struct scoutfs_btree_cursor *curs)
{
struct scoutfs_btree_item *item;
struct scoutfs_btree_block *bt;
struct buffer_head *bh;
int pos;
int cmp;
int ret;
BUG_ON(curs->bh);
bh = btree_walk(sb, key, NULL, 0, 0, WALK_DIRTY);
BUG_ON(IS_ERR(bh));
if (IS_ERR(bh))
return PTR_ERR(bh);
bt = bh_data(bh);
pos = find_pos(bt, key, &cmp);
BUG_ON(cmp);
if (cmp == 0) {
item = pos_item(bt, pos);
item->seq = bt->hdr.seq;
set_cursor(curs, bh, pos, true);
ret = 0;
} else {
unlock_block(NULL, bh, true);
scoutfs_block_put(bh);
ret = -ENOENT;
}
item = pos_item(bt, pos);
item->seq = bt->hdr.seq;
set_cursor(curs, bh, pos, true);
return ret;
}
void scoutfs_btree_release(struct scoutfs_btree_cursor *curs)

View File

@@ -27,8 +27,8 @@ int scoutfs_btree_next(struct super_block *sb, 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);
void scoutfs_btree_update(struct super_block *sb, struct scoutfs_key *key,
struct scoutfs_btree_cursor *curs);
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,
struct scoutfs_key *last, struct scoutfs_key *hole);
int scoutfs_btree_since(struct super_block *sb, struct scoutfs_key *first,

View File

@@ -249,10 +249,13 @@ void scoutfs_update_inode_item(struct inode *inode)
DECLARE_SCOUTFS_BTREE_CURSOR(curs);
struct super_block *sb = inode->i_sb;
struct scoutfs_key key;
int err;
scoutfs_set_key(&key, scoutfs_ino(inode), SCOUTFS_INODE_KEY, 0);
scoutfs_btree_update(sb, &key, &curs);
err = scoutfs_btree_update(sb, &key, &curs);
BUG_ON(err);
store_inode(curs.val, inode);
scoutfs_btree_release(&curs);
trace_scoutfs_update_inode(inode);