]> git.ipfire.org Git - people/ms/linux.git/blobdiff - fs/btrfs/backref.c
Merge branch 'for-6.0/dax' into libnvdimm-fixes
[people/ms/linux.git] / fs / btrfs / backref.c
index ebc392ea1d74c9d2a8b59ff1c15c400f7a969c63..d385357e19b6136772117b5a987f55fe89e71eb3 100644 (file)
@@ -2028,10 +2028,29 @@ out:
        return ret;
 }
 
+static int build_ino_list(u64 inum, u64 offset, u64 root, void *ctx)
+{
+       struct btrfs_data_container *inodes = ctx;
+       const size_t c = 3 * sizeof(u64);
+
+       if (inodes->bytes_left >= c) {
+               inodes->bytes_left -= c;
+               inodes->val[inodes->elem_cnt] = inum;
+               inodes->val[inodes->elem_cnt + 1] = offset;
+               inodes->val[inodes->elem_cnt + 2] = root;
+               inodes->elem_cnt += 3;
+       } else {
+               inodes->bytes_missing += c - inodes->bytes_left;
+               inodes->bytes_left = 0;
+               inodes->elem_missed += 3;
+       }
+
+       return 0;
+}
+
 int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
                                struct btrfs_path *path,
-                               iterate_extent_inodes_t *iterate, void *ctx,
-                               bool ignore_offset)
+                               void *ctx, bool ignore_offset)
 {
        int ret;
        u64 extent_item_pos;
@@ -2049,17 +2068,15 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
        extent_item_pos = logical - found_key.objectid;
        ret = iterate_extent_inodes(fs_info, found_key.objectid,
                                        extent_item_pos, search_commit_root,
-                                       iterate, ctx, ignore_offset);
+                                       build_ino_list, ctx, ignore_offset);
 
        return ret;
 }
 
-typedef int (iterate_irefs_t)(u64 parent, u32 name_len, unsigned long name_off,
-                             struct extent_buffer *eb, void *ctx);
+static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off,
+                        struct extent_buffer *eb, struct inode_fs_paths *ipath);
 
-static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
-                             struct btrfs_path *path,
-                             iterate_irefs_t *iterate, void *ctx)
+static int iterate_inode_refs(u64 inum, struct inode_fs_paths *ipath)
 {
        int ret = 0;
        int slot;
@@ -2068,6 +2085,8 @@ static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
        u32 name_len;
        u64 parent = 0;
        int found = 0;
+       struct btrfs_root *fs_root = ipath->fs_root;
+       struct btrfs_path *path = ipath->btrfs_path;
        struct extent_buffer *eb;
        struct btrfs_inode_ref *iref;
        struct btrfs_key found_key;
@@ -2103,8 +2122,8 @@ static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
                                "following ref at offset %u for inode %llu in tree %llu",
                                cur, found_key.objectid,
                                fs_root->root_key.objectid);
-                       ret = iterate(parent, name_len,
-                                     (unsigned long)(iref + 1), eb, ctx);
+                       ret = inode_to_path(parent, name_len,
+                                     (unsigned long)(iref + 1), eb, ipath);
                        if (ret)
                                break;
                        len = sizeof(*iref) + name_len;
@@ -2118,15 +2137,15 @@ static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
        return ret;
 }
 
-static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
-                                struct btrfs_path *path,
-                                iterate_irefs_t *iterate, void *ctx)
+static int iterate_inode_extrefs(u64 inum, struct inode_fs_paths *ipath)
 {
        int ret;
        int slot;
        u64 offset = 0;
        u64 parent;
        int found = 0;
+       struct btrfs_root *fs_root = ipath->fs_root;
+       struct btrfs_path *path = ipath->btrfs_path;
        struct extent_buffer *eb;
        struct btrfs_inode_extref *extref;
        u32 item_size;
@@ -2162,8 +2181,8 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
                        extref = (struct btrfs_inode_extref *)(ptr + cur_offset);
                        parent = btrfs_inode_extref_parent(eb, extref);
                        name_len = btrfs_inode_extref_name_len(eb, extref);
-                       ret = iterate(parent, name_len,
-                                     (unsigned long)&extref->name, eb, ctx);
+                       ret = inode_to_path(parent, name_len,
+                                     (unsigned long)&extref->name, eb, ipath);
                        if (ret)
                                break;
 
@@ -2180,34 +2199,13 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
        return ret;
 }
 
-static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
-                        struct btrfs_path *path, iterate_irefs_t *iterate,
-                        void *ctx)
-{
-       int ret;
-       int found_refs = 0;
-
-       ret = iterate_inode_refs(inum, fs_root, path, iterate, ctx);
-       if (!ret)
-               ++found_refs;
-       else if (ret != -ENOENT)
-               return ret;
-
-       ret = iterate_inode_extrefs(inum, fs_root, path, iterate, ctx);
-       if (ret == -ENOENT && found_refs)
-               return 0;
-
-       return ret;
-}
-
 /*
  * returns 0 if the path could be dumped (probably truncated)
  * returns <0 in case of an error
  */
 static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off,
-                        struct extent_buffer *eb, void *ctx)
+                        struct extent_buffer *eb, struct inode_fs_paths *ipath)
 {
-       struct inode_fs_paths *ipath = ctx;
        char *fspath;
        char *fspath_min;
        int i = ipath->fspath->elem_cnt;
@@ -2248,8 +2246,20 @@ static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off,
  */
 int paths_from_inode(u64 inum, struct inode_fs_paths *ipath)
 {
-       return iterate_irefs(inum, ipath->fs_root, ipath->btrfs_path,
-                            inode_to_path, ipath);
+       int ret;
+       int found_refs = 0;
+
+       ret = iterate_inode_refs(inum, ipath);
+       if (!ret)
+               ++found_refs;
+       else if (ret != -ENOENT)
+               return ret;
+
+       ret = iterate_inode_extrefs(inum, ipath);
+       if (ret == -ENOENT && found_refs)
+               return 0;
+
+       return ret;
 }
 
 struct btrfs_data_container *init_data_container(u32 total_bytes)