Blame view

block/partitions/core.c 18.6 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
94ea4158f   Al Viro   separate partitio...
2
  /*
387048bf6   Christoph Hellwig   block: merge part...
3
4
   * Copyright (C) 1991-1998  Linus Torvalds
   * Re-organised Feb 1998 Russell King
94ea4158f   Al Viro   separate partitio...
5
   */
94ea4158f   Al Viro   separate partitio...
6
7
  #include <linux/fs.h>
  #include <linux/slab.h>
94ea4158f   Al Viro   separate partitio...
8
9
  #include <linux/ctype.h>
  #include <linux/genhd.h>
387048bf6   Christoph Hellwig   block: merge part...
10
  #include <linux/vmalloc.h>
94ea4158f   Al Viro   separate partitio...
11
  #include <linux/blktrace_api.h>
74cc979c3   Christoph Hellwig   block: cleanup ho...
12
  #include <linux/raid/detect.h>
387048bf6   Christoph Hellwig   block: merge part...
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  #include "check.h"
  
  static int (*check_part[])(struct parsed_partitions *) = {
  	/*
  	 * Probe partition formats with tables at disk address 0
  	 * that also have an ADFS boot block at 0xdc0.
  	 */
  #ifdef CONFIG_ACORN_PARTITION_ICS
  	adfspart_check_ICS,
  #endif
  #ifdef CONFIG_ACORN_PARTITION_POWERTEC
  	adfspart_check_POWERTEC,
  #endif
  #ifdef CONFIG_ACORN_PARTITION_EESOX
  	adfspart_check_EESOX,
  #endif
  
  	/*
  	 * Now move on to formats that only have partition info at
  	 * disk address 0xdc0.  Since these may also have stale
  	 * PC/BIOS partition tables, they need to come before
  	 * the msdos entry.
  	 */
  #ifdef CONFIG_ACORN_PARTITION_CUMANA
  	adfspart_check_CUMANA,
  #endif
  #ifdef CONFIG_ACORN_PARTITION_ADFS
  	adfspart_check_ADFS,
  #endif
  
  #ifdef CONFIG_CMDLINE_PARTITION
  	cmdline_partition,
  #endif
  #ifdef CONFIG_EFI_PARTITION
  	efi_partition,		/* this must come before msdos */
  #endif
  #ifdef CONFIG_SGI_PARTITION
  	sgi_partition,
  #endif
  #ifdef CONFIG_LDM_PARTITION
  	ldm_partition,		/* this must come before msdos */
  #endif
  #ifdef CONFIG_MSDOS_PARTITION
  	msdos_partition,
  #endif
  #ifdef CONFIG_OSF_PARTITION
  	osf_partition,
  #endif
  #ifdef CONFIG_SUN_PARTITION
  	sun_partition,
  #endif
  #ifdef CONFIG_AMIGA_PARTITION
  	amiga_partition,
  #endif
  #ifdef CONFIG_ATARI_PARTITION
  	atari_partition,
  #endif
  #ifdef CONFIG_MAC_PARTITION
  	mac_partition,
  #endif
  #ifdef CONFIG_ULTRIX_PARTITION
  	ultrix_partition,
  #endif
  #ifdef CONFIG_IBM_PARTITION
  	ibm_partition,
  #endif
  #ifdef CONFIG_KARMA_PARTITION
  	karma_partition,
  #endif
  #ifdef CONFIG_SYSV68_PARTITION
  	sysv68_partition,
  #endif
  	NULL
  };
  
  static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
  {
  	struct parsed_partitions *state;
  	int nr;
  
  	state = kzalloc(sizeof(*state), GFP_KERNEL);
  	if (!state)
  		return NULL;
  
  	nr = disk_max_parts(hd);
  	state->parts = vzalloc(array_size(nr, sizeof(state->parts[0])));
  	if (!state->parts) {
  		kfree(state);
  		return NULL;
  	}
  
  	state->limit = nr;
  
  	return state;
  }
  
  static void free_partitions(struct parsed_partitions *state)
  {
  	vfree(state->parts);
  	kfree(state);
  }
  
  static struct parsed_partitions *check_partition(struct gendisk *hd,
  		struct block_device *bdev)
  {
  	struct parsed_partitions *state;
  	int i, res, err;
  
  	state = allocate_partitions(hd);
  	if (!state)
  		return NULL;
  	state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
  	if (!state->pp_buf) {
  		free_partitions(state);
  		return NULL;
  	}
  	state->pp_buf[0] = '\0';
  
  	state->bdev = bdev;
  	disk_name(hd, 0, state->name);
  	snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
  	if (isdigit(state->name[strlen(state->name)-1]))
  		sprintf(state->name, "p");
  
  	i = res = err = 0;
  	while (!res && check_part[i]) {
  		memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
  		res = check_part[i++](state);
  		if (res < 0) {
  			/*
  			 * We have hit an I/O error which we don't report now.
  			 * But record it, and let the others do their job.
  			 */
  			err = res;
  			res = 0;
  		}
  
  	}
  	if (res > 0) {
  		printk(KERN_INFO "%s", state->pp_buf);
  
  		free_page((unsigned long)state->pp_buf);
  		return state;
  	}
  	if (state->access_beyond_eod)
  		err = -ENOSPC;
  	/*
  	 * The partition is unrecognized. So report I/O errors if there were any
  	 */
  	if (err)
  		res = err;
  	if (res) {
  		strlcat(state->pp_buf,
  			" unable to read partition table
  ", PAGE_SIZE);
  		printk(KERN_INFO "%s", state->pp_buf);
  	}
94ea4158f   Al Viro   separate partitio...
170

387048bf6   Christoph Hellwig   block: merge part...
171
172
173
174
  	free_page((unsigned long)state->pp_buf);
  	free_partitions(state);
  	return ERR_PTR(res);
  }
94ea4158f   Al Viro   separate partitio...
175

94ea4158f   Al Viro   separate partitio...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  static ssize_t part_partition_show(struct device *dev,
  				   struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
  
  	return sprintf(buf, "%d
  ", p->partno);
  }
  
  static ssize_t part_start_show(struct device *dev,
  			       struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
  
  	return sprintf(buf, "%llu
  ",(unsigned long long)p->start_sect);
  }
94ea4158f   Al Viro   separate partitio...
193
194
195
196
197
198
199
200
201
202
203
204
  static ssize_t part_ro_show(struct device *dev,
  			    struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
  	return sprintf(buf, "%d
  ", p->policy ? 1 : 0);
  }
  
  static ssize_t part_alignment_offset_show(struct device *dev,
  					  struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
7b8917f5e   Christoph Hellwig   block: remove the...
205
206
207
208
209
  
  	return sprintf(buf, "%u
  ",
  		queue_limit_alignment_offset(&part_to_disk(p)->queue->limits,
  				p->start_sect));
94ea4158f   Al Viro   separate partitio...
210
211
212
213
214
215
  }
  
  static ssize_t part_discard_alignment_show(struct device *dev,
  					   struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
7cf34d97a   Christoph Hellwig   block: remove the...
216
217
218
219
220
  
  	return sprintf(buf, "%u
  ",
  		queue_limit_discard_alignment(&part_to_disk(p)->queue->limits,
  				p->start_sect));
94ea4158f   Al Viro   separate partitio...
221
  }
5657a819a   Joe Perches   block drivers/blo...
222
223
224
225
226
227
228
229
  static DEVICE_ATTR(partition, 0444, part_partition_show, NULL);
  static DEVICE_ATTR(start, 0444, part_start_show, NULL);
  static DEVICE_ATTR(size, 0444, part_size_show, NULL);
  static DEVICE_ATTR(ro, 0444, part_ro_show, NULL);
  static DEVICE_ATTR(alignment_offset, 0444, part_alignment_offset_show, NULL);
  static DEVICE_ATTR(discard_alignment, 0444, part_discard_alignment_show, NULL);
  static DEVICE_ATTR(stat, 0444, part_stat_show, NULL);
  static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL);
94ea4158f   Al Viro   separate partitio...
230
231
  #ifdef CONFIG_FAIL_MAKE_REQUEST
  static struct device_attribute dev_attr_fail =
5657a819a   Joe Perches   block drivers/blo...
232
  	__ATTR(make-it-fail, 0644, part_fail_show, part_fail_store);
94ea4158f   Al Viro   separate partitio...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
  #endif
  
  static struct attribute *part_attrs[] = {
  	&dev_attr_partition.attr,
  	&dev_attr_start.attr,
  	&dev_attr_size.attr,
  	&dev_attr_ro.attr,
  	&dev_attr_alignment_offset.attr,
  	&dev_attr_discard_alignment.attr,
  	&dev_attr_stat.attr,
  	&dev_attr_inflight.attr,
  #ifdef CONFIG_FAIL_MAKE_REQUEST
  	&dev_attr_fail.attr,
  #endif
  	NULL
  };
  
  static struct attribute_group part_attr_group = {
  	.attrs = part_attrs,
  };
  
  static const struct attribute_group *part_attr_groups[] = {
  	&part_attr_group,
  #ifdef CONFIG_BLK_DEV_IO_TRACE
  	&blk_trace_attr_group,
  #endif
  	NULL
  };
  
  static void part_release(struct device *dev)
  {
  	struct hd_struct *p = dev_to_part(dev);
2da78092d   Keith Busch   block: Fix dev_t ...
265
  	blk_free_devt(dev->devt);
b54e5ed8f   Ming Lei   block: partition:...
266
  	hd_free_part(p);
94ea4158f   Al Viro   separate partitio...
267
268
  	kfree(p);
  }
0d9c51a6e   San Mehat   block: partition:...
269
270
271
272
273
274
275
276
277
  static int part_uevent(struct device *dev, struct kobj_uevent_env *env)
  {
  	struct hd_struct *part = dev_to_part(dev);
  
  	add_uevent_var(env, "PARTN=%u", part->partno);
  	if (part->info && part->info->volname[0])
  		add_uevent_var(env, "PARTNAME=%s", part->info->volname);
  	return 0;
  }
94ea4158f   Al Viro   separate partitio...
278
279
280
281
  struct device_type part_type = {
  	.name		= "partition",
  	.groups		= part_attr_groups,
  	.release	= part_release,
0d9c51a6e   San Mehat   block: partition:...
282
  	.uevent		= part_uevent,
94ea4158f   Al Viro   separate partitio...
283
  };
8da2892e2   Christoph Hellwig   block: cleanup hd...
284
  static void hd_struct_free_work(struct work_struct *work)
94ea4158f   Al Viro   separate partitio...
285
  {
8da2892e2   Christoph Hellwig   block: cleanup hd...
286
287
  	struct hd_struct *part =
  		container_of(to_rcu_work(work), struct hd_struct, rcu_work);
cafe01ef8   Ming Lei   block: release di...
288
289
290
291
292
293
294
295
296
  	struct gendisk *disk = part_to_disk(part);
  
  	/*
  	 * Release the disk reference acquired in delete_partition here.
  	 * We can't release it in hd_struct_free because the final put_device
  	 * needs process context and thus can't be run directly from a
  	 * percpu_ref ->release handler.
  	 */
  	put_device(disk_to_dev(disk));
94ea4158f   Al Viro   separate partitio...
297
298
299
300
301
302
  
  	part->start_sect = 0;
  	part->nr_sects = 0;
  	part_stat_set_all(part, 0);
  	put_device(part_to_dev(part));
  }
8da2892e2   Christoph Hellwig   block: cleanup hd...
303
  static void hd_struct_free(struct percpu_ref *ref)
94ea4158f   Al Viro   separate partitio...
304
  {
6c71013ec   Ming Lei   block: partition:...
305
  	struct hd_struct *part = container_of(ref, struct hd_struct, ref);
b7d6c3033   Ming Lei   block: fix use-af...
306
307
308
309
310
  	struct gendisk *disk = part_to_disk(part);
  	struct disk_part_tbl *ptbl =
  		rcu_dereference_protected(disk->part_tbl, 1);
  
  	rcu_assign_pointer(ptbl->last_lookup, NULL);
8da2892e2   Christoph Hellwig   block: cleanup hd...
311
312
  
  	INIT_RCU_WORK(&part->rcu_work, hd_struct_free_work);
94a2c3a32   Yufen Yu   block: use rcu_wo...
313
  	queue_rcu_work(system_wq, &part->rcu_work);
94ea4158f   Al Viro   separate partitio...
314
  }
8da2892e2   Christoph Hellwig   block: cleanup hd...
315
316
317
318
319
320
  int hd_ref_init(struct hd_struct *part)
  {
  	if (percpu_ref_init(&part->ref, hd_struct_free, 0, GFP_KERNEL))
  		return -ENOMEM;
  	return 0;
  }
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
321
322
323
324
  /*
   * Must be called either with bd_mutex held, before a disk can be opened or
   * after all disk users are gone.
   */
8328eb283   Christoph Hellwig   block: remove the...
325
  void delete_partition(struct hd_struct *part)
94ea4158f   Al Viro   separate partitio...
326
  {
8328eb283   Christoph Hellwig   block: remove the...
327
  	struct gendisk *disk = part_to_disk(part);
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
328
329
  	struct disk_part_tbl *ptbl =
  		rcu_dereference_protected(disk->part_tbl, 1);
94ea4158f   Al Viro   separate partitio...
330

b7d6c3033   Ming Lei   block: fix use-af...
331
332
333
334
  	/*
  	 * ->part_tbl is referenced in this part's release handler, so
  	 *  we have to hold the disk device
  	 */
8328eb283   Christoph Hellwig   block: remove the...
335
  	get_device(disk_to_dev(disk));
cddae808a   Christoph Hellwig   block: pass a hd_...
336
  	rcu_assign_pointer(ptbl->part[part->partno], NULL);
94ea4158f   Al Viro   separate partitio...
337
338
  	kobject_put(part->holder_dir);
  	device_del(part_to_dev(part));
6fcc44d1d   Yufen Yu   block: fix use-af...
339
340
341
342
343
344
345
  	/*
  	 * Remove gendisk pointer from idr so that it cannot be looked up
  	 * while RCU period before freeing gendisk is running to prevent
  	 * use-after-free issues. Note that the device number stays
  	 * "in-use" until we really free the gendisk.
  	 */
  	blk_invalidate_devt(part_devt(part));
4377b48da   Christoph Hellwig   block: remove hd_...
346
  	percpu_ref_kill(&part->ref);
94ea4158f   Al Viro   separate partitio...
347
348
349
350
351
352
353
  }
  
  static ssize_t whole_disk_show(struct device *dev,
  			       struct device_attribute *attr, char *buf)
  {
  	return 0;
  }
5657a819a   Joe Perches   block drivers/blo...
354
  static DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL);
94ea4158f   Al Viro   separate partitio...
355

6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
356
357
358
359
  /*
   * Must be called either with bd_mutex held, before a disk can be opened or
   * after all disk users are gone.
   */
fa9156ae5   Christoph Hellwig   block: refactor b...
360
  static struct hd_struct *add_partition(struct gendisk *disk, int partno,
94ea4158f   Al Viro   separate partitio...
361
362
363
364
365
366
367
368
369
370
  				sector_t start, sector_t len, int flags,
  				struct partition_meta_info *info)
  {
  	struct hd_struct *p;
  	dev_t devt = MKDEV(0, 0);
  	struct device *ddev = disk_to_dev(disk);
  	struct device *pdev;
  	struct disk_part_tbl *ptbl;
  	const char *dname;
  	int err;
b72053072   Christoph Hellwig   block: allow part...
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
  	/*
  	 * Partitions are not supported on zoned block devices that are used as
  	 * such.
  	 */
  	switch (disk->queue->limits.zoned) {
  	case BLK_ZONED_HM:
  		pr_warn("%s: partitions not supported on host managed zoned block device
  ",
  			disk->disk_name);
  		return ERR_PTR(-ENXIO);
  	case BLK_ZONED_HA:
  		pr_info("%s: disabling host aware zoned block device support due to partitions
  ",
  			disk->disk_name);
  		disk->queue->limits.zoned = BLK_ZONED_NONE;
  		break;
  	case BLK_ZONED_NONE:
  		break;
  	}
94ea4158f   Al Viro   separate partitio...
390
391
392
  	err = disk_expand_part_tbl(disk, partno);
  	if (err)
  		return ERR_PTR(err);
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
393
  	ptbl = rcu_dereference_protected(disk->part_tbl, 1);
94ea4158f   Al Viro   separate partitio...
394
395
396
397
398
399
400
  
  	if (ptbl->part[partno])
  		return ERR_PTR(-EBUSY);
  
  	p = kzalloc(sizeof(*p), GFP_KERNEL);
  	if (!p)
  		return ERR_PTR(-EBUSY);
58d4f14fc   Christoph Hellwig   block: always use...
401
402
  	p->dkstats = alloc_percpu(struct disk_stats);
  	if (!p->dkstats) {
94ea4158f   Al Viro   separate partitio...
403
404
405
  		err = -ENOMEM;
  		goto out_free;
  	}
c83f6bf98   Vivek Goyal   block: add partit...
406

07c4e1e83   Ming Lei   block: only defin...
407
  	hd_sects_seq_init(p);
94ea4158f   Al Viro   separate partitio...
408
409
410
  	pdev = part_to_dev(p);
  
  	p->start_sect = start;
94ea4158f   Al Viro   separate partitio...
411
412
413
414
415
  	p->nr_sects = len;
  	p->partno = partno;
  	p->policy = get_disk_ro(disk);
  
  	if (info) {
f17c21c1e   Christoph Hellwig   block: remove all...
416
417
418
  		struct partition_meta_info *pinfo;
  
  		pinfo = kzalloc_node(sizeof(*pinfo), GFP_KERNEL, disk->node_id);
7bd897cfc   Dan Carpenter   block: fix an err...
419
420
  		if (!pinfo) {
  			err = -ENOMEM;
94ea4158f   Al Viro   separate partitio...
421
  			goto out_free_stats;
7bd897cfc   Dan Carpenter   block: fix an err...
422
  		}
94ea4158f   Al Viro   separate partitio...
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
  		memcpy(pinfo, info, sizeof(*info));
  		p->info = pinfo;
  	}
  
  	dname = dev_name(ddev);
  	if (isdigit(dname[strlen(dname) - 1]))
  		dev_set_name(pdev, "%sp%d", dname, partno);
  	else
  		dev_set_name(pdev, "%s%d", dname, partno);
  
  	device_initialize(pdev);
  	pdev->class = &block_class;
  	pdev->type = &part_type;
  	pdev->parent = ddev;
  
  	err = blk_alloc_devt(p, &devt);
  	if (err)
  		goto out_free_info;
  	pdev->devt = devt;
  
  	/* delay uevent until 'holders' subdir is created */
  	dev_set_uevent_suppress(pdev, 1);
  	err = device_add(pdev);
  	if (err)
  		goto out_put;
  
  	err = -ENOMEM;
  	p->holder_dir = kobject_create_and_add("holders", &pdev->kobj);
  	if (!p->holder_dir)
  		goto out_del;
  
  	dev_set_uevent_suppress(pdev, 0);
  	if (flags & ADDPART_FLAG_WHOLEDISK) {
  		err = device_create_file(pdev, &dev_attr_whole_disk);
  		if (err)
  			goto out_del;
  	}
b30a337ca   Ming Lei   block: partition:...
460
461
462
463
464
465
  	err = hd_ref_init(p);
  	if (err) {
  		if (flags & ADDPART_FLAG_WHOLEDISK)
  			goto out_remove_file;
  		goto out_del;
  	}
94ea4158f   Al Viro   separate partitio...
466
467
468
469
470
471
  	/* everything is up and running, commence */
  	rcu_assign_pointer(ptbl->part[partno], p);
  
  	/* suppress uevent if the disk suppresses it */
  	if (!dev_get_uevent_suppress(ddev))
  		kobject_uevent(&pdev->kobj, KOBJ_ADD);
b30a337ca   Ming Lei   block: partition:...
472
  	return p;
94ea4158f   Al Viro   separate partitio...
473
474
  
  out_free_info:
f17c21c1e   Christoph Hellwig   block: remove all...
475
  	kfree(p->info);
94ea4158f   Al Viro   separate partitio...
476
  out_free_stats:
58d4f14fc   Christoph Hellwig   block: always use...
477
  	free_percpu(p->dkstats);
94ea4158f   Al Viro   separate partitio...
478
479
480
  out_free:
  	kfree(p);
  	return ERR_PTR(err);
b30a337ca   Ming Lei   block: partition:...
481
482
  out_remove_file:
  	device_remove_file(pdev, &dev_attr_whole_disk);
94ea4158f   Al Viro   separate partitio...
483
484
485
486
487
  out_del:
  	kobject_put(p->holder_dir);
  	device_del(pdev);
  out_put:
  	put_device(pdev);
94ea4158f   Al Viro   separate partitio...
488
489
  	return ERR_PTR(err);
  }
fa9156ae5   Christoph Hellwig   block: refactor b...
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  static bool partition_overlaps(struct gendisk *disk, sector_t start,
  		sector_t length, int skip_partno)
  {
  	struct disk_part_iter piter;
  	struct hd_struct *part;
  	bool overlap = false;
  
  	disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
  	while ((part = disk_part_iter_next(&piter))) {
  		if (part->partno == skip_partno ||
  		    start >= part->start_sect + part->nr_sects ||
  		    start + length <= part->start_sect)
  			continue;
  		overlap = true;
  		break;
  	}
  
  	disk_part_iter_exit(&piter);
  	return overlap;
  }
  
  int bdev_add_partition(struct block_device *bdev, int partno,
  		sector_t start, sector_t length)
  {
  	struct hd_struct *part;
  
  	mutex_lock(&bdev->bd_mutex);
  	if (partition_overlaps(bdev->bd_disk, start, length, -1)) {
  		mutex_unlock(&bdev->bd_mutex);
  		return -EBUSY;
  	}
  
  	part = add_partition(bdev->bd_disk, partno, start, length,
  			ADDPART_FLAG_NONE, NULL);
  	mutex_unlock(&bdev->bd_mutex);
  	return PTR_ERR_OR_ZERO(part);
  }
  
  int bdev_del_partition(struct block_device *bdev, int partno)
  {
  	struct block_device *bdevp;
08fc1ab6d   Christoph Hellwig   block: fix lockin...
531
532
  	struct hd_struct *part = NULL;
  	int ret;
fa9156ae5   Christoph Hellwig   block: refactor b...
533

08fc1ab6d   Christoph Hellwig   block: fix lockin...
534
  	bdevp = bdget_disk(bdev->bd_disk, partno);
fa9156ae5   Christoph Hellwig   block: refactor b...
535
  	if (!bdevp)
88ce2a530   Christoph Hellwig   block: restore a ...
536
  		return -ENXIO;
fa9156ae5   Christoph Hellwig   block: refactor b...
537
538
  
  	mutex_lock(&bdevp->bd_mutex);
08fc1ab6d   Christoph Hellwig   block: fix lockin...
539
540
541
542
543
544
  	mutex_lock_nested(&bdev->bd_mutex, 1);
  
  	ret = -ENXIO;
  	part = disk_get_part(bdev->bd_disk, partno);
  	if (!part)
  		goto out_unlock;
fa9156ae5   Christoph Hellwig   block: refactor b...
545
546
547
548
  
  	ret = -EBUSY;
  	if (bdevp->bd_openers)
  		goto out_unlock;
d5f3178ec   Christoph Hellwig   block: simplify b...
549
  	sync_blockdev(bdevp);
fa9156ae5   Christoph Hellwig   block: refactor b...
550
  	invalidate_bdev(bdevp);
8328eb283   Christoph Hellwig   block: remove the...
551
  	delete_partition(part);
fa9156ae5   Christoph Hellwig   block: refactor b...
552
553
  	ret = 0;
  out_unlock:
08fc1ab6d   Christoph Hellwig   block: fix lockin...
554
  	mutex_unlock(&bdev->bd_mutex);
fa9156ae5   Christoph Hellwig   block: refactor b...
555
556
  	mutex_unlock(&bdevp->bd_mutex);
  	bdput(bdevp);
08fc1ab6d   Christoph Hellwig   block: fix lockin...
557
558
  	if (part)
  		disk_put_part(part);
fa9156ae5   Christoph Hellwig   block: refactor b...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
  	return ret;
  }
  
  int bdev_resize_partition(struct block_device *bdev, int partno,
  		sector_t start, sector_t length)
  {
  	struct block_device *bdevp;
  	struct hd_struct *part;
  	int ret = 0;
  
  	part = disk_get_part(bdev->bd_disk, partno);
  	if (!part)
  		return -ENXIO;
  
  	ret = -ENOMEM;
10ed16662   Christoph Hellwig   block: add a bdge...
574
  	bdevp = bdget_part(part);
fa9156ae5   Christoph Hellwig   block: refactor b...
575
576
577
578
579
580
581
582
583
584
585
586
587
  	if (!bdevp)
  		goto out_put_part;
  
  	mutex_lock(&bdevp->bd_mutex);
  	mutex_lock_nested(&bdev->bd_mutex, 1);
  
  	ret = -EINVAL;
  	if (start != part->start_sect)
  		goto out_unlock;
  
  	ret = -EBUSY;
  	if (partition_overlaps(bdev->bd_disk, start, length, partno))
  		goto out_unlock;
c2b4bb8cb   Christoph Hellwig   block: fix lockin...
588
589
  	part_nr_sects_write(part, length);
  	bd_set_nr_sectors(bdevp, length);
fa9156ae5   Christoph Hellwig   block: refactor b...
590
591
592
593
594
595
596
597
598
599
  
  	ret = 0;
  out_unlock:
  	mutex_unlock(&bdevp->bd_mutex);
  	mutex_unlock(&bdev->bd_mutex);
  	bdput(bdevp);
  out_put_part:
  	disk_put_part(part);
  	return ret;
  }
94ea4158f   Al Viro   separate partitio...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
  static bool disk_unlock_native_capacity(struct gendisk *disk)
  {
  	const struct block_device_operations *bdops = disk->fops;
  
  	if (bdops->unlock_native_capacity &&
  	    !(disk->flags & GENHD_FL_NATIVE_CAPACITY)) {
  		printk(KERN_CONT "enabling native capacity
  ");
  		bdops->unlock_native_capacity(disk);
  		disk->flags |= GENHD_FL_NATIVE_CAPACITY;
  		return true;
  	} else {
  		printk(KERN_CONT "truncated
  ");
  		return false;
  	}
  }
d46430bf5   Christoph Hellwig   block: remove the...
617
  int blk_drop_partitions(struct block_device *bdev)
94ea4158f   Al Viro   separate partitio...
618
  {
94ea4158f   Al Viro   separate partitio...
619
620
  	struct disk_part_iter piter;
  	struct hd_struct *part;
94ea4158f   Al Viro   separate partitio...
621

10c70d95c   Christoph Hellwig   block: remove the...
622
  	if (bdev->bd_part_count)
94ea4158f   Al Viro   separate partitio...
623
  		return -EBUSY;
e669c1da0   Christoph Hellwig   block: don't call...
624
625
626
  
  	sync_blockdev(bdev);
  	invalidate_bdev(bdev);
94ea4158f   Al Viro   separate partitio...
627

d46430bf5   Christoph Hellwig   block: remove the...
628
  	disk_part_iter_init(&piter, bdev->bd_disk, DISK_PITER_INCL_EMPTY);
94ea4158f   Al Viro   separate partitio...
629
  	while ((part = disk_part_iter_next(&piter)))
8328eb283   Christoph Hellwig   block: remove the...
630
  		delete_partition(part);
94ea4158f   Al Viro   separate partitio...
631
  	disk_part_iter_exit(&piter);
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
632
633
  	return 0;
  }
21be6cdc0   Christoph Hellwig   dasd: use blk_dro...
634
635
636
637
  #ifdef CONFIG_S390
  /* for historic reasons in the DASD driver */
  EXPORT_SYMBOL_GPL(blk_drop_partitions);
  #endif
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
638

f902b0260   Christoph Hellwig   block: refactor r...
639
640
  static bool blk_add_partition(struct gendisk *disk, struct block_device *bdev,
  		struct parsed_partitions *state, int p)
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
641
  {
f902b0260   Christoph Hellwig   block: refactor r...
642
643
  	sector_t size = state->parts[p].size;
  	sector_t from = state->parts[p].from;
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
644
  	struct hd_struct *part;
f902b0260   Christoph Hellwig   block: refactor r...
645
646
647
648
649
650
651
652
653
654
655
  
  	if (!size)
  		return true;
  
  	if (from >= get_capacity(disk)) {
  		printk(KERN_WARNING
  		       "%s: p%d start %llu is beyond EOD, ",
  		       disk->disk_name, p, (unsigned long long) from);
  		if (disk_unlock_native_capacity(disk))
  			return false;
  		return true;
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
656
  	}
f902b0260   Christoph Hellwig   block: refactor r...
657
658
659
660
  	if (from + size > get_capacity(disk)) {
  		printk(KERN_WARNING
  		       "%s: p%d size %llu extends beyond EOD, ",
  		       disk->disk_name, p, (unsigned long long) size);
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
661

f902b0260   Christoph Hellwig   block: refactor r...
662
663
664
665
666
667
668
669
670
671
672
673
674
  		if (disk_unlock_native_capacity(disk))
  			return false;
  
  		/*
  		 * We can not ignore partitions of broken tables created by for
  		 * example camera firmware, but we limit them to the end of the
  		 * disk to avoid creating invalid block devices.
  		 */
  		size = get_capacity(disk) - from;
  	}
  
  	part = add_partition(disk, p, from, size, state->parts[p].flags,
  			     &state->parts[p].info);
b72053072   Christoph Hellwig   block: allow part...
675
  	if (IS_ERR(part) && PTR_ERR(part) != -ENXIO) {
f902b0260   Christoph Hellwig   block: refactor r...
676
677
678
679
680
  		printk(KERN_ERR " %s: p%d could not be added: %ld
  ",
  		       disk->disk_name, p, -PTR_ERR(part));
  		return true;
  	}
74cc979c3   Christoph Hellwig   block: cleanup ho...
681
682
  	if (IS_BUILTIN(CONFIG_BLK_DEV_MD) &&
  	    (state->parts[p].flags & ADDPART_FLAG_RAID))
f902b0260   Christoph Hellwig   block: refactor r...
683
  		md_autodetect_dev(part_to_dev(part)->devt);
74cc979c3   Christoph Hellwig   block: cleanup ho...
684

f902b0260   Christoph Hellwig   block: refactor r...
685
686
  	return true;
  }
a1548b674   Christoph Hellwig   block: move resca...
687
  int blk_add_partitions(struct gendisk *disk, struct block_device *bdev)
f902b0260   Christoph Hellwig   block: refactor r...
688
689
690
  {
  	struct parsed_partitions *state;
  	int ret = -EAGAIN, p, highest;
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
691

142fe8f4b   Christoph Hellwig   block: fix bdev_d...
692
693
  	if (!disk_part_scan_enabled(disk))
  		return 0;
f902b0260   Christoph Hellwig   block: refactor r...
694
695
  	state = check_partition(disk, bdev);
  	if (!state)
94ea4158f   Al Viro   separate partitio...
696
697
698
  		return 0;
  	if (IS_ERR(state)) {
  		/*
f902b0260   Christoph Hellwig   block: refactor r...
699
700
  		 * I/O error reading the partition table.  If we tried to read
  		 * beyond EOD, retry after unlocking the native capacity.
94ea4158f   Al Viro   separate partitio...
701
702
703
704
705
  		 */
  		if (PTR_ERR(state) == -ENOSPC) {
  			printk(KERN_WARNING "%s: partition table beyond EOD, ",
  			       disk->disk_name);
  			if (disk_unlock_native_capacity(disk))
f902b0260   Christoph Hellwig   block: refactor r...
706
  				return -EAGAIN;
94ea4158f   Al Viro   separate partitio...
707
708
709
  		}
  		return -EIO;
  	}
5eac3eb30   Damien Le Moal   block: Remove par...
710

f902b0260   Christoph Hellwig   block: refactor r...
711
  	/*
b72053072   Christoph Hellwig   block: allow part...
712
  	 * Partitions are not supported on host managed zoned block devices.
f902b0260   Christoph Hellwig   block: refactor r...
713
  	 */
b72053072   Christoph Hellwig   block: allow part...
714
715
716
  	if (disk->queue->limits.zoned == BLK_ZONED_HM) {
  		pr_warn("%s: ignoring partition table on host managed zoned block device
  ",
5eac3eb30   Damien Le Moal   block: Remove par...
717
  			disk->disk_name);
f902b0260   Christoph Hellwig   block: refactor r...
718
719
  		ret = 0;
  		goto out_free_state;
5eac3eb30   Damien Le Moal   block: Remove par...
720
  	}
94ea4158f   Al Viro   separate partitio...
721
  	/*
f902b0260   Christoph Hellwig   block: refactor r...
722
723
724
  	 * If we read beyond EOD, try unlocking native capacity even if the
  	 * partition table was successfully read as we could be missing some
  	 * partitions.
94ea4158f   Al Viro   separate partitio...
725
726
727
728
729
730
  	 */
  	if (state->access_beyond_eod) {
  		printk(KERN_WARNING
  		       "%s: partition table partially beyond EOD, ",
  		       disk->disk_name);
  		if (disk_unlock_native_capacity(disk))
f902b0260   Christoph Hellwig   block: refactor r...
731
  			goto out_free_state;
94ea4158f   Al Viro   separate partitio...
732
733
734
735
  	}
  
  	/* tell userspace that the media / partition table may have changed */
  	kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
f902b0260   Christoph Hellwig   block: refactor r...
736
737
738
  	/*
  	 * Detect the highest partition number and preallocate disk->part_tbl.
  	 * This is an optimization and not strictly necessary.
94ea4158f   Al Viro   separate partitio...
739
740
741
742
  	 */
  	for (p = 1, highest = 0; p < state->limit; p++)
  		if (state->parts[p].size)
  			highest = p;
94ea4158f   Al Viro   separate partitio...
743
  	disk_expand_part_tbl(disk, highest);
f902b0260   Christoph Hellwig   block: refactor r...
744
745
746
  	for (p = 1; p < state->limit; p++)
  		if (!blk_add_partition(disk, bdev, state, p))
  			goto out_free_state;
94ea4158f   Al Viro   separate partitio...
747

f902b0260   Christoph Hellwig   block: refactor r...
748
749
  	ret = 0;
  out_free_state:
ac2e5327a   Ming Lei   block/partitions:...
750
  	free_partitions(state);
f902b0260   Christoph Hellwig   block: refactor r...
751
  	return ret;
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
752
  }
1a9fba3a7   Christoph Hellwig   block: unexport r...
753
  void *read_part_sector(struct parsed_partitions *state, sector_t n, Sector *p)
d1a5f2b4d   Dan Williams   block: use DAX fo...
754
  {
1a9fba3a7   Christoph Hellwig   block: unexport r...
755
  	struct address_space *mapping = state->bdev->bd_inode->i_mapping;
94ea4158f   Al Viro   separate partitio...
756
  	struct page *page;
1a9fba3a7   Christoph Hellwig   block: unexport r...
757
758
759
  	if (n >= get_capacity(state->bdev->bd_disk)) {
  		state->access_beyond_eod = true;
  		return NULL;
94ea4158f   Al Viro   separate partitio...
760
  	}
1a9fba3a7   Christoph Hellwig   block: unexport r...
761
762
763
764
765
766
767
768
769
770
771
772
773
774
  
  	page = read_mapping_page(mapping,
  			(pgoff_t)(n >> (PAGE_SHIFT - 9)), NULL);
  	if (IS_ERR(page))
  		goto out;
  	if (PageError(page))
  		goto out_put_page;
  
  	p->v = page;
  	return (unsigned char *)page_address(page) +
  			((n & ((1 << (PAGE_SHIFT - 9)) - 1)) << SECTOR_SHIFT);
  out_put_page:
  	put_page(page);
  out:
94ea4158f   Al Viro   separate partitio...
775
776
777
  	p->v = NULL;
  	return NULL;
  }