mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
bcachefs: bch2_assert_pos_locked()
This adds a new assertion to be used by bch2_inode_update_after_write(), which updates the VFS inode based on the update to the btree inode we just did - we require that the btree inode still be locked when we do that update. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
parent
9a74f63c97
commit
32b26e8c7f
@ -339,7 +339,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
|
||||
if (unlikely(ret))
|
||||
goto err;
|
||||
|
||||
bch2_inode_update_after_write(c, inode, &inode_u,
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u,
|
||||
ATTR_CTIME|ATTR_MODE);
|
||||
|
||||
set_cached_acl(&inode->v, type, acl);
|
||||
|
@ -46,7 +46,7 @@ static inline int __btree_path_cmp(const struct btree_path *l,
|
||||
unsigned r_level)
|
||||
{
|
||||
return cmp_int(l->btree_id, r_btree_id) ?:
|
||||
cmp_int(l->cached, r_cached) ?:
|
||||
cmp_int((int) l->cached, (int) r_cached) ?:
|
||||
bpos_cmp(l->pos, r_pos) ?:
|
||||
-cmp_int(l->level, r_level);
|
||||
}
|
||||
@ -762,6 +762,43 @@ static int bch2_btree_iter_verify_ret(struct btree_iter *iter, struct bkey_s_c k
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bch2_assert_pos_locked(struct btree_trans *trans, enum btree_id id,
|
||||
struct bpos pos, bool key_cache)
|
||||
{
|
||||
struct btree_path *path;
|
||||
unsigned idx;
|
||||
char buf[100];
|
||||
|
||||
trans_for_each_path_inorder(trans, path, idx) {
|
||||
int cmp = cmp_int(path->btree_id, id) ?:
|
||||
cmp_int(path->cached, key_cache);
|
||||
|
||||
if (cmp > 0)
|
||||
break;
|
||||
if (cmp < 0)
|
||||
continue;
|
||||
|
||||
if (!(path->nodes_locked & 1) ||
|
||||
!path->should_be_locked)
|
||||
continue;
|
||||
|
||||
if (!key_cache) {
|
||||
if (bkey_cmp(pos, path->l[0].b->data->min_key) >= 0 &&
|
||||
bkey_cmp(pos, path->l[0].b->key.k.p) <= 0)
|
||||
return;
|
||||
} else {
|
||||
if (!bkey_cmp(pos, path->pos))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bch2_dump_trans_paths_updates(trans);
|
||||
panic("not locked: %s %s%s\n",
|
||||
bch2_btree_ids[id],
|
||||
(bch2_bpos_to_text(&PBUF(buf), pos), buf),
|
||||
key_cache ? " cached" : "");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void bch2_btree_path_verify_level(struct btree_trans *trans,
|
||||
@ -1720,11 +1757,13 @@ void bch2_dump_trans_paths_updates(struct btree_trans *trans)
|
||||
btree_trans_sort_paths(trans);
|
||||
|
||||
trans_for_each_path_inorder(trans, path, idx)
|
||||
printk(KERN_ERR "path: idx %u ref %u:%u%s btree %s pos %s %pS\n",
|
||||
printk(KERN_ERR "path: idx %u ref %u:%u%s%s btree %s pos %s locks %u %pS\n",
|
||||
path->idx, path->ref, path->intent_ref,
|
||||
path->preserve ? " preserve" : "",
|
||||
path->should_be_locked ? " S" : "",
|
||||
path->preserve ? " P" : "",
|
||||
bch2_btree_ids[path->btree_id],
|
||||
(bch2_bpos_to_text(&PBUF(buf1), path->pos), buf1),
|
||||
path->nodes_locked,
|
||||
#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
(void *) path->ip_allocated
|
||||
#else
|
||||
|
@ -166,9 +166,13 @@ inline struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *, struct bke
|
||||
#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
void bch2_trans_verify_paths(struct btree_trans *);
|
||||
void bch2_trans_verify_locks(struct btree_trans *);
|
||||
void bch2_assert_pos_locked(struct btree_trans *, enum btree_id,
|
||||
struct bpos, bool);
|
||||
#else
|
||||
static inline void bch2_trans_verify_paths(struct btree_trans *trans) {}
|
||||
static inline void bch2_trans_verify_locks(struct btree_trans *trans) {}
|
||||
static inline void bch2_assert_pos_locked(struct btree_trans *trans, enum btree_id id,
|
||||
struct bpos pos, bool key_cache) {}
|
||||
#endif
|
||||
|
||||
void bch2_btree_path_fix_key_modified(struct btree_trans *trans,
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
static struct kmem_cache *bch2_inode_cache;
|
||||
|
||||
static void bch2_vfs_inode_init(struct bch_fs *, subvol_inum,
|
||||
static void bch2_vfs_inode_init(struct btree_trans *, subvol_inum,
|
||||
struct bch_inode_info *,
|
||||
struct bch_inode_unpacked *);
|
||||
|
||||
@ -93,11 +93,19 @@ void bch2_pagecache_block_get(struct pagecache_lock *lock)
|
||||
__pagecache_lock_get(lock, -1);
|
||||
}
|
||||
|
||||
void bch2_inode_update_after_write(struct bch_fs *c,
|
||||
void bch2_inode_update_after_write(struct btree_trans *trans,
|
||||
struct bch_inode_info *inode,
|
||||
struct bch_inode_unpacked *bi,
|
||||
unsigned fields)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
|
||||
BUG_ON(bi->bi_inum != inode->v.i_ino);
|
||||
|
||||
bch2_assert_pos_locked(trans, BTREE_ID_inodes,
|
||||
POS(0, bi->bi_inum),
|
||||
0 && c->opts.inodes_use_key_cache);
|
||||
|
||||
set_nlink(&inode->v, bch2_inode_nlink_get(bi));
|
||||
i_uid_write(&inode->v, bi->bi_uid);
|
||||
i_gid_write(&inode->v, bi->bi_gid);
|
||||
@ -126,6 +134,7 @@ int __must_check bch2_write_inode(struct bch_fs *c,
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 512);
|
||||
trans.ip = _RET_IP_;
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
|
||||
@ -140,7 +149,7 @@ int __must_check bch2_write_inode(struct bch_fs *c,
|
||||
* this is important for inode updates via bchfs_write_index_update
|
||||
*/
|
||||
if (!ret)
|
||||
bch2_inode_update_after_write(c, inode, &inode_u, fields);
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u, fields);
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
|
||||
@ -215,6 +224,7 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
|
||||
{
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct bch_inode_info *inode;
|
||||
struct btree_trans trans;
|
||||
int ret;
|
||||
|
||||
inode = to_bch_ei(iget5_locked(c->vfs_sb,
|
||||
@ -227,14 +237,19 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
|
||||
if (!(inode->v.i_state & I_NEW))
|
||||
return &inode->v;
|
||||
|
||||
ret = bch2_inode_find_by_inum(c, inum, &inode_u);
|
||||
bch2_trans_init(&trans, c, 8, 0);
|
||||
ret = lockrestart_do(&trans,
|
||||
bch2_inode_find_by_inum_trans(&trans, inum, &inode_u));
|
||||
|
||||
if (!ret)
|
||||
bch2_vfs_inode_init(&trans, inum, inode, &inode_u);
|
||||
bch2_trans_exit(&trans);
|
||||
|
||||
if (ret) {
|
||||
iget_failed(&inode->v);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
bch2_vfs_inode_init(c, inum, inode, &inode_u);
|
||||
|
||||
unlock_new_inode(&inode->v);
|
||||
|
||||
return &inode->v;
|
||||
@ -306,7 +321,7 @@ __bch2_create(struct mnt_idmap *idmap,
|
||||
}
|
||||
|
||||
if (!(flags & BCH_CREATE_TMPFILE)) {
|
||||
bch2_inode_update_after_write(c, dir, &dir_u,
|
||||
bch2_inode_update_after_write(&trans, dir, &dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
mutex_unlock(&dir->ei_update_lock);
|
||||
}
|
||||
@ -314,7 +329,8 @@ __bch2_create(struct mnt_idmap *idmap,
|
||||
inum.subvol = inode_u.bi_subvol ?: dir->ei_subvol;
|
||||
inum.inum = inode_u.bi_inum;
|
||||
|
||||
bch2_vfs_inode_init(c, inum, inode, &inode_u);
|
||||
bch2_iget5_set(&inode->v, &inum);
|
||||
bch2_vfs_inode_init(&trans, inum, inode, &inode_u);
|
||||
|
||||
set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
|
||||
set_cached_acl(&inode->v, ACL_TYPE_DEFAULT, default_acl);
|
||||
@ -429,11 +445,9 @@ static int __bch2_link(struct bch_fs *c,
|
||||
&dentry->d_name));
|
||||
|
||||
if (likely(!ret)) {
|
||||
BUG_ON(inode_u.bi_inum != inode->v.i_ino);
|
||||
|
||||
bch2_inode_update_after_write(c, dir, &dir_u,
|
||||
bch2_inode_update_after_write(&trans, dir, &dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
bch2_inode_update_after_write(c, inode, &inode_u, ATTR_CTIME);
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u, ATTR_CTIME);
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
@ -481,11 +495,9 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
|
||||
deleting_snapshot));
|
||||
|
||||
if (likely(!ret)) {
|
||||
BUG_ON(inode_u.bi_inum != inode->v.i_ino);
|
||||
|
||||
bch2_inode_update_after_write(c, dir, &dir_u,
|
||||
bch2_inode_update_after_write(&trans, dir, &dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
bch2_inode_update_after_write(c, inode, &inode_u,
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u,
|
||||
ATTR_MTIME);
|
||||
}
|
||||
|
||||
@ -613,18 +625,18 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
BUG_ON(dst_inode &&
|
||||
dst_inode->v.i_ino != dst_inode_u.bi_inum);
|
||||
|
||||
bch2_inode_update_after_write(c, src_dir, &src_dir_u,
|
||||
bch2_inode_update_after_write(&trans, src_dir, &src_dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
|
||||
if (src_dir != dst_dir)
|
||||
bch2_inode_update_after_write(c, dst_dir, &dst_dir_u,
|
||||
bch2_inode_update_after_write(&trans, dst_dir, &dst_dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
|
||||
bch2_inode_update_after_write(c, src_inode, &src_inode_u,
|
||||
bch2_inode_update_after_write(&trans, src_inode, &src_inode_u,
|
||||
ATTR_CTIME);
|
||||
|
||||
if (dst_inode)
|
||||
bch2_inode_update_after_write(c, dst_inode, &dst_inode_u,
|
||||
bch2_inode_update_after_write(&trans, dst_inode, &dst_inode_u,
|
||||
ATTR_CTIME);
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
@ -742,7 +754,7 @@ int bch2_setattr_nonsize(struct mnt_idmap *idmap,
|
||||
if (unlikely(ret))
|
||||
goto err_trans;
|
||||
|
||||
bch2_inode_update_after_write(c, inode, &inode_u, attr->ia_valid);
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u, attr->ia_valid);
|
||||
|
||||
if (acl)
|
||||
set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
|
||||
@ -1154,11 +1166,11 @@ static const struct export_operations bch_export_ops = {
|
||||
//.get_parent = bch2_get_parent,
|
||||
};
|
||||
|
||||
static void bch2_vfs_inode_init(struct bch_fs *c, subvol_inum inum,
|
||||
static void bch2_vfs_inode_init(struct btree_trans *trans, subvol_inum inum,
|
||||
struct bch_inode_info *inode,
|
||||
struct bch_inode_unpacked *bi)
|
||||
{
|
||||
bch2_inode_update_after_write(c, inode, bi, ~0);
|
||||
bch2_inode_update_after_write(trans, inode, bi, ~0);
|
||||
|
||||
inode->v.i_blocks = bi->bi_sectors;
|
||||
inode->v.i_ino = bi->bi_inum;
|
||||
|
@ -172,7 +172,7 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *, subvol_inum);
|
||||
typedef int (*inode_set_fn)(struct bch_inode_info *,
|
||||
struct bch_inode_unpacked *, void *);
|
||||
|
||||
void bch2_inode_update_after_write(struct bch_fs *,
|
||||
void bch2_inode_update_after_write(struct btree_trans *,
|
||||
struct bch_inode_info *,
|
||||
struct bch_inode_unpacked *,
|
||||
unsigned);
|
||||
|
@ -722,9 +722,9 @@ int bch2_inode_rm(struct bch_fs *c, subvol_inum inum, bool cached)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_inode_find_by_inum_trans(struct btree_trans *trans,
|
||||
subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode)
|
||||
int bch2_inode_find_by_inum_trans(struct btree_trans *trans,
|
||||
subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode)
|
||||
{
|
||||
struct btree_iter iter;
|
||||
int ret;
|
||||
|
@ -89,6 +89,8 @@ int bch2_inode_create(struct btree_trans *, struct btree_iter *,
|
||||
|
||||
int bch2_inode_rm(struct bch_fs *, subvol_inum, bool);
|
||||
|
||||
int bch2_inode_find_by_inum_trans(struct btree_trans *, subvol_inum,
|
||||
struct bch_inode_unpacked *);
|
||||
int bch2_inode_find_by_inum(struct bch_fs *, subvol_inum,
|
||||
struct bch_inode_unpacked *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user