Blame view
fs/btrfs/inode-item.c
6.29 KB
6cbd55707 Btrfs: add GPLv2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* * Copyright (C) 2007 Oracle. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License v2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 021110-1307, USA. */ |
1e1d27017 Btrfs: add inode ... |
18 19 |
#include "ctree.h" #include "disk-io.h" |
e089f05c1 Btrfs: transactio... |
20 |
#include "transaction.h" |
1e1d27017 Btrfs: add inode ... |
21 |
|
b2950863c Btrfs: make thing... |
22 |
static int find_name_in_backref(struct btrfs_path *path, const char *name, |
3954401fa Btrfs: Add back p... |
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
int name_len, struct btrfs_inode_ref **ref_ret) { struct extent_buffer *leaf; struct btrfs_inode_ref *ref; unsigned long ptr; unsigned long name_ptr; u32 item_size; u32 cur_offset = 0; int len; leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, path->slots[0]); ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); while (cur_offset < item_size) { ref = (struct btrfs_inode_ref *)(ptr + cur_offset); len = btrfs_inode_ref_name_len(leaf, ref); name_ptr = (unsigned long)(ref + 1); cur_offset += len + sizeof(*ref); if (len != name_len) continue; if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) { *ref_ret = ref; return 1; } } return 0; } |
a22285a6a Btrfs: Integrate ... |
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
struct btrfs_inode_ref * btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, const char *name, int name_len, u64 inode_objectid, u64 ref_objectid, int mod) { struct btrfs_key key; struct btrfs_inode_ref *ref; int ins_len = mod < 0 ? -1 : 0; int cow = mod != 0; int ret; key.objectid = inode_objectid; key.type = BTRFS_INODE_REF_KEY; key.offset = ref_objectid; ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); if (ret < 0) return ERR_PTR(ret); if (ret > 0) return NULL; if (!find_name_in_backref(path, name, name_len, &ref)) return NULL; return ref; } |
3954401fa Btrfs: Add back p... |
76 77 78 |
int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len, |
aec7477b3 Btrfs: Implement ... |
79 |
u64 inode_objectid, u64 ref_objectid, u64 *index) |
3954401fa Btrfs: Add back p... |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
{ struct btrfs_path *path; struct btrfs_key key; struct btrfs_inode_ref *ref; struct extent_buffer *leaf; unsigned long ptr; unsigned long item_start; u32 item_size; u32 sub_item_len; int ret; int del_len = name_len + sizeof(*ref); key.objectid = inode_objectid; key.offset = ref_objectid; btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY); path = btrfs_alloc_path(); if (!path) return -ENOMEM; |
b9473439d Btrfs: leave btre... |
99 |
path->leave_spinning = 1; |
3954401fa Btrfs: Add back p... |
100 101 102 103 104 105 106 107 108 109 110 111 112 |
ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret > 0) { ret = -ENOENT; goto out; } else if (ret < 0) { goto out; } if (!find_name_in_backref(path, name, name_len, &ref)) { ret = -ENOENT; goto out; } leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
aec7477b3 Btrfs: Implement ... |
113 114 115 |
if (index) *index = btrfs_inode_ref_index(leaf, ref); |
3954401fa Btrfs: Add back p... |
116 117 118 119 120 121 122 123 124 125 126 |
if (del_len == item_size) { ret = btrfs_del_item(trans, root, path); goto out; } ptr = (unsigned long)ref; sub_item_len = name_len + sizeof(*ref); item_start = btrfs_item_ptr_offset(leaf, path->slots[0]); memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, item_size - (ptr + sub_item_len - item_start)); ret = btrfs_truncate_item(trans, root, path, item_size - sub_item_len, 1); |
3954401fa Btrfs: Add back p... |
127 128 129 130 131 132 133 134 |
out: btrfs_free_path(path); return ret; } int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len, |
aec7477b3 Btrfs: Implement ... |
135 |
u64 inode_objectid, u64 ref_objectid, u64 index) |
3954401fa Btrfs: Add back p... |
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
{ struct btrfs_path *path; struct btrfs_key key; struct btrfs_inode_ref *ref; unsigned long ptr; int ret; int ins_len = name_len + sizeof(*ref); key.objectid = inode_objectid; key.offset = ref_objectid; btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY); path = btrfs_alloc_path(); if (!path) return -ENOMEM; |
b9473439d Btrfs: leave btre... |
151 |
path->leave_spinning = 1; |
3954401fa Btrfs: Add back p... |
152 153 154 155 156 157 158 159 160 161 |
ret = btrfs_insert_empty_item(trans, root, path, &key, ins_len); if (ret == -EEXIST) { u32 old_size; if (find_name_in_backref(path, name, name_len, &ref)) goto out; old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); ret = btrfs_extend_item(trans, root, path, ins_len); |
3954401fa Btrfs: Add back p... |
162 163 164 165 |
ref = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_ref); ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size); btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); |
aec7477b3 Btrfs: Implement ... |
166 |
btrfs_set_inode_ref_index(path->nodes[0], ref, index); |
3954401fa Btrfs: Add back p... |
167 168 169 |
ptr = (unsigned long)(ref + 1); ret = 0; } else if (ret < 0) { |
a57195214 Btrfs: check size... |
170 171 |
if (ret == -EOVERFLOW) ret = -EMLINK; |
3954401fa Btrfs: Add back p... |
172 173 174 175 176 |
goto out; } else { ref = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_ref); btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); |
aec7477b3 Btrfs: Implement ... |
177 |
btrfs_set_inode_ref_index(path->nodes[0], ref, index); |
3954401fa Btrfs: Add back p... |
178 179 180 181 182 183 184 185 186 |
ptr = (unsigned long)(ref + 1); } write_extent_buffer(path->nodes[0], name, ptr, name_len); btrfs_mark_buffer_dirty(path->nodes[0]); out: btrfs_free_path(path); return ret; } |
5f39d397d Btrfs: Create ext... |
187 188 189 |
int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 objectid) |
1e1d27017 Btrfs: add inode ... |
190 |
{ |
1e1d27017 Btrfs: add inode ... |
191 192 193 |
struct btrfs_key key; int ret; key.objectid = objectid; |
1e1d27017 Btrfs: add inode ... |
194 195 |
btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); key.offset = 0; |
5f39d397d Btrfs: Create ext... |
196 197 |
ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(struct btrfs_inode_item)); |
1e1d27017 Btrfs: add inode ... |
198 199 |
return ret; } |
e089f05c1 Btrfs: transactio... |
200 |
int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root |
d6e4a428e Btrfs: start of s... |
201 202 |
*root, struct btrfs_path *path, struct btrfs_key *location, int mod) |
1e1d27017 Btrfs: add inode ... |
203 |
{ |
1e1d27017 Btrfs: add inode ... |
204 205 |
int ins_len = mod < 0 ? -1 : 0; int cow = mod != 0; |
d6e4a428e Btrfs: start of s... |
206 207 |
int ret; int slot; |
5f39d397d Btrfs: Create ext... |
208 |
struct extent_buffer *leaf; |
d6e4a428e Btrfs: start of s... |
209 |
struct btrfs_key found_key; |
1e1d27017 Btrfs: add inode ... |
210 |
|
d6e4a428e Btrfs: start of s... |
211 212 213 214 |
ret = btrfs_search_slot(trans, root, location, path, ins_len, cow); if (ret > 0 && btrfs_key_type(location) == BTRFS_ROOT_ITEM_KEY && location->offset == (u64)-1 && path->slots[0] != 0) { slot = path->slots[0] - 1; |
5f39d397d Btrfs: Create ext... |
215 216 |
leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &found_key, slot); |
d6e4a428e Btrfs: start of s... |
217 218 219 220 221 222 223 |
if (found_key.objectid == location->objectid && btrfs_key_type(&found_key) == btrfs_key_type(location)) { path->slots[0]--; return 0; } } return ret; |
1e1d27017 Btrfs: add inode ... |
224 |
} |