| Chris Mason | 6cbd557 | 2007-06-12 09:07:21 -0400 | [diff] [blame] | 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 |  | 
| Chris Mason | 9f5fae2 | 2007-03-20 14:38:32 -0400 | [diff] [blame] | 19 | #include "ctree.h" | 
|  | 20 | #include "disk-io.h" | 
|  | 21 | #include "transaction.h" | 
|  | 22 |  | 
| Chris Mason | 1b05da2 | 2007-04-10 12:13:09 -0400 | [diff] [blame] | 23 | int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid) | 
| Chris Mason | 5be6f7f | 2007-04-05 13:35:25 -0400 | [diff] [blame] | 24 | { | 
|  | 25 | struct btrfs_path *path; | 
|  | 26 | int ret; | 
| Chris Mason | 5f39d39 | 2007-10-15 16:14:19 -0400 | [diff] [blame] | 27 | struct extent_buffer *l; | 
| Chris Mason | 5be6f7f | 2007-04-05 13:35:25 -0400 | [diff] [blame] | 28 | struct btrfs_key search_key; | 
| Chris Mason | 5f39d39 | 2007-10-15 16:14:19 -0400 | [diff] [blame] | 29 | struct btrfs_key found_key; | 
| Chris Mason | 5be6f7f | 2007-04-05 13:35:25 -0400 | [diff] [blame] | 30 | int slot; | 
|  | 31 |  | 
|  | 32 | path = btrfs_alloc_path(); | 
|  | 33 | BUG_ON(!path); | 
|  | 34 |  | 
| Zheng Yan | 6527cdb | 2008-09-05 16:43:53 -0400 | [diff] [blame] | 35 | search_key.objectid = BTRFS_LAST_FREE_OBJECTID; | 
|  | 36 | search_key.type = -1; | 
| Chris Mason | 5be6f7f | 2007-04-05 13:35:25 -0400 | [diff] [blame] | 37 | search_key.offset = (u64)-1; | 
|  | 38 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | 
|  | 39 | if (ret < 0) | 
|  | 40 | goto error; | 
|  | 41 | BUG_ON(ret == 0); | 
|  | 42 | if (path->slots[0] > 0) { | 
|  | 43 | slot = path->slots[0] - 1; | 
| Chris Mason | 5f39d39 | 2007-10-15 16:14:19 -0400 | [diff] [blame] | 44 | l = path->nodes[0]; | 
|  | 45 | btrfs_item_key_to_cpu(l, &found_key, slot); | 
| Yan, Zheng | 13a8a7c | 2009-09-21 15:56:00 -0400 | [diff] [blame] | 46 | *objectid = max_t(u64, found_key.objectid, | 
|  | 47 | BTRFS_FIRST_FREE_OBJECTID - 1); | 
| Chris Mason | 5be6f7f | 2007-04-05 13:35:25 -0400 | [diff] [blame] | 48 | } else { | 
| Yan, Zheng | 13a8a7c | 2009-09-21 15:56:00 -0400 | [diff] [blame] | 49 | *objectid = BTRFS_FIRST_FREE_OBJECTID - 1; | 
| Chris Mason | 5be6f7f | 2007-04-05 13:35:25 -0400 | [diff] [blame] | 50 | } | 
|  | 51 | ret = 0; | 
|  | 52 | error: | 
|  | 53 | btrfs_free_path(path); | 
|  | 54 | return ret; | 
|  | 55 | } | 
|  | 56 |  | 
| Chris Mason | 9f5fae2 | 2007-03-20 14:38:32 -0400 | [diff] [blame] | 57 | int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, | 
| Chris Mason | 1b05da2 | 2007-04-10 12:13:09 -0400 | [diff] [blame] | 58 | struct btrfs_root *root, | 
| Chris Mason | 9f5fae2 | 2007-03-20 14:38:32 -0400 | [diff] [blame] | 59 | u64 dirid, u64 *objectid) | 
|  | 60 | { | 
| Chris Mason | 9f5fae2 | 2007-03-20 14:38:32 -0400 | [diff] [blame] | 61 | int ret; | 
| Chris Mason | a213501 | 2008-06-25 16:01:30 -0400 | [diff] [blame] | 62 | mutex_lock(&root->objectid_mutex); | 
| Yan, Zheng | 13a8a7c | 2009-09-21 15:56:00 -0400 | [diff] [blame] | 63 |  | 
|  | 64 | if (unlikely(root->highest_objectid < BTRFS_FIRST_FREE_OBJECTID)) { | 
|  | 65 | ret = btrfs_find_highest_inode(root, &root->highest_objectid); | 
|  | 66 | if (ret) | 
|  | 67 | goto out; | 
| Chris Mason | a213501 | 2008-06-25 16:01:30 -0400 | [diff] [blame] | 68 | } | 
| Chris Mason | b1a4d96 | 2007-04-04 15:27:52 -0400 | [diff] [blame] | 69 |  | 
| Yan, Zheng | 13a8a7c | 2009-09-21 15:56:00 -0400 | [diff] [blame] | 70 | if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) { | 
|  | 71 | ret = -ENOSPC; | 
|  | 72 | goto out; | 
| Chris Mason | 9f5fae2 | 2007-03-20 14:38:32 -0400 | [diff] [blame] | 73 | } | 
| Yan, Zheng | 13a8a7c | 2009-09-21 15:56:00 -0400 | [diff] [blame] | 74 |  | 
|  | 75 | *objectid = ++root->highest_objectid; | 
|  | 76 | ret = 0; | 
|  | 77 | out: | 
| Chris Mason | a213501 | 2008-06-25 16:01:30 -0400 | [diff] [blame] | 78 | mutex_unlock(&root->objectid_mutex); | 
| Chris Mason | 9f5fae2 | 2007-03-20 14:38:32 -0400 | [diff] [blame] | 79 | return ret; | 
|  | 80 | } |