diff options
author | Stefan Behrens <sbehrens@giantdisaster.de> | 2012-11-05 08:42:30 -0500 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2012-12-12 17:15:33 -0500 |
commit | 7ba15b7d211846c187a7c5dc75a5964476f8bc89 (patch) | |
tree | 7af9534b30451d08e4dca7e8f4076d09773cfeb8 | |
parent | beaf8ab3afef27ed81255d9808b67f6d390ca06f (diff) |
Btrfs: add two more find_device() methods
The new function btrfs_find_device_missing_or_by_path() will be
used for the device replace procedure. This function itself calls
the second new function btrfs_find_device_by_path().
Unfortunately, it is not possible to currently make the rest of the
code use these functions as well, since all functions that look
similar at first view are all a little bit different in what they
are doing. But in the future, new code could benefit from these
two new functions, and currently, device replace uses them.
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r-- | fs/btrfs/volumes.c | 59 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 5 |
2 files changed, 64 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 4def1fdbf755..1483041eb86a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1522,6 +1522,65 @@ error_undo: | |||
1522 | goto error_brelse; | 1522 | goto error_brelse; |
1523 | } | 1523 | } |
1524 | 1524 | ||
1525 | int btrfs_find_device_by_path(struct btrfs_root *root, char *device_path, | ||
1526 | struct btrfs_device **device) | ||
1527 | { | ||
1528 | int ret = 0; | ||
1529 | struct btrfs_super_block *disk_super; | ||
1530 | u64 devid; | ||
1531 | u8 *dev_uuid; | ||
1532 | struct block_device *bdev; | ||
1533 | struct buffer_head *bh; | ||
1534 | |||
1535 | *device = NULL; | ||
1536 | ret = btrfs_get_bdev_and_sb(device_path, FMODE_READ, | ||
1537 | root->fs_info->bdev_holder, 0, &bdev, &bh); | ||
1538 | if (ret) | ||
1539 | return ret; | ||
1540 | disk_super = (struct btrfs_super_block *)bh->b_data; | ||
1541 | devid = btrfs_stack_device_id(&disk_super->dev_item); | ||
1542 | dev_uuid = disk_super->dev_item.uuid; | ||
1543 | *device = btrfs_find_device(root, devid, dev_uuid, | ||
1544 | disk_super->fsid); | ||
1545 | brelse(bh); | ||
1546 | if (!*device) | ||
1547 | ret = -ENOENT; | ||
1548 | blkdev_put(bdev, FMODE_READ); | ||
1549 | return ret; | ||
1550 | } | ||
1551 | |||
1552 | int btrfs_find_device_missing_or_by_path(struct btrfs_root *root, | ||
1553 | char *device_path, | ||
1554 | struct btrfs_device **device) | ||
1555 | { | ||
1556 | *device = NULL; | ||
1557 | if (strcmp(device_path, "missing") == 0) { | ||
1558 | struct list_head *devices; | ||
1559 | struct btrfs_device *tmp; | ||
1560 | |||
1561 | devices = &root->fs_info->fs_devices->devices; | ||
1562 | /* | ||
1563 | * It is safe to read the devices since the volume_mutex | ||
1564 | * is held by the caller. | ||
1565 | */ | ||
1566 | list_for_each_entry(tmp, devices, dev_list) { | ||
1567 | if (tmp->in_fs_metadata && !tmp->bdev) { | ||
1568 | *device = tmp; | ||
1569 | break; | ||
1570 | } | ||
1571 | } | ||
1572 | |||
1573 | if (!*device) { | ||
1574 | pr_err("btrfs: no missing device found\n"); | ||
1575 | return -ENOENT; | ||
1576 | } | ||
1577 | |||
1578 | return 0; | ||
1579 | } else { | ||
1580 | return btrfs_find_device_by_path(root, device_path, device); | ||
1581 | } | ||
1582 | } | ||
1583 | |||
1525 | /* | 1584 | /* |
1526 | * does all the dirty work required for changing file system's UUID. | 1585 | * does all the dirty work required for changing file system's UUID. |
1527 | */ | 1586 | */ |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 1789cda57efb..657bb12b3069 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -268,6 +268,11 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
268 | struct btrfs_fs_devices **fs_devices_ret); | 268 | struct btrfs_fs_devices **fs_devices_ret); |
269 | int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); | 269 | int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); |
270 | void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices); | 270 | void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices); |
271 | int btrfs_find_device_missing_or_by_path(struct btrfs_root *root, | ||
272 | char *device_path, | ||
273 | struct btrfs_device **device); | ||
274 | int btrfs_find_device_by_path(struct btrfs_root *root, char *device_path, | ||
275 | struct btrfs_device **device); | ||
271 | int btrfs_add_device(struct btrfs_trans_handle *trans, | 276 | int btrfs_add_device(struct btrfs_trans_handle *trans, |
272 | struct btrfs_root *root, | 277 | struct btrfs_root *root, |
273 | struct btrfs_device *device); | 278 | struct btrfs_device *device); |