@ -63,6 +63,48 @@ static void unlock_chunks(struct btrfs_root *root)
mutex_unlock ( & root - > fs_info - > chunk_mutex ) ;
mutex_unlock ( & root - > fs_info - > chunk_mutex ) ;
}
}
static struct btrfs_fs_devices * __alloc_fs_devices ( void )
{
struct btrfs_fs_devices * fs_devs ;
fs_devs = kzalloc ( sizeof ( * fs_devs ) , GFP_NOFS ) ;
if ( ! fs_devs )
return ERR_PTR ( - ENOMEM ) ;
mutex_init ( & fs_devs - > device_list_mutex ) ;
INIT_LIST_HEAD ( & fs_devs - > devices ) ;
INIT_LIST_HEAD ( & fs_devs - > alloc_list ) ;
INIT_LIST_HEAD ( & fs_devs - > list ) ;
return fs_devs ;
}
/**
* alloc_fs_devices - allocate struct btrfs_fs_devices
* @ fsid : a pointer to UUID for this FS . If NULL a new UUID is
* generated .
*
* Return : a pointer to a new & struct btrfs_fs_devices on success ;
* ERR_PTR ( ) on error . Returned struct is not linked onto any lists and
* can be destroyed with kfree ( ) right away .
*/
static struct btrfs_fs_devices * alloc_fs_devices ( const u8 * fsid )
{
struct btrfs_fs_devices * fs_devs ;
fs_devs = __alloc_fs_devices ( ) ;
if ( IS_ERR ( fs_devs ) )
return fs_devs ;
if ( fsid )
memcpy ( fs_devs - > fsid , fsid , BTRFS_FSID_SIZE ) ;
else
generate_random_uuid ( fs_devs - > fsid ) ;
return fs_devs ;
}
static void free_fs_devices ( struct btrfs_fs_devices * fs_devices )
static void free_fs_devices ( struct btrfs_fs_devices * fs_devices )
{
{
struct btrfs_device * device ;
struct btrfs_device * device ;
@ -417,16 +459,14 @@ static noinline int device_list_add(const char *path,
fs_devices = find_fsid ( disk_super - > fsid ) ;
fs_devices = find_fsid ( disk_super - > fsid ) ;
if ( ! fs_devices ) {
if ( ! fs_devices ) {
fs_devices = kzalloc ( sizeof ( * fs_devices ) , GFP_NOFS ) ;
fs_devices = alloc_fs_devices ( disk_super - > fsid ) ;
if ( ! fs_devices )
if ( IS_ERR ( fs_devices ) )
return - ENOMEM ;
return PTR_ERR ( fs_devices ) ;
INIT_LIST_HEAD ( & fs_devices - > devices ) ;
INIT_LIST_HEAD ( & fs_devices - > alloc_list ) ;
list_add ( & fs_devices - > list , & fs_uuids ) ;
list_add ( & fs_devices - > list , & fs_uuids ) ;
memcpy ( fs_devices - > fsid , disk_super - > fsid , BTRFS_FSID_SIZE ) ;
fs_devices - > latest_devid = devid ;
fs_devices - > latest_devid = devid ;
fs_devices - > latest_trans = found_transid ;
fs_devices - > latest_trans = found_transid ;
mutex_init ( & fs_devices - > device_list_mutex ) ;
device = NULL ;
device = NULL ;
} else {
} else {
device = __find_device ( & fs_devices - > devices , devid ,
device = __find_device ( & fs_devices - > devices , devid ,
@ -482,18 +522,13 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
struct btrfs_device * device ;
struct btrfs_device * device ;
struct btrfs_device * orig_dev ;
struct btrfs_device * orig_dev ;
fs_devices = kzalloc ( sizeof ( * fs_devices ) , GFP_NOFS ) ;
fs_devices = alloc_fs_devices ( orig - > fsid ) ;
if ( ! fs_devices )
if ( IS_ERR ( fs_devices ) )
return ERR_PTR ( - ENOMEM ) ;
return fs_devices ;
INIT_LIST_HEAD ( & fs_devices - > devices ) ;
INIT_LIST_HEAD ( & fs_devices - > alloc_list ) ;
INIT_LIST_HEAD ( & fs_devices - > list ) ;
mutex_init ( & fs_devices - > device_list_mutex ) ;
fs_devices - > latest_devid = orig - > latest_devid ;
fs_devices - > latest_devid = orig - > latest_devid ;
fs_devices - > latest_trans = orig - > latest_trans ;
fs_devices - > latest_trans = orig - > latest_trans ;
fs_devices - > total_devices = orig - > total_devices ;
fs_devices - > total_devices = orig - > total_devices ;
memcpy ( fs_devices - > fsid , orig - > fsid , sizeof ( fs_devices - > fsid ) ) ;
/* We have held the volume lock, it is safe to get the devices. */
/* We have held the volume lock, it is safe to get the devices. */
list_for_each_entry ( orig_dev , & orig - > devices , dev_list ) {
list_for_each_entry ( orig_dev , & orig - > devices , dev_list ) {
@ -1797,9 +1832,9 @@ static int btrfs_prepare_sprout(struct btrfs_root *root)
if ( ! fs_devices - > seeding )
if ( ! fs_devices - > seeding )
return - EINVAL ;
return - EINVAL ;
seed_devices = kzalloc ( sizeof ( * fs_devices ) , GFP_NOFS ) ;
seed_devices = __alloc_fs_devices ( ) ;
if ( ! seed_devices )
if ( IS_ERR ( seed_devices ) )
return - ENOMEM ;
return PTR_ERR ( seed_devices ) ;
old_devices = clone_fs_devices ( fs_devices ) ;
old_devices = clone_fs_devices ( fs_devices ) ;
if ( IS_ERR ( old_devices ) ) {
if ( IS_ERR ( old_devices ) ) {