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 19886322e8e787604731e782d36c34327a8970bda9Sachin Kamat#include <linux/err.h> 208ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block#include <linux/uuid.h> 213768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "ctree.h" 225eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason#include "transaction.h" 233768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "disk-io.h" 243768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "print-tree.h" 253768f3689fc76ecea17414936dff7a02746a4355Chris Mason 26bf4ef67924d87b0addb32f084e83a9283496350eChris Mason/* 278ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * Read a root item from the tree. In case we detect a root item smaller then 288ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * sizeof(root_item), we know it's an old version of the root structure and 298ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * initialize all new fields to zero. The same happens if we detect mismatching 308ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * generation numbers as then we know the root was once mounted with an older 318ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * kernel that was not aware of the root item structure change. 328ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block */ 33171170c1c5625cab9687ecf6714e09e0c8a6ed3cSergei Trofimovichstatic void btrfs_read_root_item(struct extent_buffer *eb, int slot, 34171170c1c5625cab9687ecf6714e09e0c8a6ed3cSergei Trofimovich struct btrfs_root_item *item) 358ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block{ 368ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block uuid_le uuid; 378ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block int len; 388ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block int need_reset = 0; 398ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 408ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block len = btrfs_item_size_nr(eb, slot); 418ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block read_extent_buffer(eb, item, btrfs_item_ptr_offset(eb, slot), 428ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block min_t(int, len, (int)sizeof(*item))); 438ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block if (len < sizeof(*item)) 448ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block need_reset = 1; 458ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block if (!need_reset && btrfs_root_generation(item) 468ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block != btrfs_root_generation_v2(item)) { 478ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block if (btrfs_root_generation_v2(item) != 0) { 48efe120a067c8674a8ae21b194f0e68f098b61ee2Frank Holton printk(KERN_WARNING "BTRFS: mismatching " 498ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block "generation and generation_v2 " 508ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block "found in root item. This root " 518ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block "was probably mounted with an " 528ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block "older kernel. Resetting all " 538ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block "new fields.\n"); 548ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block } 558ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block need_reset = 1; 568ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block } 578ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block if (need_reset) { 588ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block memset(&item->generation_v2, 0, 598ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block sizeof(*item) - offsetof(struct btrfs_root_item, 608ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block generation_v2)); 618ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 628ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block uuid_le_gen(&uuid); 638ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block memcpy(item->uuid, uuid.b, BTRFS_UUID_SIZE); 648ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block } 658ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block} 668ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 678ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block/* 68cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * btrfs_find_root - lookup the root by the key. 69cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * root: the root of the root tree 70cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * search_key: the key to search 71cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * path: the path we search 72cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * root_item: the root item of the tree we look for 73cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * root_key: the reak key of the tree we look for 74cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * 75cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * If ->offset of 'seach_key' is -1ULL, it means we are not sure the offset 76cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * of the search key, just lookup the root with the highest offset for a 77cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * given objectid. 78cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * 79cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie * If we find something return 0, otherwise > 0, < 0 on error. 80d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */ 81cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xieint btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key, 82cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie struct btrfs_path *path, struct btrfs_root_item *root_item, 83cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie struct btrfs_key *root_key) 843768f3689fc76ecea17414936dff7a02746a4355Chris Mason{ 855f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct btrfs_key found_key; 865f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct extent_buffer *l; 873768f3689fc76ecea17414936dff7a02746a4355Chris Mason int ret; 883768f3689fc76ecea17414936dff7a02746a4355Chris Mason int slot; 893768f3689fc76ecea17414936dff7a02746a4355Chris Mason 90cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0); 913768f3689fc76ecea17414936dff7a02746a4355Chris Mason if (ret < 0) 92cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie return ret; 935f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason 94cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (search_key->offset != -1ULL) { /* the search key is exact */ 95cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (ret > 0) 96cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie goto out; 97cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie } else { 98cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie BUG_ON(ret == 0); /* Logical error */ 99cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (path->slots[0] == 0) 100cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie goto out; 101cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie path->slots[0]--; 102cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie ret = 0; 10376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 104cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie 1055f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason l = path->nodes[0]; 106cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie slot = path->slots[0]; 107cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie 1085f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason btrfs_item_key_to_cpu(l, &found_key, slot); 109cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (found_key.objectid != search_key->objectid || 11076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng found_key.type != BTRFS_ROOT_ITEM_KEY) { 1113768f3689fc76ecea17414936dff7a02746a4355Chris Mason ret = 1; 1123768f3689fc76ecea17414936dff7a02746a4355Chris Mason goto out; 1133768f3689fc76ecea17414936dff7a02746a4355Chris Mason } 1148ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 115cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (root_item) 116cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie btrfs_read_root_item(l, slot, root_item); 117cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (root_key) 118cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie memcpy(root_key, &found_key, sizeof(found_key)); 1193768f3689fc76ecea17414936dff7a02746a4355Chris Masonout: 120cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie btrfs_release_path(path); 1213768f3689fc76ecea17414936dff7a02746a4355Chris Mason return ret; 1223768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 1233768f3689fc76ecea17414936dff7a02746a4355Chris Mason 124bf5f32ecb6caac52b4d1c083251b3dd4f40a0b7aMark Fashehvoid btrfs_set_root_node(struct btrfs_root_item *item, 125bf5f32ecb6caac52b4d1c083251b3dd4f40a0b7aMark Fasheh struct extent_buffer *node) 1265d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng{ 1275d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng btrfs_set_root_bytenr(item, node->start); 1285d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng btrfs_set_root_level(item, btrfs_header_level(node)); 1295d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng btrfs_set_root_generation(item, btrfs_header_generation(node)); 1305d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng} 1315d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng 132d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/* 133d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * copy the data in 'item' into the btree 134d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */ 135e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Masonint btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root 136e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason *root, struct btrfs_key *key, struct btrfs_root_item 137e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason *item) 1383768f3689fc76ecea17414936dff7a02746a4355Chris Mason{ 1395caf2a002901f0fde475371c4bf1c553b51884afChris Mason struct btrfs_path *path; 1405f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason struct extent_buffer *l; 1413768f3689fc76ecea17414936dff7a02746a4355Chris Mason int ret; 1423768f3689fc76ecea17414936dff7a02746a4355Chris Mason int slot; 1435f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason unsigned long ptr; 1448ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block int old_len; 1453768f3689fc76ecea17414936dff7a02746a4355Chris Mason 1465caf2a002901f0fde475371c4bf1c553b51884afChris Mason path = btrfs_alloc_path(); 147b45a9d8b48e5ce534bd222007c43cbf374544f0bJeff Mahoney if (!path) 148b45a9d8b48e5ce534bd222007c43cbf374544f0bJeff Mahoney return -ENOMEM; 149b45a9d8b48e5ce534bd222007c43cbf374544f0bJeff Mahoney 1505caf2a002901f0fde475371c4bf1c553b51884afChris Mason ret = btrfs_search_slot(trans, root, key, path, 0, 1); 151005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba if (ret < 0) { 152005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba btrfs_abort_transaction(trans, root, ret); 153005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba goto out; 154005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba } 155d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason 156d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason if (ret != 0) { 157d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason btrfs_print_leaf(root, path->nodes[0]); 158efe120a067c8674a8ae21b194f0e68f098b61ee2Frank Holton btrfs_crit(root->fs_info, "unable to update root key %llu %u %llu", 159c1c9ff7c94e83fae89a742df74db51156869bad5Geert Uytterhoeven key->objectid, key->type, key->offset); 160d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason BUG_ON(1); 161d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason } 162d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason 1635f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason l = path->nodes[0]; 1645caf2a002901f0fde475371c4bf1c553b51884afChris Mason slot = path->slots[0]; 1655f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason ptr = btrfs_item_ptr_offset(l, slot); 1668ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block old_len = btrfs_item_size_nr(l, slot); 1678ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 1688ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block /* 1698ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * If this is the first time we update the root item which originated 1708ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * from an older kernel, we need to enlarge the item size to make room 1718ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * for the added fields. 1728ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block */ 1738ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block if (old_len < sizeof(*item)) { 1748ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block btrfs_release_path(path); 1758ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block ret = btrfs_search_slot(trans, root, key, path, 1768ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block -1, 1); 177005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba if (ret < 0) { 178005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba btrfs_abort_transaction(trans, root, ret); 179005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba goto out; 180005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba } 181005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba 1828ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block ret = btrfs_del_item(trans, root, path); 183005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba if (ret < 0) { 184005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba btrfs_abort_transaction(trans, root, ret); 185005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba goto out; 186005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba } 1878ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block btrfs_release_path(path); 1888ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block ret = btrfs_insert_empty_item(trans, root, path, 1898ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block key, sizeof(*item)); 190005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba if (ret < 0) { 191005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba btrfs_abort_transaction(trans, root, ret); 192005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba goto out; 193005d6427ac4f276d937a36ca6a1d62b181ed70bfDavid Sterba } 1948ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block l = path->nodes[0]; 1958ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block slot = path->slots[0]; 1968ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block ptr = btrfs_item_ptr_offset(l, slot); 1978ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block } 1988ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 1998ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block /* 2008ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * Update generation_v2 so at the next mount we know the new root 2018ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * fields are valid. 2028ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block */ 2038ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block btrfs_set_root_generation_v2(item, btrfs_root_generation(item)); 2048ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 2055f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason write_extent_buffer(l, item, ptr, sizeof(*item)); 2065caf2a002901f0fde475371c4bf1c553b51884afChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 2073768f3689fc76ecea17414936dff7a02746a4355Chris Masonout: 2085caf2a002901f0fde475371c4bf1c553b51884afChris Mason btrfs_free_path(path); 2093768f3689fc76ecea17414936dff7a02746a4355Chris Mason return ret; 2103768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 2113768f3689fc76ecea17414936dff7a02746a4355Chris Mason 212d16cb050e5b1c3a9d754fed7098eefb8237877d1Jeff Mahoneyint btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, 213d16cb050e5b1c3a9d754fed7098eefb8237877d1Jeff Mahoney struct btrfs_key *key, struct btrfs_root_item *item) 2143768f3689fc76ecea17414936dff7a02746a4355Chris Mason{ 2158ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block /* 2168ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block * Make sure generation v1 and v2 match. See update_root for details. 2178ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block */ 2188ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block btrfs_set_root_generation_v2(item, btrfs_root_generation(item)); 219d16cb050e5b1c3a9d754fed7098eefb8237877d1Jeff Mahoney return btrfs_insert_item(trans, root, key, item, sizeof(*item)); 2203768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 2213768f3689fc76ecea17414936dff7a02746a4355Chris Mason 22276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zhengint btrfs_find_orphan_roots(struct btrfs_root *tree_root) 22376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng{ 22476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng struct extent_buffer *leaf; 22576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng struct btrfs_path *path; 22676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng struct btrfs_key key; 227d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng struct btrfs_key root_key; 228d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng struct btrfs_root *root; 22976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng int err = 0; 23076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng int ret; 23168a7342c51c950428d90cd15da898c63d6c33267Josef Bacik bool can_recover = true; 23268a7342c51c950428d90cd15da898c63d6c33267Josef Bacik 23368a7342c51c950428d90cd15da898c63d6c33267Josef Bacik if (tree_root->fs_info->sb->s_flags & MS_RDONLY) 23468a7342c51c950428d90cd15da898c63d6c33267Josef Bacik can_recover = false; 23576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 23676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng path = btrfs_alloc_path(); 23776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (!path) 23876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng return -ENOMEM; 23976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 24076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.objectid = BTRFS_ORPHAN_OBJECTID; 24176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.type = BTRFS_ORPHAN_ITEM_KEY; 24276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.offset = 0; 24376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 244d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng root_key.type = BTRFS_ROOT_ITEM_KEY; 245d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng root_key.offset = (u64)-1; 246d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng 24776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng while (1) { 24876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); 24976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (ret < 0) { 25076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng err = ret; 25176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 25276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 25376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 25476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng leaf = path->nodes[0]; 25576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (path->slots[0] >= btrfs_header_nritems(leaf)) { 25676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng ret = btrfs_next_leaf(tree_root, path); 25776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (ret < 0) 25876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng err = ret; 25976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (ret != 0) 26076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 26176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng leaf = path->nodes[0]; 26276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 26376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 26476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 265b3b4aa74b58bded927f579fff787fb6fa1c0393cDavid Sterba btrfs_release_path(path); 26676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 26776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng if (key.objectid != BTRFS_ORPHAN_OBJECTID || 26876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng key.type != BTRFS_ORPHAN_ITEM_KEY) 26976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 27076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 271d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng root_key.objectid = key.offset; 272d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng key.offset++; 273d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng 274cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie root = btrfs_read_fs_root(tree_root, &root_key); 275886322e8e787604731e782d36c34327a8970bda9Sachin Kamat err = PTR_ERR_OR_ZERO(root); 27668a7342c51c950428d90cd15da898c63d6c33267Josef Bacik if (err && err != -ENOENT) { 277cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie break; 27868a7342c51c950428d90cd15da898c63d6c33267Josef Bacik } else if (err == -ENOENT) { 27968a7342c51c950428d90cd15da898c63d6c33267Josef Bacik struct btrfs_trans_handle *trans; 28068a7342c51c950428d90cd15da898c63d6c33267Josef Bacik 28168a7342c51c950428d90cd15da898c63d6c33267Josef Bacik btrfs_release_path(path); 28268a7342c51c950428d90cd15da898c63d6c33267Josef Bacik 28368a7342c51c950428d90cd15da898c63d6c33267Josef Bacik trans = btrfs_join_transaction(tree_root); 28468a7342c51c950428d90cd15da898c63d6c33267Josef Bacik if (IS_ERR(trans)) { 28568a7342c51c950428d90cd15da898c63d6c33267Josef Bacik err = PTR_ERR(trans); 28668a7342c51c950428d90cd15da898c63d6c33267Josef Bacik btrfs_error(tree_root->fs_info, err, 28768a7342c51c950428d90cd15da898c63d6c33267Josef Bacik "Failed to start trans to delete " 28868a7342c51c950428d90cd15da898c63d6c33267Josef Bacik "orphan item"); 28968a7342c51c950428d90cd15da898c63d6c33267Josef Bacik break; 29068a7342c51c950428d90cd15da898c63d6c33267Josef Bacik } 29168a7342c51c950428d90cd15da898c63d6c33267Josef Bacik err = btrfs_del_orphan_item(trans, tree_root, 29268a7342c51c950428d90cd15da898c63d6c33267Josef Bacik root_key.objectid); 29368a7342c51c950428d90cd15da898c63d6c33267Josef Bacik btrfs_end_transaction(trans, tree_root); 29468a7342c51c950428d90cd15da898c63d6c33267Josef Bacik if (err) { 29568a7342c51c950428d90cd15da898c63d6c33267Josef Bacik btrfs_error(tree_root->fs_info, err, 29668a7342c51c950428d90cd15da898c63d6c33267Josef Bacik "Failed to delete root orphan " 29768a7342c51c950428d90cd15da898c63d6c33267Josef Bacik "item"); 29868a7342c51c950428d90cd15da898c63d6c33267Josef Bacik break; 29968a7342c51c950428d90cd15da898c63d6c33267Josef Bacik } 30068a7342c51c950428d90cd15da898c63d6c33267Josef Bacik continue; 301cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie } 302cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie 303cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie err = btrfs_init_fs_root(root); 304cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (err) { 305cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie btrfs_free_fs_root(root); 30676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng break; 30776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng } 30876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng 30927cdeb7096b86f05ad018a24cdb63acdf0850a5dMiao Xie set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state); 310cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie 311cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie err = btrfs_insert_fs_root(root->fs_info, root); 312cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie if (err) { 313cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie BUG_ON(err == -EEXIST); 314cb517eabba4f109810dba2e5f37b0dcf22103065Miao Xie btrfs_free_fs_root(root); 315d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng break; 316d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng } 31714927d95464956ffe8af4278331a6bfea94ab780Miao Xie 31814927d95464956ffe8af4278331a6bfea94ab780Miao Xie if (btrfs_root_refs(&root->root_item) == 0) 31914927d95464956ffe8af4278331a6bfea94ab780Miao Xie btrfs_add_dead_root(root); 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; 3323768f3689fc76ecea17414936dff7a02746a4355Chris Mason 3335caf2a002901f0fde475371c4bf1c553b51884afChris Mason path = btrfs_alloc_path(); 334db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh if (!path) 335db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh return -ENOMEM; 3365caf2a002901f0fde475371c4bf1c553b51884afChris Mason ret = btrfs_search_slot(trans, root, key, path, -1, 1); 3373768f3689fc76ecea17414936dff7a02746a4355Chris Mason if (ret < 0) 3383768f3689fc76ecea17414936dff7a02746a4355Chris Mason goto out; 339edbd8d4efe4ddaf29a175ae504e2c9a05a96ebeeChris Mason 3403768f3689fc76ecea17414936dff7a02746a4355Chris Mason BUG_ON(ret != 0); 341c5739bba5260a59cebd20a51a55080592c8d3b07Chris Mason 3425eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason ret = btrfs_del_item(trans, root, path); 3433768f3689fc76ecea17414936dff7a02746a4355Chris Masonout: 3445caf2a002901f0fde475371c4bf1c553b51884afChris Mason btrfs_free_path(path); 3453768f3689fc76ecea17414936dff7a02746a4355Chris Mason return ret; 3463768f3689fc76ecea17414936dff7a02746a4355Chris Mason} 3470660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 3480660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Masonint btrfs_del_root_ref(struct btrfs_trans_handle *trans, 3490660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_root *tree_root, 3504df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, 3514df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng const char *name, int name_len) 3524df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3530660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason{ 3544df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct btrfs_path *path; 3554df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct btrfs_root_ref *ref; 3564df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct extent_buffer *leaf; 3570660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_key key; 3584df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng unsigned long ptr; 3594df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng int err = 0; 3600660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason int ret; 3610660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 3620660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason path = btrfs_alloc_path(); 3634df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (!path) 3644df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return -ENOMEM; 3650660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 3660660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.objectid = root_id; 3674df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_BACKREF_KEY; 3680660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.offset = ref_id; 3694df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zhengagain: 3700660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); 3714df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng BUG_ON(ret < 0); 3724df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (ret == 0) { 3734df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng leaf = path->nodes[0]; 3744df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng ref = btrfs_item_ptr(leaf, path->slots[0], 3754df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng struct btrfs_root_ref); 3764df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3774df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid); 3784df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len); 3794df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng ptr = (unsigned long)(ref + 1); 3804df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len)); 3814df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng *sequence = btrfs_root_ref_sequence(leaf, ref); 3824df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3834df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng ret = btrfs_del_item(trans, tree_root, path); 38465a246c5ffe3b487a001de025816326939e63362Tsutomu Itoh if (ret) { 38565a246c5ffe3b487a001de025816326939e63362Tsutomu Itoh err = ret; 38665a246c5ffe3b487a001de025816326939e63362Tsutomu Itoh goto out; 38765a246c5ffe3b487a001de025816326939e63362Tsutomu Itoh } 3884df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng } else 3894df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng err = -ENOENT; 3904df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 3914df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (key.type == BTRFS_ROOT_BACKREF_KEY) { 392b3b4aa74b58bded927f579fff787fb6fa1c0393cDavid Sterba btrfs_release_path(path); 3934df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.objectid = ref_id; 3944df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_REF_KEY; 3954df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.offset = root_id; 3964df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng goto again; 3974df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng } 3980660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 39965a246c5ffe3b487a001de025816326939e63362Tsutomu Itohout: 4000660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_free_path(path); 4014df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return err; 4020660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason} 4030660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4040660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason/* 4050660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY 4060660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * or BTRFS_ROOT_BACKREF_KEY. 4070660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * 4080660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * The dirid, sequence, name and name_len refer to the directory entry 4090660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * that is referencing the root. 4100660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * 4110660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * For a forward ref, the root_id is the id of the tree referencing 4120660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * the root and ref_id is the id of the subvol or snapshot. 4130660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * 4140660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * For a back ref the root_id is the id of the subvol or snapshot and 4150660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * ref_id is the id of the tree referencing it. 41679787eaab46121d4713ed03c8fc63b9ec3eaec76Jeff Mahoney * 41779787eaab46121d4713ed03c8fc63b9ec3eaec76Jeff Mahoney * Will return 0, -ENOMEM, or anything from the CoW path 4180660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason */ 4190660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Masonint btrfs_add_root_ref(struct btrfs_trans_handle *trans, 4200660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_root *tree_root, 4214df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng u64 root_id, u64 ref_id, u64 dirid, u64 sequence, 4220660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason const char *name, int name_len) 4230660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason{ 4240660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_key key; 4250660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason int ret; 4260660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_path *path; 4270660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct btrfs_root_ref *ref; 4280660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason struct extent_buffer *leaf; 4290660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason unsigned long ptr; 4300660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4310660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason path = btrfs_alloc_path(); 4324df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (!path) 4334df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return -ENOMEM; 4340660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4350660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.objectid = root_id; 4364df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_BACKREF_KEY; 4370660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason key.offset = ref_id; 4384df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zhengagain: 4390660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ret = btrfs_insert_empty_item(trans, tree_root, path, &key, 4400660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason sizeof(*ref) + name_len); 44179787eaab46121d4713ed03c8fc63b9ec3eaec76Jeff Mahoney if (ret) { 44279787eaab46121d4713ed03c8fc63b9ec3eaec76Jeff Mahoney btrfs_abort_transaction(trans, tree_root, ret); 44379787eaab46121d4713ed03c8fc63b9ec3eaec76Jeff Mahoney btrfs_free_path(path); 44479787eaab46121d4713ed03c8fc63b9ec3eaec76Jeff Mahoney return ret; 44579787eaab46121d4713ed03c8fc63b9ec3eaec76Jeff Mahoney } 4460660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4470660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason leaf = path->nodes[0]; 4480660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); 4490660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_set_root_ref_dirid(leaf, ref, dirid); 4500660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_set_root_ref_sequence(leaf, ref, sequence); 4510660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_set_root_ref_name_len(leaf, ref, name_len); 4520660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason ptr = (unsigned long)(ref + 1); 4530660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason write_extent_buffer(leaf, name, ptr, name_len); 4540660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_mark_buffer_dirty(leaf); 4550660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason 4564df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng if (key.type == BTRFS_ROOT_BACKREF_KEY) { 457b3b4aa74b58bded927f579fff787fb6fa1c0393cDavid Sterba btrfs_release_path(path); 4584df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.objectid = ref_id; 4594df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.type = BTRFS_ROOT_REF_KEY; 4604df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng key.offset = root_id; 4614df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng goto again; 4624df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng } 4634df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng 4640660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason btrfs_free_path(path); 4654df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng return 0; 4660660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason} 46708fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan 46808fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan/* 46908fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan * Old btrfs forgets to init root_item->flags and root_item->byte_limit 47008fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan * for subvolumes. To work around this problem, we steal a bit from 47108fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan * root_item->inode_item->flags, and use it to indicate if those fields 47208fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan * have been properly initialized. 47308fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan */ 47408fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefanvoid btrfs_check_and_init_root_item(struct btrfs_root_item *root_item) 47508fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan{ 4763cae210fa529d69cb25c2a3c491f29dab687b245Qu Wenruo u64 inode_flags = btrfs_stack_inode_flags(&root_item->inode); 47708fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan 47808fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) { 47908fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT; 4803cae210fa529d69cb25c2a3c491f29dab687b245Qu Wenruo btrfs_set_stack_inode_flags(&root_item->inode, inode_flags); 4813cae210fa529d69cb25c2a3c491f29dab687b245Qu Wenruo btrfs_set_root_flags(root_item, 0); 4823cae210fa529d69cb25c2a3c491f29dab687b245Qu Wenruo btrfs_set_root_limit(root_item, 0); 48308fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan } 48408fe4db170b4193603d9d31f40ebaf652d07ac9cLi Zefan} 4858ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 4868ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Blockvoid btrfs_update_root_times(struct btrfs_trans_handle *trans, 4878ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block struct btrfs_root *root) 4888ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block{ 4898ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block struct btrfs_root_item *item = &root->root_item; 4908ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block struct timespec ct = CURRENT_TIME; 4918ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block 4925f3ab90a72f98adbf00c50ac2d4d2b47cf4a9685Anand Jain spin_lock(&root->root_item_lock); 4933cae210fa529d69cb25c2a3c491f29dab687b245Qu Wenruo btrfs_set_root_ctransid(item, trans->transid); 4943cae210fa529d69cb25c2a3c491f29dab687b245Qu Wenruo btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec); 4953cae210fa529d69cb25c2a3c491f29dab687b245Qu Wenruo btrfs_set_stack_timespec_nsec(&item->ctime, ct.tv_nsec); 4965f3ab90a72f98adbf00c50ac2d4d2b47cf4a9685Anand Jain spin_unlock(&root->root_item_lock); 4978ea05e3a4262b9e6871c349fa3486bcfc72ffd1aAlexander Block} 498