2007-06-12 17:07:21 +04:00
/*
* Copyright ( C ) 2007 Oracle . All rights reserved .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public
* License v2 as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public
* License along with this program ; if not , write to the
* Free Software Foundation , Inc . , 59 Temple Place - Suite 330 ,
* Boston , MA 021110 - 1307 , USA .
*/
2007-03-20 21:38:32 +03:00
# include "ctree.h"
# include "disk-io.h"
# include "transaction.h"
2007-04-10 20:13:09 +04:00
int btrfs_find_highest_inode ( struct btrfs_root * root , u64 * objectid )
2007-04-05 21:35:25 +04:00
{
struct btrfs_path * path ;
int ret ;
2007-10-16 00:14:19 +04:00
struct extent_buffer * l ;
2007-04-05 21:35:25 +04:00
struct btrfs_key search_key ;
2007-10-16 00:14:19 +04:00
struct btrfs_key found_key ;
2007-04-05 21:35:25 +04:00
int slot ;
path = btrfs_alloc_path ( ) ;
BUG_ON ( ! path ) ;
2008-09-06 00:43:53 +04:00
search_key . objectid = BTRFS_LAST_FREE_OBJECTID ;
search_key . type = - 1 ;
2007-04-05 21:35:25 +04:00
search_key . offset = ( u64 ) - 1 ;
ret = btrfs_search_slot ( NULL , root , & search_key , path , 0 , 0 ) ;
if ( ret < 0 )
goto error ;
BUG_ON ( ret = = 0 ) ;
if ( path - > slots [ 0 ] > 0 ) {
slot = path - > slots [ 0 ] - 1 ;
2007-10-16 00:14:19 +04:00
l = path - > nodes [ 0 ] ;
btrfs_item_key_to_cpu ( l , & found_key , slot ) ;
* objectid = found_key . objectid ;
2007-04-05 21:35:25 +04:00
} else {
* objectid = BTRFS_FIRST_FREE_OBJECTID ;
}
ret = 0 ;
error :
btrfs_free_path ( path ) ;
return ret ;
}
2007-03-20 21:38:32 +03:00
/*
* walks the btree of allocated inodes and find a hole .
*/
int btrfs_find_free_objectid ( struct btrfs_trans_handle * trans ,
2007-04-10 20:13:09 +04:00
struct btrfs_root * root ,
2007-03-20 21:38:32 +03:00
u64 dirid , u64 * objectid )
{
2007-04-02 22:53:59 +04:00
struct btrfs_path * path ;
2007-03-20 21:38:32 +03:00
struct btrfs_key key ;
int ret ;
int slot = 0 ;
2007-03-22 19:13:20 +03:00
u64 last_ino = 0 ;
2007-03-20 21:38:32 +03:00
int start_found ;
2007-10-16 00:14:19 +04:00
struct extent_buffer * l ;
2007-03-20 21:38:32 +03:00
struct btrfs_key search_key ;
u64 search_start = dirid ;
2008-06-26 00:01:30 +04:00
mutex_lock ( & root - > objectid_mutex ) ;
2008-09-06 00:43:53 +04:00
if ( root - > last_inode_alloc > = BTRFS_FIRST_FREE_OBJECTID & &
root - > last_inode_alloc < BTRFS_LAST_FREE_OBJECTID ) {
2008-06-26 00:01:30 +04:00
* objectid = + + root - > last_inode_alloc ;
mutex_unlock ( & root - > objectid_mutex ) ;
return 0 ;
}
2007-04-04 23:27:52 +04:00
path = btrfs_alloc_path ( ) ;
BUG_ON ( ! path ) ;
2009-04-21 23:38:30 +04:00
search_start = max ( search_start , ( u64 ) BTRFS_FIRST_FREE_OBJECTID ) ;
2007-03-20 21:38:32 +03:00
search_key . objectid = search_start ;
2008-09-06 00:43:53 +04:00
search_key . type = 0 ;
2007-03-20 21:38:32 +03:00
search_key . offset = 0 ;
start_found = 0 ;
2007-04-02 22:53:59 +04:00
ret = btrfs_search_slot ( trans , root , & search_key , path , 0 , 0 ) ;
2007-03-20 21:38:32 +03:00
if ( ret < 0 )
goto error ;
while ( 1 ) {
2007-10-16 00:14:19 +04:00
l = path - > nodes [ 0 ] ;
2007-04-02 22:53:59 +04:00
slot = path - > slots [ 0 ] ;
2007-10-16 00:14:19 +04:00
if ( slot > = btrfs_header_nritems ( l ) ) {
2007-04-02 22:53:59 +04:00
ret = btrfs_next_leaf ( root , path ) ;
2007-03-20 21:38:32 +03:00
if ( ret = = 0 )
continue ;
if ( ret < 0 )
goto error ;
if ( ! start_found ) {
* objectid = search_start ;
start_found = 1 ;
goto found ;
}
* objectid = last_ino > search_start ?
last_ino : search_start ;
goto found ;
}
2007-10-16 00:14:19 +04:00
btrfs_item_key_to_cpu ( l , & key , slot ) ;
2007-03-20 21:38:32 +03:00
if ( key . objectid > = search_start ) {
if ( start_found ) {
if ( last_ino < search_start )
last_ino = search_start ;
2008-01-22 20:46:56 +03:00
if ( key . objectid > last_ino ) {
2007-03-20 21:38:32 +03:00
* objectid = last_ino ;
goto found ;
}
2008-09-26 18:05:38 +04:00
} else if ( key . objectid > search_start ) {
* objectid = search_start ;
goto found ;
2007-03-20 21:38:32 +03:00
}
}
2008-09-06 00:43:53 +04:00
if ( key . objectid > = BTRFS_LAST_FREE_OBJECTID )
break ;
2008-09-26 18:05:38 +04:00
2007-03-20 21:38:32 +03:00
start_found = 1 ;
last_ino = key . objectid + 1 ;
2007-04-02 22:53:59 +04:00
path - > slots [ 0 ] + + ;
2007-03-20 21:38:32 +03:00
}
2008-09-06 00:43:53 +04:00
BUG_ON ( 1 ) ;
2007-03-20 21:38:32 +03:00
found :
2007-04-02 22:53:59 +04:00
btrfs_release_path ( root , path ) ;
btrfs_free_path ( path ) ;
2007-03-20 21:38:32 +03:00
BUG_ON ( * objectid < search_start ) ;
2008-06-26 00:01:30 +04:00
mutex_unlock ( & root - > objectid_mutex ) ;
2007-03-20 21:38:32 +03:00
return 0 ;
error :
2007-04-02 22:53:59 +04:00
btrfs_release_path ( root , path ) ;
btrfs_free_path ( path ) ;
2008-06-26 00:01:30 +04:00
mutex_unlock ( & root - > objectid_mutex ) ;
2007-03-20 21:38:32 +03:00
return ret ;
}