Blame view

block/partition-generic.c 17 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
94ea4158f   Al Viro   separate partitio...
2
3
4
5
6
7
8
9
10
11
12
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
  /*
   *  Code extracted from drivers/block/genhd.c
   *  Copyright (C) 1991-1998  Linus Torvalds
   *  Re-organised Feb 1998 Russell King
   *
   *  We now have independent partition support from the
   *  block drivers, which allows all the partition code to
   *  be grouped in one location, and it to be mostly self
   *  contained.
   */
  
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/fs.h>
  #include <linux/slab.h>
  #include <linux/kmod.h>
  #include <linux/ctype.h>
  #include <linux/genhd.h>
  #include <linux/blktrace_api.h>
  
  #include "partitions/check.h"
  
  #ifdef CONFIG_BLK_DEV_MD
  extern void md_autodetect_dev(dev_t dev);
  #endif
   
  /*
   * disk_name() is used by partition check code and the genhd driver.
   * It formats the devicename of the indicated disk into
   * the supplied buffer (of size at least 32), and returns
   * a pointer to that same buffer (for convenience).
   */
  
  char *disk_name(struct gendisk *hd, int partno, char *buf)
  {
  	if (!partno)
  		snprintf(buf, BDEVNAME_SIZE, "%s", hd->disk_name);
  	else if (isdigit(hd->disk_name[strlen(hd->disk_name)-1]))
  		snprintf(buf, BDEVNAME_SIZE, "%sp%d", hd->disk_name, partno);
  	else
  		snprintf(buf, BDEVNAME_SIZE, "%s%d", hd->disk_name, partno);
  
  	return buf;
  }
  
  const char *bdevname(struct block_device *bdev, char *buf)
  {
  	return disk_name(bdev->bd_disk, bdev->bd_part->partno, buf);
  }
  
  EXPORT_SYMBOL(bdevname);
3c84b5aaf   Jiufei Xue   block: display th...
53
54
55
56
57
  const char *bio_devname(struct bio *bio, char *buf)
  {
  	return disk_name(bio->bi_disk, bio->bi_partno, buf);
  }
  EXPORT_SYMBOL(bio_devname);
94ea4158f   Al Viro   separate partitio...
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
  /*
   * There's very little reason to use this, you should really
   * have a struct block_device just about everywhere and use
   * bdevname() instead.
   */
  const char *__bdevname(dev_t dev, char *buffer)
  {
  	scnprintf(buffer, BDEVNAME_SIZE, "unknown-block(%u,%u)",
  				MAJOR(dev), MINOR(dev));
  	return buffer;
  }
  
  EXPORT_SYMBOL(__bdevname);
  
  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);
  }
  
  ssize_t part_size_show(struct device *dev,
  		       struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
c83f6bf98   Vivek Goyal   block: add partit...
94
95
  	return sprintf(buf, "%llu
  ",(unsigned long long)part_nr_sects_read(p));
94ea4158f   Al Viro   separate partitio...
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
  }
  
  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);
  	return sprintf(buf, "%llu
  ", (unsigned long long)p->alignment_offset);
  }
  
  static ssize_t part_discard_alignment_show(struct device *dev,
  					   struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
  	return sprintf(buf, "%u
  ", p->discard_alignment);
  }
  
  ssize_t part_stat_show(struct device *dev,
  		       struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
f5c156c4c   Shaohua Li   block: fix a cras...
126
  	struct request_queue *q = part_to_disk(p)->queue;
0609e0efc   Jens Axboe   block: make part_...
127
  	unsigned int inflight[2];
94ea4158f   Al Viro   separate partitio...
128
129
130
  	int cpu;
  
  	cpu = part_stat_lock();
d62e26b3f   Jens Axboe   block: pass in qu...
131
  	part_round_stats(q, cpu, p);
94ea4158f   Al Viro   separate partitio...
132
  	part_stat_unlock();
0609e0efc   Jens Axboe   block: make part_...
133
  	part_in_flight(q, p, inflight);
94ea4158f   Al Viro   separate partitio...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  	return sprintf(buf,
  		"%8lu %8lu %8llu %8u "
  		"%8lu %8lu %8llu %8u "
  		"%8u %8u %8u"
  		"
  ",
  		part_stat_read(p, ios[READ]),
  		part_stat_read(p, merges[READ]),
  		(unsigned long long)part_stat_read(p, sectors[READ]),
  		jiffies_to_msecs(part_stat_read(p, ticks[READ])),
  		part_stat_read(p, ios[WRITE]),
  		part_stat_read(p, merges[WRITE]),
  		(unsigned long long)part_stat_read(p, sectors[WRITE]),
  		jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
0609e0efc   Jens Axboe   block: make part_...
148
  		inflight[0],
94ea4158f   Al Viro   separate partitio...
149
150
151
  		jiffies_to_msecs(part_stat_read(p, io_ticks)),
  		jiffies_to_msecs(part_stat_read(p, time_in_queue)));
  }
06beec871   Omar Sandoval   blk-mq: fix sysfs...
152
153
  ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr,
  			   char *buf)
