Btrfs: initial move to kernel module land
[safe/jmp/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 /*
7  * walks the btree of allocated inodes and find a hole.
8  */
9 int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
10                              struct btrfs_root *fs_root,
11                              u64 dirid, u64 *objectid)
12 {
13         struct btrfs_path path;
14         struct btrfs_key key;
15         int ret;
16         u64 hole_size = 0;
17         int slot = 0;
18         u64 last_ino;
19         int start_found;
20         struct btrfs_leaf *l;
21         struct btrfs_root *root = fs_root->fs_info->inode_root;
22         struct btrfs_key search_key;
23         u64 search_start = dirid;
24
25         if (fs_root->fs_info->last_inode_alloc_dirid == dirid)
26                 search_start = fs_root->fs_info->last_inode_alloc;
27
28         search_key.objectid = search_start;
29         search_key.flags = 0;
30         btrfs_set_key_type(&search_key, BTRFS_INODE_MAP_ITEM_KEY);
31         search_key.offset = 0;
32
33         btrfs_init_path(&path);
34         start_found = 0;
35         ret = btrfs_search_slot(trans, root, &search_key, &path, 0, 0);
36         if (ret < 0)
37                 goto error;
38
39         if (path.slots[0] > 0)
40                 path.slots[0]--;
41
42         while (1) {
43                 l = &path.nodes[0]->leaf;
44                 slot = path.slots[0];
45                 if (slot >= btrfs_header_nritems(&l->header)) {
46                         ret = btrfs_next_leaf(root, &path);
47                         if (ret == 0)
48                                 continue;
49                         if (ret < 0)
50                                 goto error;
51                         if (!start_found) {
52                                 *objectid = search_start;
53                                 start_found = 1;
54                                 goto found;
55                         }
56                         *objectid = last_ino > search_start ?
57                                 last_ino : search_start;
58                         goto found;
59                 }
60                 btrfs_disk_key_to_cpu(&key, &l->items[slot].key);
61                 if (key.objectid >= search_start) {
62                         if (start_found) {
63                                 if (last_ino < search_start)
64                                         last_ino = search_start;
65                                 hole_size = key.objectid - last_ino;
66                                 if (hole_size > 0) {
67                                         *objectid = last_ino;
68                                         goto found;
69                                 }
70                         }
71                 }
72                 start_found = 1;
73                 last_ino = key.objectid + 1;
74                 path.slots[0]++;
75         }
76         // FIXME -ENOSPC
77 found:
78         root->fs_info->last_inode_alloc = *objectid;
79         root->fs_info->last_inode_alloc_dirid = dirid;
80         btrfs_release_path(root, &path);
81         BUG_ON(*objectid < search_start);
82         return 0;
83 error:
84         btrfs_release_path(root, &path);
85         return ret;
86 }
87
88 int btrfs_insert_inode_map(struct btrfs_trans_handle *trans,
89                            struct btrfs_root *fs_root,
90                            u64 objectid, struct btrfs_key *location)
91 {
92         int ret = 0;
93         struct btrfs_path path;
94         struct btrfs_inode_map_item *inode_item;
95         struct btrfs_key key;
96         struct btrfs_root *inode_root = fs_root->fs_info->inode_root;
97
98         key.objectid = objectid;
99         key.flags = 0;
100         btrfs_set_key_type(&key, BTRFS_INODE_MAP_ITEM_KEY);
101         key.offset = 0;
102         btrfs_init_path(&path);
103         ret = btrfs_insert_empty_item(trans, inode_root, &path, &key,
104                                       sizeof(struct btrfs_inode_map_item));
105         if (ret)
106                 goto out;
107
108         inode_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
109                                   struct btrfs_inode_map_item);
110         btrfs_cpu_key_to_disk(&inode_item->key, location);
111 out:
112         btrfs_release_path(inode_root, &path);
113         return ret;
114 }
115
116 int btrfs_lookup_inode_map(struct btrfs_trans_handle *trans,
117                            struct btrfs_root *fs_root, struct btrfs_path *path,
118                            u64 objectid, int mod)
119 {
120         int ret;
121         struct btrfs_key key;
122         int ins_len = mod < 0 ? -1 : 0;
123         int cow = mod != 0;
124         struct btrfs_root *inode_root = fs_root->fs_info->inode_root;
125
126         key.objectid = objectid;
127         key.flags = 0;
128         key.offset = 0;
129         btrfs_set_key_type(&key, BTRFS_INODE_MAP_ITEM_KEY);
130         ret = btrfs_search_slot(trans, inode_root, &key, path, ins_len, cow);
131         return ret;
132 }
133