summaryrefslogtreecommitdiff
path: root/fs/bcachefs/dirent.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-03-02 18:35:30 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2021-05-19 15:32:03 -0400
commit437ed5966a16590ba7b5e286709a74250642a9bc (patch)
tree30c07e12c48a845abfcf1665c69d44352ef6193c /fs/bcachefs/dirent.c
parent2f4f33f30ae7f3f40cef9dd6a15825e7b0c60ebd (diff)
bcachefs: Inode backpointers
This patch adds two new inode fields, bi_dir and bi_dir_offset, that point back to the inode's dirent. Since we're only adding fields for a single backpointer, files that have been hardlinked won't necessarily have valid backpointers: we also add a new inode flag, BCH_INODE_BACKPTR_UNTRUSTED, that's set if an inode has ever had multiple links to it. That's ok, because we only really need this functionality for directories, which can never have multiple hardlinks - when we add subvolumes, we'll need a way to enemurate and print subvolumes, and this will let us reconstruct a path to a subvolume root given a subvolume root inode. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/dirent.c')
-rw-r--r--fs/bcachefs/dirent.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c
index 592dd80cf963..cf4ce2e7f29c 100644
--- a/fs/bcachefs/dirent.c
+++ b/fs/bcachefs/dirent.c
@@ -141,7 +141,7 @@ static struct bkey_i_dirent *dirent_create_key(struct btree_trans *trans,
int bch2_dirent_create(struct btree_trans *trans,
u64 dir_inum, const struct bch_hash_info *hash_info,
u8 type, const struct qstr *name, u64 dst_inum,
- int flags)
+ u64 *dir_offset, int flags)
{
struct bkey_i_dirent *dirent;
int ret;
@@ -151,8 +151,11 @@ int bch2_dirent_create(struct btree_trans *trans,
if (ret)
return ret;
- return bch2_hash_set(trans, bch2_dirent_hash_desc, hash_info,
- dir_inum, &dirent->k_i, flags);
+ ret = bch2_hash_set(trans, bch2_dirent_hash_desc, hash_info,
+ dir_inum, &dirent->k_i, flags);
+ *dir_offset = dirent->k.p.offset;
+
+ return ret;
}
static void dirent_copy_target(struct bkey_i_dirent *dst,
@@ -165,8 +168,8 @@ static void dirent_copy_target(struct bkey_i_dirent *dst,
int bch2_dirent_rename(struct btree_trans *trans,
u64 src_dir, struct bch_hash_info *src_hash,
u64 dst_dir, struct bch_hash_info *dst_hash,
- const struct qstr *src_name, u64 *src_inum,
- const struct qstr *dst_name, u64 *dst_inum,
+ const struct qstr *src_name, u64 *src_inum, u64 *src_offset,
+ const struct qstr *dst_name, u64 *dst_inum, u64 *dst_offset,
enum bch_rename_mode mode)
{
struct btree_iter *src_iter = NULL, *dst_iter = NULL;
@@ -255,7 +258,7 @@ int bch2_dirent_rename(struct btree_trans *trans,
new_dst->k.p = src_iter->pos;
bch2_trans_update(trans, src_iter,
&new_dst->k_i, 0);
- goto out;
+ goto out_set_offset;
} else {
/* If we're overwriting, we can't insert new_dst
* at a different slot because it has to
@@ -278,6 +281,9 @@ int bch2_dirent_rename(struct btree_trans *trans,
bch2_trans_update(trans, src_iter, &new_src->k_i, 0);
bch2_trans_update(trans, dst_iter, &new_dst->k_i, 0);
+out_set_offset:
+ *src_offset = new_src->k.p.offset;
+ *dst_offset = new_dst->k.p.offset;
out:
bch2_trans_iter_put(trans, src_iter);
bch2_trans_iter_put(trans, dst_iter);