94ea4158f   Al Viro   separate partitio...
154
155
  {
  	struct hd_struct *p = dev_to_part(dev);
06beec871   Omar Sandoval   blk-mq: fix sysfs...
156
157
  	struct request_queue *q = part_to_disk(p)->queue;
  	unsigned int inflight[2];
94ea4158f   Al Viro   separate partitio...
158

06beec871   Omar Sandoval   blk-mq: fix sysfs...
159
160
161
  	part_in_flight_rw(q, p, inflight);
  	return sprintf(buf, "%8u %8u
  ", inflight[0], inflight[1]);
94ea4158f   Al Viro   separate partitio...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  }
  
  #ifdef CONFIG_FAIL_MAKE_REQUEST
  ssize_t part_fail_show(struct device *dev,
  		       struct device_attribute *attr, char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
  
  	return sprintf(buf, "%d
  ", p->make_it_fail);
  }
  
  ssize_t part_fail_store(struct device *dev,
  			struct device_attribute *attr,
  			const char *buf, size_t count)
  {
  	struct hd_struct *p = dev_to_part(dev);
  	int i;
  
  	if (count > 0 && sscanf(buf, "%d", &i) > 0)
  		p->make_it_fail = (i == 0) ? 0 : 1;
  
  	return count;
  }
  #endif
  
  static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL);
  static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
  static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
  static DEVICE_ATTR(ro, S_IRUGO, part_ro_show, NULL);
  static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL);
  static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show,
  		   NULL);
  static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
  static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
  #ifdef CONFIG_FAIL_MAKE_REQUEST
  static struct device_attribute dev_attr_fail =
  	__ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
  #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 ...
232
  	blk_free_devt(dev->devt);
b54e5ed8f   Ming Lei   block: partition:...
233
  	hd_free_part(p);
94ea4158f   Al Viro   separate partitio...
234
235
  	kfree(p);
  }
0d9c51a6e   San Mehat   block: partition:...
236
237
238
239
240
241
242
243
244
  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...
245
246
247
248
  struct device_type part_type = {
  	.name		= "partition",
  	.groups		= part_attr_groups,
  	.release	= part_release,
0d9c51a6e   San Mehat   block: partition:...
249
  	.uevent		= part_uevent,
94ea4158f   Al Viro   separate partitio...
250
251
252
253
254
255
256
257
258
259
260
  };
  
  static void delete_partition_rcu_cb(struct rcu_head *head)
  {
  	struct hd_struct *part = container_of(head, struct hd_struct, rcu_head);
  
  	part->start_sect = 0;
  	part->nr_sects = 0;
  	part_stat_set_all(part, 0);
  	put_device(part_to_dev(part));
  }
6c71013ec   Ming Lei   block: partition:...
261
  void __delete_partition(struct percpu_ref *ref)
94ea4158f   Al Viro   separate partitio...
262
  {
6c71013ec   Ming Lei   block: partition:...
263
  	struct hd_struct *part = container_of(ref, struct hd_struct, ref);
94ea4158f   Al Viro   separate partitio...
264
265
  	call_rcu(&part->rcu_head, delete_partition_rcu_cb);
  }
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
266
267
268
269
  /*
   * Must be called either with bd_mutex held, before a disk can be opened or
   * after all disk users are gone.
   */
