diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-02-18 22:27:10 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:08:35 +0300 |
commit | 8b53852d0a80ec4e438205bf8eb3a5a73ee8238c (patch) | |
tree | 32502129e6ea44593c7efddc801e7080a44a5f05 /fs/bcachefs/fs-common.c | |
parent | fdf224003354fb14e20f638e479273c4728dfc0a (diff) | |
download | linux-8b53852d0a80ec4e438205bf8eb3a5a73ee8238c.tar.xz |
bcachefs: Make sure we're releasing btree iterators
This wasn't originally required, but this is the model we're moving
towards.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fs-common.c')
-rw-r--r-- | fs/bcachefs/fs-common.c | 126 |
1 files changed, 81 insertions, 45 deletions
diff --git a/fs/bcachefs/fs-common.c b/fs/bcachefs/fs-common.c index 96f7bbe0a3ed..878419d40992 100644 --- a/fs/bcachefs/fs-common.c +++ b/fs/bcachefs/fs-common.c @@ -19,14 +19,15 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, struct posix_acl *acl) { struct bch_fs *c = trans->c; - struct btree_iter *dir_iter; + struct btree_iter *dir_iter = NULL; struct bch_hash_info hash = bch2_hash_info_init(c, new_inode); u64 now = bch2_current_time(trans->c); int ret; dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT); - if (IS_ERR(dir_iter)) - return PTR_ERR(dir_iter); + ret = PTR_ERR_OR_ZERO(dir_iter); + if (ret) + goto err; bch2_inode_init_late(new_inode, now, uid, gid, mode, rdev, dir_u); @@ -37,20 +38,20 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, BLOCKDEV_INODE_MAX, 0, &c->unused_inode_hint); if (ret) - return ret; + goto err; if (default_acl) { ret = bch2_set_acl_trans(trans, new_inode, &hash, default_acl, ACL_TYPE_DEFAULT); if (ret) - return ret; + goto err; } if (acl) { ret = bch2_set_acl_trans(trans, new_inode, &hash, acl, ACL_TYPE_ACCESS); if (ret) - return ret; + goto err; } if (name) { @@ -62,48 +63,55 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, ret = bch2_inode_write(trans, dir_iter, dir_u); if (ret) - return ret; + goto err; ret = bch2_dirent_create(trans, dir_inum, &dir_hash, mode_to_type(new_inode->bi_mode), name, new_inode->bi_inum, BCH_HASH_SET_MUST_CREATE); if (ret) - return ret; + goto err; } - - return 0; +err: + bch2_trans_iter_put(trans, dir_iter); + return ret; } int bch2_link_trans(struct btree_trans *trans, u64 dir_inum, u64 inum, struct bch_inode_unpacked *dir_u, struct bch_inode_unpacked *inode_u, const struct qstr *name) { - struct btree_iter *dir_iter, *inode_iter; + struct btree_iter *dir_iter = NULL, *inode_iter = NULL; struct bch_hash_info dir_hash; u64 now = bch2_current_time(trans->c); + int ret; inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT); - if (IS_ERR(inode_iter)) - return PTR_ERR(inode_iter); + ret = PTR_ERR_OR_ZERO(inode_iter); + if (ret) + goto err; inode_u->bi_ctime = now; bch2_inode_nlink_inc(inode_u); dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, 0); - if (IS_ERR(dir_iter)) - return PTR_ERR(dir_iter); + ret = PTR_ERR_OR_ZERO(dir_iter); + if (ret) + goto err; dir_u->bi_mtime = dir_u->bi_ctime = now; dir_hash = bch2_hash_info_init(trans->c, dir_u); - bch2_trans_iter_put(trans, dir_iter); - return bch2_dirent_create(trans, dir_inum, &dir_hash, + ret = bch2_dirent_create(trans, dir_inum, &dir_hash, mode_to_type(inode_u->bi_mode), name, inum, BCH_HASH_SET_MUST_CREATE) ?: bch2_inode_write(trans, dir_iter, dir_u) ?: bch2_inode_write(trans, inode_iter, inode_u); +err: + bch2_trans_iter_put(trans, dir_iter); + bch2_trans_iter_put(trans, inode_iter); + return ret; } int bch2_unlink_trans(struct btree_trans *trans, @@ -111,39 +119,49 @@ int bch2_unlink_trans(struct btree_trans *trans, struct bch_inode_unpacked *inode_u, const struct qstr *name) { - struct btree_iter *dir_iter, *dirent_iter, *inode_iter; + struct btree_iter *dir_iter = NULL, *dirent_iter = NULL, + *inode_iter = NULL; struct bch_hash_info dir_hash; u64 inum, now = bch2_current_time(trans->c); struct bkey_s_c k; + int ret; dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT); - if (IS_ERR(dir_iter)) - return PTR_ERR(dir_iter); + ret = PTR_ERR_OR_ZERO(dir_iter); + if (ret) + goto err; dir_hash = bch2_hash_info_init(trans->c, dir_u); dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, &dir_hash, name, BTREE_ITER_INTENT); - if (IS_ERR(dirent_iter)) - return PTR_ERR(dirent_iter); + ret = PTR_ERR_OR_ZERO(dirent_iter); + if (ret) + goto err; k = bch2_btree_iter_peek_slot(dirent_iter); inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum); inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT); - if (IS_ERR(inode_iter)) - return PTR_ERR(inode_iter); + ret = PTR_ERR_OR_ZERO(inode_iter); + if (ret) + goto err; dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now; dir_u->bi_nlink -= S_ISDIR(inode_u->bi_mode); bch2_inode_nlink_dec(inode_u); - return (S_ISDIR(inode_u->bi_mode) + ret = (S_ISDIR(inode_u->bi_mode) ? bch2_empty_dir_trans(trans, inum) : 0) ?: bch2_dirent_delete_at(trans, &dir_hash, dirent_iter) ?: bch2_inode_write(trans, dir_iter, dir_u) ?: bch2_inode_write(trans, inode_iter, inode_u); +err: + bch2_trans_iter_put(trans, inode_iter); + bch2_trans_iter_put(trans, dirent_iter); + bch2_trans_iter_put(trans, dir_iter); + return ret; } bool bch2_reinherit_attrs(struct bch_inode_unpacked *dst_u, @@ -179,24 +197,26 @@ int bch2_rename_trans(struct btree_trans *trans, const struct qstr *dst_name, enum bch_rename_mode mode) { - struct btree_iter *src_dir_iter, *dst_dir_iter = NULL; - struct btree_iter *src_inode_iter, *dst_inode_iter = NULL; + struct btree_iter *src_dir_iter = NULL, *dst_dir_iter = NULL; + struct btree_iter *src_inode_iter = NULL, *dst_inode_iter = NULL; struct bch_hash_info src_hash, dst_hash; u64 src_inode, dst_inode, now = bch2_current_time(trans->c); int ret; src_dir_iter = bch2_inode_peek(trans, src_dir_u, src_dir, BTREE_ITER_INTENT); - if (IS_ERR(src_dir_iter)) - return PTR_ERR(src_dir_iter); + ret = PTR_ERR_OR_ZERO(src_dir_iter); + if (ret) + goto err; src_hash = bch2_hash_info_init(trans->c, src_dir_u); if (dst_dir != src_dir) { dst_dir_iter = bch2_inode_peek(trans, dst_dir_u, dst_dir, BTREE_ITER_INTENT); - if (IS_ERR(dst_dir_iter)) - return PTR_ERR(dst_dir_iter); + ret = PTR_ERR_OR_ZERO(dst_dir_iter); + if (ret) + goto err; dst_hash = bch2_hash_info_init(trans->c, dst_dir_u); } else { @@ -211,38 +231,48 @@ int bch2_rename_trans(struct btree_trans *trans, dst_name, &dst_inode, mode); if (ret) - return ret; + goto err; src_inode_iter = bch2_inode_peek(trans, src_inode_u, src_inode, BTREE_ITER_INTENT); - if (IS_ERR(src_inode_iter)) - return PTR_ERR(src_inode_iter); + ret = PTR_ERR_OR_ZERO(src_inode_iter); + if (ret) + goto err; if (dst_inode) { dst_inode_iter = bch2_inode_peek(trans, dst_inode_u, dst_inode, BTREE_ITER_INTENT); - if (IS_ERR(dst_inode_iter)) - return PTR_ERR(dst_inode_iter); + ret = PTR_ERR_OR_ZERO(dst_inode_iter); + if (ret) + goto err; } if (mode == BCH_RENAME_OVERWRITE) { if (S_ISDIR(src_inode_u->bi_mode) != - S_ISDIR(dst_inode_u->bi_mode)) - return -ENOTDIR; + S_ISDIR(dst_inode_u->bi_mode)) { + ret = -ENOTDIR; + goto err; + } if (S_ISDIR(dst_inode_u->bi_mode) && - bch2_empty_dir_trans(trans, dst_inode)) - return -ENOTEMPTY; + bch2_empty_dir_trans(trans, dst_inode)) { + ret = -ENOTEMPTY; + goto err; + } } if (bch2_reinherit_attrs(src_inode_u, dst_dir_u) && - S_ISDIR(src_inode_u->bi_mode)) - return -EXDEV; + S_ISDIR(src_inode_u->bi_mode)) { + ret = -EXDEV; + goto err; + } if (mode == BCH_RENAME_EXCHANGE && bch2_reinherit_attrs(dst_inode_u, src_dir_u) && - S_ISDIR(dst_inode_u->bi_mode)) - return -EXDEV; + S_ISDIR(dst_inode_u->bi_mode)) { + ret = -EXDEV; + goto err; + } if (S_ISDIR(src_inode_u->bi_mode)) { src_dir_u->bi_nlink--; @@ -270,7 +300,7 @@ int bch2_rename_trans(struct btree_trans *trans, if (dst_inode) dst_inode_u->bi_ctime = now; - return bch2_inode_write(trans, src_dir_iter, src_dir_u) ?: + ret = bch2_inode_write(trans, src_dir_iter, src_dir_u) ?: (src_dir != dst_dir ? bch2_inode_write(trans, dst_dir_iter, dst_dir_u) : 0 ) ?: @@ -278,4 +308,10 @@ int bch2_rename_trans(struct btree_trans *trans, (dst_inode ? bch2_inode_write(trans, dst_inode_iter, dst_inode_u) : 0 ); +err: + bch2_trans_iter_put(trans, dst_inode_iter); + bch2_trans_iter_put(trans, src_inode_iter); + bch2_trans_iter_put(trans, dst_dir_iter); + bch2_trans_iter_put(trans, src_dir_iter); + return ret; } |