ordered-data.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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 <linux/gfp.h>
  19. #include <linux/slab.h>
  20. #include <linux/blkdev.h>
  21. #include "ctree.h"
  22. #include "transaction.h"
  23. #include "btrfs_inode.h"
  24. struct tree_entry {
  25. u64 root_objectid;
  26. u64 objectid;
  27. struct inode *inode;
  28. struct rb_node rb_node;
  29. };
  30. /*
  31. * returns > 0 if entry passed (root, objectid) is > entry,
  32. * < 0 if (root, objectid) < entry and zero if they are equal
  33. */
  34. static int comp_entry(struct tree_entry *entry, u64 root_objectid,
  35. u64 objectid)
  36. {
  37. if (root_objectid < entry->root_objectid)
  38. return -1;
  39. if (root_objectid > entry->root_objectid)
  40. return 1;
  41. if (objectid < entry->objectid)
  42. return -1;
  43. if (objectid > entry->objectid)
  44. return 1;
  45. return 0;
  46. }
  47. static struct rb_node *tree_insert(struct rb_root *root, u64 root_objectid,
  48. u64 objectid, struct rb_node *node)
  49. {
  50. struct rb_node ** p = &root->rb_node;
  51. struct rb_node * parent = NULL;
  52. struct tree_entry *entry;
  53. int comp;
  54. while(*p) {
  55. parent = *p;
  56. entry = rb_entry(parent, struct tree_entry, rb_node);
  57. comp = comp_entry(entry, root_objectid, objectid);
  58. if (comp < 0)
  59. p = &(*p)->rb_left;
  60. else if (comp > 0)
  61. p = &(*p)->rb_right;
  62. else
  63. return parent;
  64. }
  65. rb_link_node(node, parent, p);
  66. rb_insert_color(node, root);
  67. return NULL;
  68. }
  69. static struct rb_node *__tree_search(struct rb_root *root, u64 root_objectid,
  70. u64 objectid, struct rb_node **prev_ret)
  71. {
  72. struct rb_node * n = root->rb_node;
  73. struct rb_node *prev = NULL;
  74. struct tree_entry *entry;
  75. struct tree_entry *prev_entry = NULL;
  76. int comp;
  77. while(n) {
  78. entry = rb_entry(n, struct tree_entry, rb_node);
  79. prev = n;
  80. prev_entry = entry;
  81. comp = comp_entry(entry, root_objectid, objectid);
  82. if (comp < 0)
  83. n = n->rb_left;
  84. else if (comp > 0)
  85. n = n->rb_right;
  86. else
  87. return n;
  88. }
  89. if (!prev_ret)
  90. return NULL;
  91. while(prev && comp_entry(prev_entry, root_objectid, objectid) >= 0) {
  92. prev = rb_next(prev);
  93. prev_entry = rb_entry(prev, struct tree_entry, rb_node);
  94. }
  95. *prev_ret = prev;
  96. return NULL;
  97. }
  98. static inline struct rb_node *tree_search(struct rb_root *root,
  99. u64 root_objectid, u64 objectid)
  100. {
  101. struct rb_node *prev;
  102. struct rb_node *ret;
  103. ret = __tree_search(root, root_objectid, objectid, &prev);
  104. if (!ret)
  105. return prev;
  106. return ret;
  107. }
  108. int btrfs_add_ordered_inode(struct inode *inode)
  109. {
  110. struct btrfs_root *root = BTRFS_I(inode)->root;
  111. u64 root_objectid = root->root_key.objectid;
  112. u64 transid = root->fs_info->running_transaction->transid;
  113. struct tree_entry *entry;
  114. struct rb_node *node;
  115. struct btrfs_ordered_inode_tree *tree;
  116. if (transid <= BTRFS_I(inode)->ordered_trans)
  117. return 0;
  118. tree = &root->fs_info->running_transaction->ordered_inode_tree;
  119. read_lock(&tree->lock);
  120. node = __tree_search(&tree->tree, root_objectid, inode->i_ino, NULL);
  121. read_unlock(&tree->lock);
  122. if (node) {
  123. return 0;
  124. }
  125. entry = kmalloc(sizeof(*entry), GFP_NOFS);
  126. if (!entry)
  127. return -ENOMEM;
  128. write_lock(&tree->lock);
  129. entry->objectid = inode->i_ino;
  130. entry->root_objectid = root_objectid;
  131. entry->inode = inode;
  132. node = tree_insert(&tree->tree, root_objectid,
  133. inode->i_ino, &entry->rb_node);
  134. BTRFS_I(inode)->ordered_trans = transid;
  135. write_unlock(&tree->lock);
  136. if (node)
  137. kfree(entry);
  138. else
  139. igrab(inode);
  140. return 0;
  141. }
  142. int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
  143. u64 *root_objectid, u64 *objectid,
  144. struct inode **inode)
  145. {
  146. struct tree_entry *entry;
  147. struct rb_node *node;
  148. write_lock(&tree->lock);
  149. node = tree_search(&tree->tree, *root_objectid, *objectid);
  150. if (!node) {
  151. write_unlock(&tree->lock);
  152. return 0;
  153. }
  154. entry = rb_entry(node, struct tree_entry, rb_node);
  155. while(comp_entry(entry, *root_objectid, *objectid) >= 0) {
  156. node = rb_next(node);
  157. if (!node)
  158. break;
  159. entry = rb_entry(node, struct tree_entry, rb_node);
  160. }
  161. if (!node) {
  162. write_unlock(&tree->lock);
  163. return 0;
  164. }
  165. *root_objectid = entry->root_objectid;
  166. *inode = entry->inode;
  167. atomic_inc(&entry->inode->i_count);
  168. *objectid = entry->objectid;
  169. write_unlock(&tree->lock);
  170. return 1;
  171. }
  172. int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
  173. u64 *root_objectid, u64 *objectid,
  174. struct inode **inode)
  175. {
  176. struct tree_entry *entry;
  177. struct rb_node *node;
  178. write_lock(&tree->lock);
  179. node = tree_search(&tree->tree, *root_objectid, *objectid);
  180. if (!node) {
  181. write_unlock(&tree->lock);
  182. return 0;
  183. }
  184. entry = rb_entry(node, struct tree_entry, rb_node);
  185. while(comp_entry(entry, *root_objectid, *objectid) >= 0) {
  186. node = rb_next(node);
  187. if (!node)
  188. break;
  189. entry = rb_entry(node, struct tree_entry, rb_node);
  190. }
  191. if (!node) {
  192. write_unlock(&tree->lock);
  193. return 0;
  194. }
  195. *root_objectid = entry->root_objectid;
  196. *objectid = entry->objectid;
  197. *inode = entry->inode;
  198. atomic_inc(&entry->inode->i_count);
  199. rb_erase(node, &tree->tree);
  200. write_unlock(&tree->lock);
  201. kfree(entry);
  202. return 1;
  203. }
  204. static void __btrfs_del_ordered_inode(struct btrfs_ordered_inode_tree *tree,
  205. struct inode *inode,
  206. u64 root_objectid, u64 objectid)
  207. {
  208. struct tree_entry *entry;
  209. struct rb_node *node;
  210. struct rb_node *prev;
  211. write_lock(&tree->lock);
  212. node = __tree_search(&tree->tree, root_objectid, objectid, &prev);
  213. if (!node) {
  214. write_unlock(&tree->lock);
  215. return;
  216. }
  217. rb_erase(node, &tree->tree);
  218. BTRFS_I(inode)->ordered_trans = 0;
  219. write_unlock(&tree->lock);
  220. atomic_dec(&inode->i_count);
  221. entry = rb_entry(node, struct tree_entry, rb_node);
  222. kfree(entry);
  223. return;
  224. }
  225. void btrfs_del_ordered_inode(struct inode *inode, int force)
  226. {
  227. struct btrfs_root *root = BTRFS_I(inode)->root;
  228. u64 root_objectid = root->root_key.objectid;
  229. if (!BTRFS_I(inode)->ordered_trans) {
  230. return;
  231. }
  232. if (!force && (mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY) ||
  233. mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK)))
  234. return;
  235. spin_lock(&root->fs_info->new_trans_lock);
  236. if (root->fs_info->running_transaction) {
  237. struct btrfs_ordered_inode_tree *tree;
  238. tree = &root->fs_info->running_transaction->ordered_inode_tree;
  239. __btrfs_del_ordered_inode(tree, inode, root_objectid,
  240. inode->i_ino);
  241. }
  242. spin_unlock(&root->fs_info->new_trans_lock);
  243. }
  244. int btrfs_ordered_throttle(struct btrfs_root *root, struct inode *inode)
  245. {
  246. struct btrfs_transaction *cur = root->fs_info->running_transaction;
  247. while(cur == root->fs_info->running_transaction &&
  248. atomic_read(&BTRFS_I(inode)->ordered_writeback)) {
  249. #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)
  250. congestion_wait(WRITE, HZ/20);
  251. #else
  252. blk_congestion_wait(WRITE, HZ/20);
  253. #endif
  254. }
  255. return 0;
  256. }