94ea4158f   Al Viro   separate partitio...
270
271
  void delete_partition(struct gendisk *disk, int partno)
  {
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
272
273
  	struct disk_part_tbl *ptbl =
  		rcu_dereference_protected(disk->part_tbl, 1);
94ea4158f   Al Viro   separate partitio...
274
275
276
277
  	struct hd_struct *part;
  
  	if (partno >= ptbl->len)
  		return;
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
278
  	part = rcu_dereference_protected(ptbl->part[partno], 1);
94ea4158f   Al Viro   separate partitio...
279
280
  	if (!part)
  		return;
94ea4158f   Al Viro   separate partitio...
281
282
283
284
  	rcu_assign_pointer(ptbl->part[partno], NULL);
  	rcu_assign_pointer(ptbl->last_lookup, NULL);
  	kobject_put(part->holder_dir);
  	device_del(part_to_dev(part));
6c71013ec   Ming Lei   block: partition:...
285
  	hd_struct_kill(part);
94ea4158f   Al Viro   separate partitio...
286
287
288
289
290
291
292
293
294
  }
  
  static ssize_t whole_disk_show(struct device *dev,
  			       struct device_attribute *attr, char *buf)
  {
  	return 0;
  }
  static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH,
  		   whole_disk_show, NULL);
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
295
296
297
298
  /*
   * Must be called either with bd_mutex held, before a disk can be opened or
   * after all disk users are gone.
   */
