aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/dev-replace.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2018-03-20 11:09:48 -0400
committerDavid Sterba <dsterba@suse.com>2018-05-28 12:07:24 -0400
commitd48f39d5a529244f59454386208c6da92bb1c493 (patch)
treef6d3c92a651d9f95703dba563ca6eb67bd94408f /fs/btrfs/dev-replace.c
parenta425f9d4755a14fd8b9d2648a23ebe1dea11bd57 (diff)
btrfs: move btrfs_init_dev_replace_tgtdev to dev-replace.c and make static
The function logically belongs there and there's only a single caller, no need to export it. No code changes. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r--fs/btrfs/dev-replace.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index e3ec0eb5789b..8531b5dae777 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -177,6 +177,105 @@ out:
177} 177}
178 178
179/* 179/*
180 * Initialize a new device for device replace target from a given source dev
181 * and path.
182 *
183 * Return 0 and new device in @device_out, otherwise return < 0
184 */
185static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
186 const char *device_path,
187 struct btrfs_device *srcdev,
188 struct btrfs_device **device_out)
189{
190 struct btrfs_device *device;
191 struct block_device *bdev;
192 struct list_head *devices;
193 struct rcu_string *name;
194 u64 devid = BTRFS_DEV_REPLACE_DEVID;
195 int ret = 0;
196
197 *device_out = NULL;
198 if (fs_info->fs_devices->seeding) {
199 btrfs_err(fs_info, "the filesystem is a seed filesystem!");
200 return -EINVAL;
201 }
202
203 bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL,
204 fs_info->bdev_holder);
205 if (IS_ERR(bdev)) {
206 btrfs_err(fs_info, "target device %s is invalid!", device_path);
207 return PTR_ERR(bdev);
208 }
209
210 filemap_write_and_wait(bdev->bd_inode->i_mapping);
211
212 devices = &fs_info->fs_devices->devices;
213 list_for_each_entry(device, devices, dev_list) {
214 if (device->bdev == bdev) {
215 btrfs_err(fs_info,
216 "target device is in the filesystem!");
217 ret = -EEXIST;
218 goto error;
219 }
220 }
221
222
223 if (i_size_read(bdev->bd_inode) <
224 btrfs_device_get_total_bytes(srcdev)) {
225 btrfs_err(fs_info,
226 "target device is smaller than source device!");
227 ret = -EINVAL;
228 goto error;
229 }
230
231
232 device = btrfs_alloc_device(NULL, &devid, NULL);
233 if (IS_ERR(device)) {
234 ret = PTR_ERR(device);
235 goto error;
236 }
237
238 name = rcu_string_strdup(device_path, GFP_KERNEL);
239 if (!name) {
240 btrfs_free_device(device);
241 ret = -ENOMEM;
242 goto error;
243 }
244 rcu_assign_pointer(device->name, name);
245
246 mutex_lock(&fs_info->fs_devices->device_list_mutex);
247 set_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
248 device->generation = 0;
249 device->io_width = fs_info->sectorsize;
250 device->io_align = fs_info->sectorsize;
251 device->sector_size = fs_info->sectorsize;
252 device->total_bytes = btrfs_device_get_total_bytes(srcdev);
253 device->disk_total_bytes = btrfs_device_get_disk_total_bytes(srcdev);
254 device->bytes_used = btrfs_device_get_bytes_used(srcdev);
255 device->commit_total_bytes = srcdev->commit_total_bytes;
256 device->commit_bytes_used = device->bytes_used;
257 device->fs_info = fs_info;
258 device->bdev = bdev;
259 set_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);
260 set_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state);
261 device->mode = FMODE_EXCL;
262 device->dev_stats_valid = 1;
263 set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
264 device->fs_devices = fs_info->fs_devices;
265 list_add(&device->dev_list, &fs_info->fs_devices->devices);
266 fs_info->fs_devices->num_devices++;
267 fs_info->fs_devices->open_devices++;
268 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
269
270 *device_out = device;
271 return 0;
272
273error:
274 blkdev_put(bdev, FMODE_EXCL);
275 return ret;
276}
277
278/*
180 * called from commit_transaction. Writes changed device replace state to 279 * called from commit_transaction. Writes changed device replace state to
181 * disk. 280 * disk.
182 */ 281 */