inode-item.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*
  2. * Copyright (C) 2007 Oracle. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License v2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public
  14. * License along with this program; if not, write to the
  15. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. * Boston, MA 021110-1307, USA.
  17. */
  18. #include "ctree.h"
  19. #include "disk-io.h"
  20. #include "hash.h"
  21. #include "transaction.h"
  22. #include "print-tree.h"
  23. int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot,
  24. const char *name,
  25. int name_len, struct btrfs_inode_ref **ref_ret)
  26. {
  27. struct btrfs_inode_ref *ref;
  28. unsigned long ptr;
  29. unsigned long name_ptr;
  30. u32 item_size;
  31. u32 cur_offset = 0;
  32. int len;
  33. item_size = btrfs_item_size_nr(leaf, slot);
  34. ptr = btrfs_item_ptr_offset(leaf, slot);
  35. while (cur_offset < item_size) {
  36. ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
  37. len = btrfs_inode_ref_name_len(leaf, ref);
  38. name_ptr = (unsigned long)(ref + 1);
  39. cur_offset += len + sizeof(*ref);
  40. if (len != name_len)
  41. continue;
  42. if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) {
  43. if (ref_ret)
  44. *ref_ret = ref;
  45. return 1;
  46. }
  47. }
  48. return 0;
  49. }
  50. int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
  51. u64 ref_objectid,
  52. const char *name, int name_len,
  53. struct btrfs_inode_extref **extref_ret)
  54. {
  55. struct btrfs_inode_extref *extref;
  56. unsigned long ptr;
  57. unsigned long name_ptr;
  58. u32 item_size;
  59. u32 cur_offset = 0;
  60. int ref_name_len;
  61. item_size = btrfs_item_size_nr(leaf, slot);
  62. ptr = btrfs_item_ptr_offset(leaf, slot);
  63. /*
  64. * Search all extended backrefs in this item. We're only
  65. * looking through any collisions so most of the time this is
  66. * just going to compare against one buffer. If all is well,
  67. * we'll return success and the inode ref object.
  68. */
  69. while (cur_offset < item_size) {
  70. extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
  71. name_ptr = (unsigned long)(&extref->name);
  72. ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
  73. if (ref_name_len == name_len &&
  74. btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
  75. (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)) {
  76. if (extref_ret)
  77. *extref_ret = extref;
  78. return 1;
  79. }
  80. cur_offset += ref_name_len + sizeof(*extref);
  81. }
  82. return 0;
  83. }
  84. /* Returns NULL if no extref found */
  85. struct btrfs_inode_extref *
  86. btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
  87. struct btrfs_root *root,
  88. struct btrfs_path *path,
  89. const char *name, int name_len,
  90. u64 inode_objectid, u64 ref_objectid, int ins_len,
  91. int cow)
  92. {
  93. int ret;
  94. struct btrfs_key key;
  95. struct btrfs_inode_extref *extref;
  96. key.objectid = inode_objectid;
  97. key.type = BTRFS_INODE_EXTREF_KEY;
  98. key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
  99. ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
  100. if (ret < 0)
  101. return ERR_PTR(ret);
  102. if (ret > 0)
  103. return NULL;
  104. if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
  105. ref_objectid, name, name_len,
  106. &extref))
  107. return NULL;
  108. return extref;
  109. }
  110. static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
  111. struct btrfs_root *root,
  112. const char *name, int name_len,
  113. u64 inode_objectid, u64 ref_objectid,
  114. u64 *index)
  115. {
  116. struct btrfs_path *path;
  117. struct btrfs_key key;
  118. struct btrfs_inode_extref *extref;
  119. struct extent_buffer *leaf;
  120. int ret;
  121. int del_len = name_len + sizeof(*extref);
  122. unsigned long ptr;
  123. unsigned long item_start;
  124. u32 item_size;
  125. key.objectid = inode_objectid;
  126. key.type = BTRFS_INODE_EXTREF_KEY;
  127. key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
  128. path = btrfs_alloc_path();
  129. if (!path)
  130. return -ENOMEM;
  131. path->leave_spinning = 1;
  132. ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
  133. if (ret > 0)
  134. ret = -ENOENT;
  135. if (ret < 0)
  136. goto out;
  137. /*
  138. * Sanity check - did we find the right item for this name?
  139. * This should always succeed so error here will make the FS
  140. * readonly.
  141. */
  142. if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
  143. ref_objectid,
  144. name, name_len, &extref)) {
  145. btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
  146. ret = -EROFS;
  147. goto out;
  148. }
  149. leaf = path->nodes[0];
  150. item_size = btrfs_item_size_nr(leaf, path->slots[0]);
  151. if (index)
  152. *index = btrfs_inode_extref_index(leaf, extref);
  153. if (del_len == item_size) {
  154. /*
  155. * Common case only one ref in the item, remove the
  156. * whole item.
  157. */
  158. ret = btrfs_del_item(trans, root, path);
  159. goto out;
  160. }
  161. ptr = (unsigned long)extref;
  162. item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
  163. memmove_extent_buffer(leaf, ptr, ptr + del_len,
  164. item_size - (ptr + del_len - item_start));
  165. btrfs_truncate_item(root->fs_info, path, item_size - del_len, 1);
  166. out:
  167. btrfs_free_path(path);
  168. return ret;
  169. }
  170. int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
  171. struct btrfs_root *root,
  172. const char *name, int name_len,
  173. u64 inode_objectid, u64 ref_objectid, u64 *index)
  174. {
  175. struct btrfs_path *path;
  176. struct btrfs_key key;
  177. struct btrfs_inode_ref *ref;
  178. struct extent_buffer *leaf;
  179. unsigned long ptr;
  180. unsigned long item_start;
  181. u32 item_size;
  182. u32 sub_item_len;
  183. int ret;
  184. int search_ext_refs = 0;
  185. int del_len = name_len + sizeof(*ref);
  186. key.objectid = inode_objectid;
  187. key.offset = ref_objectid;
  188. key.type = BTRFS_INODE_REF_KEY;
  189. path = btrfs_alloc_path();
  190. if (!path)
  191. return -ENOMEM;
  192. path->leave_spinning = 1;
  193. ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
  194. if (ret > 0) {
  195. ret = -ENOENT;
  196. search_ext_refs = 1;
  197. goto out;
  198. } else if (ret < 0) {
  199. goto out;
  200. }
  201. if (!btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
  202. name, name_len, &ref)) {
  203. ret = -ENOENT;
  204. search_ext_refs = 1;
  205. goto out;
  206. }
  207. leaf = path->nodes[0];
  208. item_size = btrfs_item_size_nr(leaf, path->slots[0]);
  209. if (index)
  210. *index = btrfs_inode_ref_index(leaf, ref);
  211. if (del_len == item_size) {
  212. ret = btrfs_del_item(trans, root, path);
  213. goto out;
  214. }
  215. ptr = (unsigned long)ref;
  216. sub_item_len = name_len + sizeof(*ref);
  217. item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
  218. memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
  219. item_size - (ptr + sub_item_len - item_start));
  220. btrfs_truncate_item(root->fs_info, path, item_size - sub_item_len, 1);
  221. out:
  222. btrfs_free_path(path);
  223. if (search_ext_refs) {
  224. /*
  225. * No refs were found, or we could not find the
  226. * name in our ref array. Find and remove the extended
  227. * inode ref then.
  228. */
  229. return btrfs_del_inode_extref(trans, root, name, name_len,
  230. inode_objectid, ref_objectid, index);
  231. }
  232. return ret;
  233. }
  234. /*
  235. * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
  236. *
  237. * The caller must have checked against BTRFS_LINK_MAX already.
  238. */
  239. static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
  240. struct btrfs_root *root,
  241. const char *name, int name_len,
  242. u64 inode_objectid, u64 ref_objectid, u64 index)
  243. {
  244. struct btrfs_inode_extref *extref;
  245. int ret;
  246. int ins_len = name_len + sizeof(*extref);
  247. unsigned long ptr;
  248. struct btrfs_path *path;
  249. struct btrfs_key key;
  250. struct extent_buffer *leaf;
  251. struct btrfs_item *item;
  252. key.objectid = inode_objectid;
  253. key.type = BTRFS_INODE_EXTREF_KEY;
  254. key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
  255. path = btrfs_alloc_path();
  256. if (!path)
  257. return -ENOMEM;
  258. path->leave_spinning = 1;
  259. ret = btrfs_insert_empty_item(trans, root, path, &key,
  260. ins_len);
  261. if (ret == -EEXIST) {
  262. if (btrfs_find_name_in_ext_backref(path->nodes[0],
  263. path->slots[0],
  264. ref_objectid,
  265. name, name_len, NULL))
  266. goto out;
  267. btrfs_extend_item(root->fs_info, path, ins_len);
  268. ret = 0;
  269. }
  270. if (ret < 0)
  271. goto out;
  272. leaf = path->nodes[0];
  273. item = btrfs_item_nr(path->slots[0]);
  274. ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
  275. ptr += btrfs_item_size(leaf, item) - ins_len;
  276. extref = (struct btrfs_inode_extref *)ptr;
  277. btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len);
  278. btrfs_set_inode_extref_index(path->nodes[0], extref, index);
  279. btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
  280. ptr = (unsigned long)&extref->name;
  281. write_extent_buffer(path->nodes[0], name, ptr, name_len);
  282. btrfs_mark_buffer_dirty(path->nodes[0]);
  283. out:
  284. btrfs_free_path(path);
  285. return ret;
  286. }
  287. /* Will return 0, -ENOMEM, -EMLINK, or -EEXIST or anything from the CoW path */
  288. int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
  289. struct btrfs_root *root,
  290. const char *name, int name_len,
  291. u64 inode_objectid, u64 ref_objectid, u64 index)
  292. {
  293. struct btrfs_fs_info *fs_info = root->fs_info;
  294. struct btrfs_path *path;
  295. struct btrfs_key key;
  296. struct btrfs_inode_ref *ref;
  297. unsigned long ptr;
  298. int ret;
  299. int ins_len = name_len + sizeof(*ref);
  300. key.objectid = inode_objectid;
  301. key.offset = ref_objectid;
  302. key.type = BTRFS_INODE_REF_KEY;
  303. path = btrfs_alloc_path();
  304. if (!path)
  305. return -ENOMEM;
  306. path->leave_spinning = 1;
  307. path->skip_release_on_error = 1;
  308. ret = btrfs_insert_empty_item(trans, root, path, &key,
  309. ins_len);
  310. if (ret == -EEXIST) {
  311. u32 old_size;
  312. if (btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
  313. name, name_len, &ref))
  314. goto out;
  315. old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
  316. btrfs_extend_item(fs_info, path, ins_len);
  317. ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
  318. struct btrfs_inode_ref);
  319. ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
  320. btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
  321. btrfs_set_inode_ref_index(path->nodes[0], ref, index);
  322. ptr = (unsigned long)(ref + 1);
  323. ret = 0;
  324. } else if (ret < 0) {
  325. if (ret == -EOVERFLOW) {
  326. if (btrfs_find_name_in_backref(path->nodes[0],
  327. path->slots[0],
  328. name, name_len, &ref))
  329. ret = -EEXIST;
  330. else
  331. ret = -EMLINK;
  332. }
  333. goto out;
  334. } else {
  335. ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
  336. struct btrfs_inode_ref);
  337. btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
  338. btrfs_set_inode_ref_index(path->nodes[0], ref, index);
  339. ptr = (unsigned long)(ref + 1);
  340. }
  341. write_extent_buffer(path->nodes[0], name, ptr, name_len);
  342. btrfs_mark_buffer_dirty(path->nodes[0]);
  343. out:
  344. btrfs_free_path(path);
  345. if (ret == -EMLINK) {
  346. struct btrfs_super_block *disk_super = fs_info->super_copy;
  347. /* We ran out of space in the ref array. Need to
  348. * add an extended ref. */
  349. if (btrfs_super_incompat_flags(disk_super)
  350. & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
  351. ret = btrfs_insert_inode_extref(trans, root, name,
  352. name_len,
  353. inode_objectid,
  354. ref_objectid, index);
  355. }
  356. return ret;
  357. }
  358. int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
  359. struct btrfs_root *root,
  360. struct btrfs_path *path, u64 objectid)
  361. {
  362. struct btrfs_key key;
  363. int ret;
  364. key.objectid = objectid;
  365. key.type = BTRFS_INODE_ITEM_KEY;
  366. key.offset = 0;
  367. ret = btrfs_insert_empty_item(trans, root, path, &key,
  368. sizeof(struct btrfs_inode_item));
  369. return ret;
  370. }
  371. int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
  372. *root, struct btrfs_path *path,
  373. struct btrfs_key *location, int mod)
  374. {
  375. int ins_len = mod < 0 ? -1 : 0;
  376. int cow = mod != 0;
  377. int ret;
  378. int slot;
  379. struct extent_buffer *leaf;
  380. struct btrfs_key found_key;
  381. ret = btrfs_search_slot(trans, root, location, path, ins_len, cow);
  382. if (ret > 0 && location->type == BTRFS_ROOT_ITEM_KEY &&
  383. location->offset == (u64)-1 && path->slots[0] != 0) {
  384. slot = path->slots[0] - 1;
  385. leaf = path->nodes[0];
  386. btrfs_item_key_to_cpu(leaf, &found_key, slot);
  387. if (found_key.objectid == location->objectid &&
  388. found_key.type == location->type) {
  389. path->slots[0]--;
  390. return 0;
  391. }
  392. }
  393. return ret;
  394. }