94ea4158f   Al Viro   separate partitio...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
  struct hd_struct *add_partition(struct gendisk *disk, int partno,
  				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;
  
  	err = disk_expand_part_tbl(disk, partno);
  	if (err)
  		return ERR_PTR(err);
6d2cf6f2b   Bart Van Assche   genhd: Annotate a...
314
  	ptbl = rcu_dereference_protected(disk->part_tbl, 1);
94ea4158f   Al Viro   separate partitio...
315
316
317
318
319
320
321
322
323
324
325
326
  
  	if (ptbl->part[partno])
  		return ERR_PTR(-EBUSY);
  
  	p = kzalloc(sizeof(*p), GFP_KERNEL);
  	if (!p)
  		return ERR_PTR(-EBUSY);
  
  	if (!init_part_stats(p)) {
  		err = -ENOMEM;
  		goto out_free;
  	}
c83f6bf98   Vivek Goyal   block: add partit...
327
328
  
  	seqcount_init(&p->nr_sects_seq);
94ea4158f   Al Viro   separate partitio...
329
330
331
332
333
334
335
336
337
338
339
340
341
  	pdev = part_to_dev(p);
  
  	p->start_sect = start;
  	p->alignment_offset =
  		queue_limit_alignment_offset(&disk->queue->limits, start);
  	p->discard_alignment =
  		queue_limit_discard_alignment(&disk->queue->limits, start);
  	p->nr_sects = len;
  	p->partno = partno;
  	p->policy = get_disk_ro(disk);
  
  	if (info) {
  		struct partition_meta_info *pinfo = alloc_part_info(disk);
7bd897cfc   Dan Carpenter   block: fix an err...
342
343
  		if (!pinfo) {
  			err = -ENOMEM;
94ea4158f   Al Viro   separate partitio...
344
  			goto out_free_stats;
7bd897cfc   Dan Carpenter   block: fix an err...
345
  		}
94ea4158f   Al Viro   separate partitio...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
  		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:...
383
384
385
386
387
388
  	err = hd_ref_init(p);
  	if (err) {
  		if (flags & ADDPART_FLAG_WHOLEDISK)
  			goto out_remove_file;
  		goto out_del;
  	}
94ea4158f   Al Viro   separate partitio...
389
390
391
392
393
394
  	/* 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:...
395
  	return p;
94ea4158f   Al Viro   separate partitio...
396
397
398
399
400
401
402
403
  
  out_free_info:
  	free_part_info(p);
  out_free_stats:
  	free_part_stats(p);
  out_free:
  	kfree(p);
  	return ERR_PTR(err);
b30a337ca   Ming Lei   block: partition:...
404
405
  out_remove_file:
  	device_remove_file(pdev, &dev_attr_whole_disk);
94ea4158f   Al Viro   separate partitio...
406
407
408
409
410
  out_del:
  	kobject_put(p->holder_dir);
  	device_del(pdev);
  out_put:
  	put_device(pdev);
94ea4158f   Al Viro   separate partitio...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
  	return ERR_PTR(err);
  }
  
  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;
  	}
  }
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
431
  static int drop_partitions(struct gendisk *disk, struct block_device *bdev)
94ea4158f   Al Viro   separate partitio...
432
  {
94ea4158f   Al Viro   separate partitio...
433
434
  	struct disk_part_iter piter;
  	struct hd_struct *part;
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
435
  	int res;
94ea4158f   Al Viro   separate partitio...
436

77032ca66   Eric Sandeen   Return EBUSY from...
437
  	if (bdev->bd_part_count || bdev->bd_super)
94ea4158f   Al Viro   separate partitio...
438
439
440
441
442
443
444
445
446
  		return -EBUSY;
  	res = invalidate_partition(disk, 0);
  	if (res)
  		return res;
  
  	disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
  	while ((part = disk_part_iter_next(&piter)))
  		delete_partition(disk, part->partno);
  	disk_part_iter_exit(&piter);
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
447
448
  	return 0;
  }
b02d8aaea   Damien Le Moal   block: Check part...
449
450
451
452
  static bool part_zone_aligned(struct gendisk *disk,
  			      struct block_device *bdev,
  			      sector_t from, sector_t size)
  {
f99e86485   Damien Le Moal   block: Rename blk...
453
  	unsigned int zone_sectors = bdev_zone_sectors(bdev);
b02d8aaea   Damien Le Moal   block: Check part...
454
455
456
457
458
459
460
461
462
463
464
  
  	/*
  	 * If this function is called, then the disk is a zoned block device
  	 * (host-aware or host-managed). This can be detected even if the
  	 * zoned block device support is disabled (CONFIG_BLK_DEV_ZONED not
  	 * set). In this case, however, only host-aware devices will be seen
  	 * as a block device is not created for host-managed devices. Without
  	 * zoned block device support, host-aware drives can still be used as
  	 * regular block devices (no zone operation) and their zone size will
  	 * be reported as 0. Allow this case.
  	 */
f99e86485   Damien Le Moal   block: Rename blk...
465
  	if (!zone_sectors)
b02d8aaea   Damien Le Moal   block: Check part...
466
467
468
469
470
471
472
473
  		return true;
  
  	/*
  	 * Check partition start and size alignement. If the drive has a
  	 * smaller last runt zone, ignore it and allow the partition to
  	 * use it. Check the zone size too: it should be a power of 2 number
  	 * of sectors.
  	 */
f99e86485   Damien Le Moal   block: Rename blk...
474
  	if (WARN_ON_ONCE(!is_power_of_2(zone_sectors))) {
b02d8aaea   Damien Le Moal   block: Check part...
475
  		u32 rem;
f99e86485   Damien Le Moal   block: Rename blk...
476
  		div_u64_rem(from, zone_sectors, &rem);
b02d8aaea   Damien Le Moal   block: Check part...
477
478
479
  		if (rem)
  			return false;
  		if ((from + size) < get_capacity(disk)) {
f99e86485   Damien Le Moal   block: Rename blk...
480
  			div_u64_rem(size, zone_sectors, &rem);
b02d8aaea   Damien Le Moal   block: Check part...
481
482
483
484
485
  			if (rem)
  				return false;
  		}
  
  	} else {
f99e86485   Damien Le Moal   block: Rename blk...
486
  		if (from & (zone_sectors - 1))
b02d8aaea   Damien Le Moal   block: Check part...
487
488
  			return false;
  		if ((from + size) < get_capacity(disk) &&
f99e86485   Damien Le Moal   block: Rename blk...
489
  		    (size & (zone_sectors - 1)))
b02d8aaea   Damien Le Moal   block: Check part...
490
491
492
493
494
495
  			return false;
  
  	}
  
  	return true;
  }
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
496
497
498
499
500
501
502
  int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
  {
  	struct parsed_partitions *state = NULL;
  	struct hd_struct *part;
  	int p, highest, res;
  rescan:
  	if (state && !IS_ERR(state)) {
ac2e5327a   Ming Lei   block/partitions:...
503
  		free_partitions(state);
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
504
505
506
507
508
509
  		state = NULL;
  	}
  
  	res = drop_partitions(disk, bdev);
  	if (res)
  		return res;
94ea4158f   Al Viro   separate partitio...
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
  	if (disk->fops->revalidate_disk)
  		disk->fops->revalidate_disk(disk);
  	check_disk_size_change(disk, bdev);
  	bdev->bd_invalidated = 0;
  	if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
  		return 0;
  	if (IS_ERR(state)) {
  		/*
  		 * I/O error reading the partition table.  If any
  		 * partition code tried to read beyond EOD, retry
  		 * after unlocking native capacity.
  		 */
  		if (PTR_ERR(state) == -ENOSPC) {
  			printk(KERN_WARNING "%s: partition table beyond EOD, ",
  			       disk->disk_name);
  			if (disk_unlock_native_capacity(disk))
  				goto rescan;
  		}
  		return -EIO;
  	}
  	/*
  	 * If any partition code tried to read beyond EOD, try
  	 * unlocking native capacity even if partition table is
  	 * successfully read as we could be missing some partitions.
  	 */
  	if (state->access_beyond_eod) {
  		printk(KERN_WARNING
  		       "%s: partition table partially beyond EOD, ",
  		       disk->disk_name);
  		if (disk_unlock_native_capacity(disk))
  			goto rescan;
  	}
  
  	/* tell userspace that the media / partition table may have changed */
  	kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
  
  	/* Detect the highest partition number and preallocate
  	 * disk->part_tbl.  This is an optimization and not strictly
  	 * necessary.
  	 */
  	for (p = 1, highest = 0; p < state->limit; p++)
  		if (state->parts[p].size)
  			highest = p;
  
  	disk_expand_part_tbl(disk, highest);
  
  	/* add partitions */
  	for (p = 1; p < state->limit; p++) {
  		sector_t size, from;
94ea4158f   Al Viro   separate partitio...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
  
  		size = state->parts[p].size;
  		if (!size)
  			continue;
  
  		from = state->parts[p].from;
  		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))
  				goto rescan;
  			continue;
  		}
  
  		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);
  
  			if (disk_unlock_native_capacity(disk)) {
  				/* free state and restart */
  				goto rescan;
  			} else {
  				/*
  				 * 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;
  			}
  		}
b02d8aaea   Damien Le Moal   block: Check part...
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
  		/*
  		 * On a zoned block device, partitions should be aligned on the
  		 * device zone size (i.e. zone boundary crossing not allowed).
  		 * Otherwise, resetting the write pointer of the last zone of
  		 * one partition may impact the following partition.
  		 */
  		if (bdev_is_zoned(bdev) &&
  		    !part_zone_aligned(disk, bdev, from, size)) {
  			printk(KERN_WARNING
  			       "%s: p%d start %llu+%llu is not zone aligned
  ",
  			       disk->disk_name, p, (unsigned long long) from,
  			       (unsigned long long) size);
  			continue;
  		}
94ea4158f   Al Viro   separate partitio...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
  		part = add_partition(disk, p, from, size,
  				     state->parts[p].flags,
  				     &state->parts[p].info);
  		if (IS_ERR(part)) {
  			printk(KERN_ERR " %s: p%d could not be added: %ld
  ",
  			       disk->disk_name, p, -PTR_ERR(part));
  			continue;
  		}
  #ifdef CONFIG_BLK_DEV_MD
  		if (state->parts[p].flags & ADDPART_FLAG_RAID)
  			md_autodetect_dev(part_to_dev(part)->devt);
  #endif
  	}
