root-tree.c revision db5b493ac78e46c7b6bad22cd25d8041564cd8ea
16cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason/* 26cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * Copyright (C) 2007 Oracle. All rights reserved. 36cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * 46cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * This program is free software; you can redistribute it and/or 56cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * modify it under the terms of the GNU General Public 66cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * License v2 as published by the Free Software Foundation. 76cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * 86cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * This program is distributed in the hope that it will be useful, 96cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * but WITHOUT ANY WARRANTY; without even the implied warranty of 106cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 116cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * General Public License for more details. 126cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * 136cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * You should have received a copy of the GNU General Public 146cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * License along with this program; if not, write to the 156cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 166cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * Boston, MA 021110-1307, USA. 176cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason */ 186cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason 193768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "ctree.h" 205eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason#include "transaction.h" 213768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "disk-io.h" 223768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "print-tree.h" 233768f3689fc76ecea17414936dff7a02746a4355Chris Mason 24bf4ef67924d87b0addb32f084e83a9283496350eChris Mason/* 25d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * search forward for a root, starting with objectid 'search_start' 26d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * if a root key is found, the objectid we find is filled into 'found_objectid' 27d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * and 0 is returned. < 0 is returned on error, 1 if there is nothing 28d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * left in the tree. 29bf4ef67924d87b0addb32f084e83a9283496350eChris Mason */ 30bf4ef67924d87b0addb32f084e83a9283496350eChris Masonint btrfs_search_root(struct btrfs_root *root, u64 search_start, 31bf4ef67924d87b0addb32f084e83a9283496350eChris Mason u64 *found_objectid) 32bf4ef67924d87b0addb32f084e83a9283496350eChris Mason{ 33bf4ef67924d87b0addb32f084e83a9283496350eChris Mason struct btrfs_path *path; 34bf4ef67924d87b0addb32f084e83a9283496350eChris Mason struct btrfs_key search_key; 35bf4ef67924d87b0addb32f084e83a9283496350eChris Mason int ret; 36bf4ef67924d87b0addb32f084e83a9283496350eChris Mason 37bf4ef67924d87b0addb32f084e83a9283496350eChris Mason root = root->fs_info->tree_root; 38bf4ef67924d87b0addb32f084e83a9283496350eChris Mason search_key.objectid = search_start; 39bf4ef67924d87b0addb32f084e83a9283496350eChris Mason search_key.type = (u8)-1; 40bf4ef67924d87b0addb32f084e83a9283496350eChris Mason search_key.offset = (u64)-1; 41bf4ef67924d87b0addb32f084e83a9283496350eChris Mason 42bf4ef67924d87b0addb32f084e83a9283496350eChris Mason path = btrfs_alloc_path(); 43bf4ef67924d87b0addb32f084e83a9283496350eChris Mason BUG_ON(!path); 44bf4ef67924d87b0addb32f084e83a9283496350eChris Masonagain: 45bf4ef67924d87b0addb32f084e83a9283496350eChris Mason ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); 46bf4ef67924d87b0addb32f084e83a9283496350eChris Mason if (ret < 0) 47bf4ef67924d87b0addb32f084e83a9283496350eChris Mason goto out; 48bf4ef67924d87b0addb32f084e83a9283496350eChris Mason if (ret == 0) { 49bf4ef67924d87b0addb32f084e83a9283496350eChris Mason ret = 1; 50bf4ef67924d87b0addb32f084e83a9283496350eChris Mason goto out; 51bf4ef67924d87b0addb32f084e83a9283496350eChris Mason } 52bf4ef67924d87b0addb32f084e83a9283496350eChris Mason if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { 53bf4ef67924d87b0addb32f084e83a9283496350eChris Mason ret = btrfs_next_leaf(root, path); 54bf4ef67924d87b0addb32f084e83a9283496350eChris Mason if (ret) 55bf4ef67924d87b0addb32f084e83a9283496350eChris Mason goto out; 56bf4ef67924d87b0addb32f084e83a9283496350eChris Mason } 57bf4ef67924d87b0addb32f084e83a9283496350eChris Mason btrfs_item_key_to_cpu(path->nodes[0], &search_key, path->slots[0]); 58bf4ef67924d87b0addb32f084e83a9283496350eChris Mason if (search_key.type != BTRFS_ROOT_ITEM_KEY) { 59bf4ef67924d87b0addb32f084e83a9283496350eChris Mason search_key.offset++; 60bf4ef67924d87b0addb32f084e83a9283496350eChris Mason btrfs_release_path(root, path); 61bf4ef67924d87b0addb32f084e83a9283496350eChris Mason goto again; 62bf4ef67924d87b0addb32f084e83a9283496350eChris Mason } 63bf4ef67924d87b0addb32f084e83a9283496350eChris Mason ret = 0; 64bf4ef67924d87b0addb32f084e83a9283496350eChris Mason *found_objectid = search_key.objectid; 65bf4ef67924d87b0addb32f084e83a9283496350eChris Mason 66bf4ef67924d87b0addb32f084e83a9283496350eChris Masonout: 67bf4ef67924d87b0addb32f084e83a9283496350eChris Mason btrfs_free_path(path); 68bf4ef67924d87b0addb32f084e83a9283496350eChris Mason return ret; 69bf4ef67924d87b0addb32f084e83a9283496350eChris Mason} 70bf4ef67924d87b0addb32f084e83a9283496350eChris Mason 71d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/* 72d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * lookup the root with the highest offset for a given objectid. The key we do 73d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * find is copied into 'key'. If we find something return 0, otherwise 1, < 0 74d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * on error. 75d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */ 763768f3689fc76ecea17414936dff7a02746a4355Chris Masonint btrfs_find_last_root(struct btrfs_root *root, u64 objectid, 773768f3689fc76ecea17414936dff7a02746a4355Chris Mason struct btrfs_root_item *item, struct btrfs_key *key) 783768f3689fc76ecea17414936dff7a02746a4355Chris Mason{ 795caf2a002901f0fde475371c4bf1c553b51884afChris Mason struct btrfs_path *path; 803768f3689fc76ecea17414936dff7a02746a4355Chris Mason struct btrfs_key search_key; 815f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct btrfs_key found_key; 825f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct extent_buffer *l; 833768f3689fc76ecea17414936dff7a02746a4355Chris Mason int ret; 843768f3689fc76ecea17414936dff7a02746a4355Chris Mason int slot; 853768f3689fc76ecea17414936dff7a02746a4355Chris Mason 863768f3689fc76ecea17414936dff7a02746a4355Chris Mason search_key.objectid = objectid; 870660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason search_key.type = BTRFS_ROOT_ITEM_KEY; 885eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason search_key.offset = (u64)-1; 893768f3689fc76ecea17414936dff7a02746a4355Chris Mason 905caf2a002901f0fde475371c4bf1c553b51884afChris Mason path = btrfs_alloc_path(); 91db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh if (!path) 92db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh return -ENOMEM; 935caf2a002901f0fde475371c4bf1c553b51884afChris Mason ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); 943768f3689fc76ecea17414936dff7a02746a4355Chris Mason if (ret < 0) 953768f3689fc76ecea17414936dff7a02746a4355Chris Mason goto out; 965f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason 973768f3689fc76ecea17414936dff7a02746a4355Chris Mason BUG_ON(ret == 0); 9876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (path->slots[0] == 0) { 9976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng ret = 1; 10076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng goto out; 10176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 1025f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason l = path->nodes[0]; 1035caf2a002901f0fde475371c4bf1c553b51884afChris Mason slot = path->slots[0] - 1; 1045f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason btrfs_item_key_to_cpu(l, &found_key, slot); 10576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (found_key.objectid != objectid || 10676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng found_key.type != BTRFS_ROOT_ITEM_KEY) { 1073768f3689fc76ecea17414936dff7a02746a4355Chris Mason ret = 1; 1083768f3689fc76ecea17414936dff7a02746a4355Chris Mason goto out; 1093768f3689fc76ecea17414936dff7a02746a4355Chris Mason } 11076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (item) 11176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), 11276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng sizeof(*item)); 11376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (key) 11476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng memcpy(key, &found_key, sizeof(found_key)); 1153768f3689fc76ecea17414936dff7a02746a4355Chris Mason ret = 0; 1163768f3689fc76ecea17414936dff7a02746a4355Chris Masonout: 1175caf2a002901f0fde475371c4bf1c553b51884afChris Mason btrfs_free_path(path); 1183768f3689fc76ecea17414936dff7a02746a4355Chris Mason return ret; 1193768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 1203768f3689fc76ecea17414936dff7a02746a4355Chris Mason 1215d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zhengint btrfs_set_root_node(struct btrfs_root_item *item, 1225d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng struct extent_buffer *node) 1235d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng{ 1245d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng btrfs_set_root_bytenr(item, node->start); 1255d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng btrfs_set_root_level(item, btrfs_header_level(node)); 1265d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng btrfs_set_root_generation(item, btrfs_header_generation(node)); 1275d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng return 0; 1285d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng} 1295d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng 130d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/* 131d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * copy the data in 'item' into the btree 132d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */ 133e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Masonint btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root 134e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason *root, struct btrfs_key *key, struct btrfs_root_item 135e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason *item) 1363768f3689fc76ecea17414936dff7a02746a4355Chris Mason{ 1375caf2a002901f0fde475371c4bf1c553b51884afChris Mason struct btrfs_path *path; 1385f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct extent_buffer *l; 1393768f3689fc76ecea17414936dff7a02746a4355Chris Mason int ret; 1403768f3689fc76ecea17414936dff7a02746a4355Chris Mason int slot; 1415f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason unsigned long ptr; 1423768f3689fc76ecea17414936dff7a02746a4355Chris Mason 1435caf2a002901f0fde475371c4bf1c553b51884afChris Mason path = btrfs_alloc_path(); 1445caf2a002901f0fde475371c4bf1c553b51884afChris Mason BUG_ON(!path); 1455caf2a002901f0fde475371c4bf1c553b51884afChris Mason ret = btrfs_search_slot(trans, root, key, path, 0, 1); 1463768f3689fc76ecea17414936dff7a02746a4355Chris Mason if (ret < 0) 1473768f3689fc76ecea17414936dff7a02746a4355Chris Mason goto out; 148d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason 149d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason if (ret != 0) { 150d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason btrfs_print_leaf(root, path->nodes[0]); 151d397712bcc6a759a560fd247e6053ecae091f958Chris Mason printk(KERN_CRIT "unable to update root key %llu %u %llu\n", 152d397712bcc6a759a560fd247e6053ecae091f958Chris Mason (unsigned long long)key->objectid, key->type, 153d397712bcc6a759a560fd247e6053ecae091f958Chris Mason (unsigned long long)key->offset); 154d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason BUG_ON(1); 155d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason } 156d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason 1575f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason l = path->nodes[0]; 1585caf2a002901f0fde475371c4bf1c553b51884afChris Mason slot = path->slots[0]; 1595f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason ptr = btrfs_item_ptr_offset(l, slot); 1605f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason write_extent_buffer(l, item, ptr, sizeof(*item)); 1615caf2a002901f0fde475371c4bf1c553b51884afChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 1623768f3689fc76ecea17414936dff7a02746a4355Chris Masonout: 1635caf2a002901f0fde475371c4bf1c553b51884afChris Mason btrfs_free_path(path); 1643768f3689fc76ecea17414936dff7a02746a4355Chris Mason return ret; 1653768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 1663768f3689fc76ecea17414936dff7a02746a4355Chris Mason 167e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Masonint btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root 168e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason *root, struct btrfs_key *key, struct btrfs_root_item 169e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason *item) 1703768f3689fc76ecea17414936dff7a02746a4355Chris Mason{ 1713768f3689fc76ecea17414936dff7a02746a4355Chris Mason int ret; 172e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason ret = btrfs_insert_item(trans, root, key, item, sizeof(*item)); 1733768f3689fc76ecea17414936dff7a02746a4355Chris Mason return ret; 1743768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 1753768f3689fc76ecea17414936dff7a02746a4355Chris Mason 176d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/* 177d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * at mount time we want to find all the old transaction snapshots that were in 178d397712bcc6a759a560fd247e6053ecae091f958Chris Mason * the process of being deleted if we crashed. This is any root item with an 179d397712bcc6a759a560fd247e6053ecae091f958Chris Mason * offset lower than the latest root. They need to be queued for deletion to 180d397712bcc6a759a560fd247e6053ecae091f958Chris Mason * finish what was happening when we crashed. 181d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */ 1825d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zhengint btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid) 1835eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason{ 1845eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason struct btrfs_root *dead_root; 1855eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason struct btrfs_root_item *ri; 1865eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason struct btrfs_key key; 187a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason struct btrfs_key found_key; 1885eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason struct btrfs_path *path; 1895eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason int ret; 1905eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason u32 nritems; 1915f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct extent_buffer *leaf; 1925eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason int slot; 1935eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason 1945ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason key.objectid = objectid; 1955eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); 1965eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason key.offset = 0; 1975eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason path = btrfs_alloc_path(); 1985eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason if (!path) 1995eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason return -ENOMEM; 200a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason 201a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Masonagain: 2025eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 2035eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason if (ret < 0) 2045eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason goto err; 205d397712bcc6a759a560fd247e6053ecae091f958Chris Mason while (1) { 2065f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason leaf = path->nodes[0]; 2075f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason nritems = btrfs_header_nritems(leaf); 2085eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason slot = path->slots[0]; 2095eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason if (slot >= nritems) { 2105eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason ret = btrfs_next_leaf(root, path); 2115eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason if (ret) 2125eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason break; 2135f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason leaf = path->nodes[0]; 2145f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason nritems = btrfs_header_nritems(leaf); 2155eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason slot = path->slots[0]; 2165eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason } 2175f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason btrfs_item_key_to_cpu(leaf, &key, slot); 2185eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY) 2195eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason goto next; 2205ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason 2215ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason if (key.objectid < objectid) 2225ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason goto next; 2235ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason 2245ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason if (key.objectid > objectid) 2255ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason break; 2265ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason 2275eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item); 2285f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason if (btrfs_disk_root_refs(leaf, ri) != 0) 2295eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason goto next; 2305ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason 231a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason memcpy(&found_key, &key, sizeof(key)); 232a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason key.offset++; 233a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason btrfs_release_path(root, path); 234e02119d5a7b4396c5a872582fddc8bd6d305a70aChris Mason dead_root = 235e02119d5a7b4396c5a872582fddc8bd6d305a70aChris Mason btrfs_read_fs_root_no_radix(root->fs_info->tree_root, 236e02119d5a7b4396c5a872582fddc8bd6d305a70aChris Mason &found_key); 237a1f396304fb7e5f18e4ea81c294415375f1c814cAneesh if (IS_ERR(dead_root)) { 238a1f396304fb7e5f18e4ea81c294415375f1c814cAneesh ret = PTR_ERR(dead_root); 2395eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason goto err; 2405eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason } 2415ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason 2425d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng ret = btrfs_add_dead_root(dead_root); 2435eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason if (ret) 2445eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason goto err; 245a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason goto again; 2465eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Masonnext: 2475eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason slot++; 2485eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason path->slots[0]++; 2495eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason } 2505eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason ret = 0; 2515eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Masonerr: 2525eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason btrfs_free_path(path); 2535eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason return ret; 2545eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason} 2555eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason 25676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zhengint btrfs_find_orphan_roots(struct btrfs_root *tree_root) 25776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng{ 25876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng struct extent_buffer *leaf; 25976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng struct btrfs_path *path; 26076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng struct btrfs_key key; 261d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng struct btrfs_key root_key; 262d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng struct btrfs_root *root; 26376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng int err = 0; 26476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng int ret; 26576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 26676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng path = btrfs_alloc_path(); 26776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (!path) 26876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng return -ENOMEM; 26976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 27076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.objectid = BTRFS_ORPHAN_OBJECTID; 27176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.type = BTRFS_ORPHAN_ITEM_KEY; 27276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.offset = 0; 27376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 274d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng root_key.type = BTRFS_ROOT_ITEM_KEY; 275d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng root_key.offset = (u64)-1; 276d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng 27776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng while (1) { 27876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); 27976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (ret < 0) { 28076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng err = ret; 28176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 28276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 28376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 28476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng leaf = path->nodes[0]; 28576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (path->slots[0] >= btrfs_header_nritems(leaf)) { 28676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng ret = btrfs_next_leaf(tree_root, path); 28776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (ret < 0) 28876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng err = ret; 28976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (ret != 0) 29076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 29176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng leaf = path->nodes[0]; 29276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 29376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 29476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 29576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng btrfs_release_path(tree_root, path); 29676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 29776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (key.objectid != BTRFS_ORPHAN_OBJECTID || 29876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.type != BTRFS_ORPHAN_ITEM_KEY) 29976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 30076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 301d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng root_key.objectid = key.offset; 302d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng key.offset++; 303d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng 304d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng root = btrfs_read_fs_root_no_name(tree_root->fs_info, 305d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng &root_key); 306d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng if (!IS_ERR(root)) 307d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng continue; 308d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng 309d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng ret = PTR_ERR(root); 310d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng if (ret != -ENOENT) { 31176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng err = ret; 31276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 31376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 31476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 315d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng ret = btrfs_find_dead_roots(tree_root, root_key.objectid); 316d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng if (ret) { 317d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng err = ret; 318d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng break; 319d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng } 32076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 32176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 32276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng btrfs_free_path(path); 32376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng return err; 32476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng} 32576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 326d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/* drop the root item for 'key' from 'root' */ 327e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Masonint btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, 328e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason struct btrfs_key *key) 3293768f3689fc76ecea17414936dff7a02746a4355Chris Mason{ 3305caf2a002901f0fde475371c4bf1c553b51884afChris Mason struct btrfs_path *path; 3313768f3689fc76ecea17414936dff7a02746a4355Chris Mason int ret; 332c5739bba5260a59cebd20a51a55080592c8d3b07Chris Mason struct btrfs_root_item *ri; 3335f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct extent_buffer *leaf; 3343768f3689fc76ecea17414936dff7a02746a4355Chris Mason 3355caf2a002901f0fde475371c4bf1c553b51884afChris Mason path = btrfs_alloc_path(); 336db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh if (!path) 337db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh return -ENOMEM; 3385caf2a002901f0fde475371c4bf1c553b51884afChris Mason ret = btrfs_search_slot(trans, root, key, path, -1, 1); 3393768f3689fc76ecea17414936dff7a02746a4355Chris Mason if (ret < 0) 3403768f3689fc76ecea17414936dff7a02746a4355Chris Mason goto out; 341edbd8d4efe4ddaf29a175ae504e2c9a05a96ebeeChris Mason 3423768f3689fc76ecea17414936dff7a02746a4355Chris Mason BUG_ON(ret != 0); 3435f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason leaf = path->nodes[0]; 3445f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item); 345c5739bba5260a59cebd20a51a55080592c8d3b07Chris Mason 3465eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason ret = btrfs_del_item(trans, root, path); 3473768f3689fc76ecea17414936dff7a02746a4355Chris Masonout: 3485caf2a002901f0fde475371c4bf1c553b51884afChris Mason btrfs_free_path(path); 3493768f3689fc76ecea17414936dff7a02746a4355Chris Mason return ret; 3503768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 3510660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 3520660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Masonint btrfs_del_root_ref(struct btrfs_trans_handle *trans, 3530660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_root *tree_root, 3544df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, 3554df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng const char *name, int name_len) 3564df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3570660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason{ 3584df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct btrfs_path *path; 3594df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct btrfs_root_ref *ref; 3604df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct extent_buffer *leaf; 3610660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_key key; 3624df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng unsigned long ptr; 3634df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng int err = 0; 3640660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason int ret; 3650660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 3660660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason path = btrfs_alloc_path(); 3674df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (!path) 3684df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return -ENOMEM; 3690660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 3700660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.objectid = root_id; 3714df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_BACKREF_KEY; 3720660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.offset = ref_id; 3734df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zhengagain: 3740660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); 3754df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng BUG_ON(ret < 0); 3764df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (ret == 0) { 3774df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng leaf = path->nodes[0]; 3784df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng ref = btrfs_item_ptr(leaf, path->slots[0], 3794df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct btrfs_root_ref); 3804df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3814df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid); 3824df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len); 3834df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng ptr = (unsigned long)(ref + 1); 3844df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len)); 3854df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng *sequence = btrfs_root_ref_sequence(leaf, ref); 3864df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3874df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng ret = btrfs_del_item(trans, tree_root, path); 3884df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng BUG_ON(ret); 3894df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng } else 3904df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng err = -ENOENT; 3914df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3924df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (key.type == BTRFS_ROOT_BACKREF_KEY) { 3934df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng btrfs_release_path(tree_root, path); 3944df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.objectid = ref_id; 3954df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_REF_KEY; 3964df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.offset = root_id; 3974df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng goto again; 3984df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng } 3990660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4000660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_free_path(path); 4014df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return err; 4020660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason} 4030660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 404ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Masonint btrfs_find_root_ref(struct btrfs_root *tree_root, 405ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason struct btrfs_path *path, 406ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason u64 root_id, u64 ref_id) 407ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason{ 408ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason struct btrfs_key key; 409ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason int ret; 410ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason 411ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason key.objectid = root_id; 412ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason key.type = BTRFS_ROOT_REF_KEY; 413ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason key.offset = ref_id; 414ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason 415ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); 416ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason return ret; 417ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason} 418ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason 4190660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason/* 4200660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY 4210660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * or BTRFS_ROOT_BACKREF_KEY. 4220660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * 4230660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * The dirid, sequence, name and name_len refer to the directory entry 4240660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * that is referencing the root. 4250660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * 4260660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * For a forward ref, the root_id is the id of the tree referencing 4270660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * the root and ref_id is the id of the subvol or snapshot. 4280660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * 4290660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * For a back ref the root_id is the id of the subvol or snapshot and 4300660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * ref_id is the id of the tree referencing it. 4310660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason */ 4320660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Masonint btrfs_add_root_ref(struct btrfs_trans_handle *trans, 4330660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_root *tree_root, 4344df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng u64 root_id, u64 ref_id, u64 dirid, u64 sequence, 4350660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason const char *name, int name_len) 4360660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason{ 4370660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_key key; 4380660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason int ret; 4390660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_path *path; 4400660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_root_ref *ref; 4410660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct extent_buffer *leaf; 4420660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason unsigned long ptr; 4430660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4440660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason path = btrfs_alloc_path(); 4454df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (!path) 4464df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return -ENOMEM; 4470660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4480660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.objectid = root_id; 4494df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_BACKREF_KEY; 4500660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.offset = ref_id; 4514df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zhengagain: 4520660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ret = btrfs_insert_empty_item(trans, tree_root, path, &key, 4530660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason sizeof(*ref) + name_len); 4540660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason BUG_ON(ret); 4550660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4560660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason leaf = path->nodes[0]; 4570660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); 4580660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_set_root_ref_dirid(leaf, ref, dirid); 4590660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_set_root_ref_sequence(leaf, ref, sequence); 4600660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_set_root_ref_name_len(leaf, ref, name_len); 4610660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ptr = (unsigned long)(ref + 1); 4620660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason write_extent_buffer(leaf, name, ptr, name_len); 4630660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_mark_buffer_dirty(leaf); 4640660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4654df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (key.type == BTRFS_ROOT_BACKREF_KEY) { 4664df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng btrfs_release_path(tree_root, path); 4674df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.objectid = ref_id; 4684df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_REF_KEY; 4694df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.offset = root_id; 4704df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng goto again; 4714df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng } 4724df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 4730660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_free_path(path); 4744df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return 0; 4750660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason} 476