Btrfs: 64 bit div fixes
[linux-3.10.git] / fs / btrfs / root-tree.c
1 #include <linux/module.h>
2 #include "ctree.h"
3 #include "disk-io.h"
4 #include "print-tree.h"
5
6 int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
7                         struct btrfs_root_item *item, struct btrfs_key *key)
8 {
9         struct btrfs_path *path;
10         struct btrfs_key search_key;
11         struct btrfs_leaf *l;
12         int ret;
13         int slot;
14
15         search_key.objectid = objectid;
16         search_key.flags = (u32)-1;
17         search_key.offset = (u32)-1;
18
19         path = btrfs_alloc_path();
20         BUG_ON(!path);
21         btrfs_init_path(path);
22         ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
23         if (ret < 0)
24                 goto out;
25         BUG_ON(ret == 0);
26         l = btrfs_buffer_leaf(path->nodes[0]);
27         BUG_ON(path->slots[0] == 0);
28         slot = path->slots[0] - 1;
29         if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) {
30                 ret = 1;
31                 goto out;
32         }
33         memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item),
34                 sizeof(*item));
35         btrfs_disk_key_to_cpu(key, &l->items[slot].key);
36         ret = 0;
37 out:
38         btrfs_release_path(root, path);
39         btrfs_free_path(path);
40         return ret;
41 }
42
43 int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
44                       *root, struct btrfs_key *key, struct btrfs_root_item
45                       *item)
46 {
47         struct btrfs_path *path;
48         struct btrfs_leaf *l;
49         int ret;
50         int slot;
51         struct btrfs_root_item *update_item;
52
53         path = btrfs_alloc_path();
54         BUG_ON(!path);
55         btrfs_init_path(path);
56         ret = btrfs_search_slot(trans, root, key, path, 0, 1);
57         if (ret < 0)
58                 goto out;
59         BUG_ON(ret != 0);
60         l = btrfs_buffer_leaf(path->nodes[0]);
61         slot = path->slots[0];
62         update_item = btrfs_item_ptr(l, slot, struct btrfs_root_item);
63         btrfs_memcpy(root, l, update_item, item, sizeof(*item));
64         btrfs_mark_buffer_dirty(path->nodes[0]);
65 out:
66         btrfs_release_path(root, path);
67         btrfs_free_path(path);
68         return ret;
69 }
70
71 int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
72                       *root, struct btrfs_key *key, struct btrfs_root_item
73                       *item)
74 {
75         int ret;
76         ret = btrfs_insert_item(trans, root, key, item, sizeof(*item));
77         BUG_ON(ret);
78         return ret;
79 }
80
81 int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
82                    struct btrfs_key *key)
83 {
84         struct btrfs_path *path;
85         int ret;
86         u32 refs;
87         struct btrfs_root_item *ri;
88
89         path = btrfs_alloc_path();
90         BUG_ON(!path);
91         btrfs_init_path(path);
92         ret = btrfs_search_slot(trans, root, key, path, -1, 1);
93         if (ret < 0)
94                 goto out;
95         BUG_ON(ret != 0);
96         ri = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
97                             path->slots[0], struct btrfs_root_item);
98
99         refs = btrfs_root_refs(ri);
100         BUG_ON(refs == 0);
101         if (refs == 1) {
102                 ret = btrfs_del_item(trans, root, path);
103         } else {
104                 btrfs_set_root_refs(ri, refs - 1);
105 printk("ref now %u root %llu %Lu %u\n", refs -1, key->objectid, key->offset, key->flags);
106                 mark_buffer_dirty(path->nodes[0]);
107         }
108 out:
109         btrfs_release_path(root, path);
110         btrfs_free_path(path);
111         return ret;
112 }