Btrfs: drop the inode map tree
[linux-2.6] / fs / btrfs / inode-map.c
1 #include <linux/module.h>
2 #include "ctree.h"
3 #include "disk-io.h"
4 #include "transaction.h"
5
6 int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid)
7 {
8         struct btrfs_path *path;
9         int ret;
10         struct btrfs_leaf *l;
11         struct btrfs_key search_key;
12         int slot;
13
14         path = btrfs_alloc_path();
15         BUG_ON(!path);
16
17         search_key.objectid = (u64)-1;
18         search_key.offset = (u64)-1;
19         ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
20         if (ret < 0)
21                 goto error;
22         BUG_ON(ret == 0);
23         if (path->slots[0] > 0) {
24                 slot = path->slots[0] - 1;
25                 l = btrfs_buffer_leaf(path->nodes[0]);
26                 *objectid = btrfs_disk_key_objectid(&l->items[slot].key);
27         } else {
28                 *objectid = BTRFS_FIRST_FREE_OBJECTID;
29         }
30         ret = 0;
31 error:
32         btrfs_free_path(path);
33         return ret;
34 }
35
36 /*
37  * walks the btree of allocated inodes and find a hole.
38  */
39 int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
40                              struct btrfs_root *root,
41                              u64 dirid, u64 *objectid)
42 {
43         struct btrfs_path *path;
44         struct btrfs_key key;
45         int ret;
46         u64 hole_size = 0;
47         int slot = 0;
48         u64 last_ino = 0;
49         int start_found;
50         struct btrfs_leaf *l;
51         struct btrfs_key search_key;
52         u64 search_start = dirid;
53
54         path = btrfs_alloc_path();
55         BUG_ON(!path);
56         search_key.flags = 0;
57         search_start = root->last_inode_alloc;
58         search_start = max(search_start, BTRFS_FIRST_FREE_OBJECTID);
59         search_key.objectid = search_start;
60         search_key.offset = 0;
61
62         btrfs_init_path(path);
63         start_found = 0;
64         ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0);
65         if (ret < 0)
66                 goto error;
67
68         if (path->slots[0] > 0)
69                 path->slots[0]--;
70
71         while (1) {
72                 l = btrfs_buffer_leaf(path->nodes[0]);
73                 slot = path->slots[0];
74                 if (slot >= btrfs_header_nritems(&l->header)) {
75                         ret = btrfs_next_leaf(root, path);
76                         if (ret == 0)
77                                 continue;
78                         if (ret < 0)
79                                 goto error;
80                         if (!start_found) {
81                                 *objectid = search_start;
82                                 start_found = 1;
83                                 goto found;
84                         }
85                         *objectid = last_ino > search_start ?
86                                 last_ino : search_start;
87                         goto found;
88                 }
89                 btrfs_disk_key_to_cpu(&key, &l->items[slot].key);
90                 if (key.objectid >= search_start) {
91                         if (start_found) {
92                                 if (last_ino < search_start)
93                                         last_ino = search_start;
94                                 hole_size = key.objectid - last_ino;
95                                 if (hole_size > 0) {
96                                         *objectid = last_ino;
97                                         goto found;
98                                 }
99                         }
100                 }
101                 start_found = 1;
102                 last_ino = key.objectid + 1;
103                 path->slots[0]++;
104         }
105         // FIXME -ENOSPC
106 found:
107         root->last_inode_alloc = *objectid;
108         btrfs_release_path(root, path);
109         btrfs_free_path(path);
110         BUG_ON(*objectid < search_start);
111         return 0;
112 error:
113         btrfs_release_path(root, path);
114         btrfs_free_path(path);
115         return ret;
116 }