ac2e5327a   Ming Lei   block/partitions:...
621
  	free_partitions(state);
94ea4158f   Al Viro   separate partitio...
622
623
  	return 0;
  }
fe316bf2d   Jun'ichi Nomura   block: Fix NULL p...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
  int invalidate_partitions(struct gendisk *disk, struct block_device *bdev)
  {
  	int res;
  
  	if (!bdev->bd_invalidated)
  		return 0;
  
  	res = drop_partitions(disk, bdev);
  	if (res)
  		return res;
  
  	set_capacity(disk, 0);
  	check_disk_size_change(disk, bdev);
  	bdev->bd_invalidated = 0;
  	/* tell userspace that the media / partition table may have changed */
  	kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
  
  	return 0;
  }
d1a5f2b4d   Dan Williams   block: use DAX fo...
643
644
  unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
  {
a41fe02b6   Dan Williams   Revert "block: us...
645
  	struct address_space *mapping = bdev->bd_inode->i_mapping;
94ea4158f   Al Viro   separate partitio...
646
  	struct page *page;
a41fe02b6   Dan Williams   Revert "block: us...
647
  	page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_SHIFT-9)), NULL);
94ea4158f   Al Viro   separate partitio...
648
649
650
651
  	if (!IS_ERR(page)) {
  		if (PageError(page))
  			goto fail;
  		p->v = page;
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
652
  		return (unsigned char *)page_address(page) +  ((n & ((1 << (PAGE_SHIFT - 9)) - 1)) << 9);
94ea4158f   Al Viro   separate partitio...
653
  fail:
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
654
  		put_page(page);
94ea4158f   Al Viro   separate partitio...
655
656
657
658
659
660
  	}
  	p->v = NULL;
  	return NULL;
  }
  
  EXPORT_SYMBOL(read_dev_sector);