Blame view
block/partition-generic.c
17.4 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
94ea4158f 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); |
9c0fb1e31 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 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 block: add partit... |
94 95 |
return sprintf(buf, "%llu ",(unsigned long long)part_nr_sects_read(p)); |
94ea4158f 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 block: fix a cras... |
126 |
struct request_queue *q = part_to_disk(p)->queue; |
e016b7820 block: return jus... |
127 |
unsigned int inflight; |
94ea4158f separate partitio... |
128 |
|
e016b7820 block: return jus... |
129 |
inflight = part_in_flight(q, p); |
94ea4158f separate partitio... |
130 131 132 |
return sprintf(buf, "%8lu %8lu %8llu %8u " "%8lu %8lu %8llu %8u " |
bdca3c87f block: Track DISC... |
133 134 |
"%8u %8u %8u " "%8lu %8lu %8llu %8u" |
94ea4158f separate partitio... |
135 136 |
" ", |
dbae2c551 block: Define and... |
137 138 139 |
part_stat_read(p, ios[STAT_READ]), part_stat_read(p, merges[STAT_READ]), (unsigned long long)part_stat_read(p, sectors[STAT_READ]), |
b57e99b4b block: use nanose... |
140 |
(unsigned int)part_stat_read_msecs(p, STAT_READ), |
dbae2c551 block: Define and... |
141 142 143 |
part_stat_read(p, ios[STAT_WRITE]), part_stat_read(p, merges[STAT_WRITE]), (unsigned long long)part_stat_read(p, sectors[STAT_WRITE]), |
b57e99b4b block: use nanose... |
144 |
(unsigned int)part_stat_read_msecs(p, STAT_WRITE), |
e016b7820 block: return jus... |
145 |
inflight, |
94ea4158f separate partitio... |
146 |
jiffies_to_msecs(part_stat_read(p, io_ticks)), |
bdca3c87f block: Track DISC... |
147 148 149 150 |
jiffies_to_msecs(part_stat_read(p, time_in_queue)), part_stat_read(p, ios[STAT_DISCARD]), part_stat_read(p, merges[STAT_DISCARD]), (unsigned long long)part_stat_read(p, sectors[STAT_DISCARD]), |
b57e99b4b block: use nanose... |
151 |
(unsigned int)part_stat_read_msecs(p, STAT_DISCARD)); |
94ea4158f separate partitio... |
152 |
} |
bf0ddaba6 blk-mq: fix sysfs... |
153 154 |
ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr, char *buf) |
94ea4158f separate partitio... |
155 156 |
{ struct hd_struct *p = dev_to_part(dev); |
bf0ddaba6 blk-mq: fix sysfs... |
157 158 |
struct request_queue *q = part_to_disk(p)->queue; unsigned int inflight[2]; |
94ea4158f separate partitio... |
159 |
|
bf0ddaba6 blk-mq: fix sysfs... |
160 161 162 |
part_in_flight_rw(q, p, inflight); return sprintf(buf, "%8u %8u ", inflight[0], inflight[1]); |
94ea4158f separate partitio... |
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 |
} #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 |
5657a819a block drivers/blo... |
188 189 190 191 192 193 194 195 |
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 separate partitio... |
196 197 |
#ifdef CONFIG_FAIL_MAKE_REQUEST static struct device_attribute dev_attr_fail = |
5657a819a block drivers/blo... |
198 |
__ATTR(make-it-fail, 0644, part_fail_show, part_fail_store); |
94ea4158f separate partitio... |
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 |
#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 block: Fix dev_t ... |
231 |
blk_free_devt(dev->devt); |
b54e5ed8f block: partition:... |
232 |
hd_free_part(p); |
94ea4158f separate partitio... |
233 234 |
kfree(p); } |
0d9c51a6e block: partition:... |
235 236 237 238 239 240 241 242 243 |
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 separate partitio... |
244 245 246 247 |
struct device_type part_type = { .name = "partition", .groups = part_attr_groups, .release = part_release, |
0d9c51a6e block: partition:... |
248 |
.uevent = part_uevent, |
94ea4158f separate partitio... |
249 |
}; |
94a2c3a32 block: use rcu_wo... |
250 |
static void delete_partition_work_fn(struct work_struct *work) |
94ea4158f separate partitio... |
251 |
{ |
94a2c3a32 block: use rcu_wo... |
252 253 |
struct hd_struct *part = container_of(to_rcu_work(work), struct hd_struct, rcu_work); |
94ea4158f separate partitio... |
254 255 256 257 258 259 |
part->start_sect = 0; part->nr_sects = 0; part_stat_set_all(part, 0); put_device(part_to_dev(part)); } |
6c71013ec block: partition:... |
260 |
void __delete_partition(struct percpu_ref *ref) |
94ea4158f separate partitio... |
261 |
{ |
6c71013ec block: partition:... |
262 |
struct hd_struct *part = container_of(ref, struct hd_struct, ref); |
94a2c3a32 block: use rcu_wo... |
263 264 |
INIT_RCU_WORK(&part->rcu_work, delete_partition_work_fn); queue_rcu_work(system_wq, &part->rcu_work); |
94ea4158f separate partitio... |
265 |
} |
6d2cf6f2b 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 separate partitio... |
270 271 |
void delete_partition(struct gendisk *disk, int partno) { |
6d2cf6f2b genhd: Annotate a... |
272 273 |
struct disk_part_tbl *ptbl = rcu_dereference_protected(disk->part_tbl, 1); |
94ea4158f separate partitio... |
274 275 276 277 |
struct hd_struct *part; if (partno >= ptbl->len) return; |
6d2cf6f2b genhd: Annotate a... |
278 |
part = rcu_dereference_protected(ptbl->part[partno], 1); |
94ea4158f separate partitio... |
279 280 |
if (!part) return; |
94ea4158f 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)); |
6fcc44d1d block: fix use-af... |
285 286 287 288 289 290 291 |
/* * 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)); |
6c71013ec block: partition:... |
292 |
hd_struct_kill(part); |
94ea4158f separate partitio... |
293 294 295 296 297 298 299 |
} static ssize_t whole_disk_show(struct device *dev, struct device_attribute *attr, char *buf) { return 0; } |
5657a819a block drivers/blo... |
300 |
static DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL); |
94ea4158f separate partitio... |
301 |
|
6d2cf6f2b genhd: Annotate a... |
302 303 304 305 |
/* * Must be called either with bd_mutex held, before a disk can be opened or * after all disk users are gone. */ |
94ea4158f separate partitio... |
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
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 genhd: Annotate a... |
321 |
ptbl = rcu_dereference_protected(disk->part_tbl, 1); |
94ea4158f separate partitio... |
322 323 324 325 326 327 328 329 330 331 332 333 |
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 block: add partit... |
334 335 |
seqcount_init(&p->nr_sects_seq); |
94ea4158f separate partitio... |
336 337 338 339 340 341 342 343 344 345 346 347 348 |
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 block: fix an err... |
349 350 |
if (!pinfo) { err = -ENOMEM; |
94ea4158f separate partitio... |
351 |
goto out_free_stats; |
7bd897cfc block: fix an err... |
352 |
} |
94ea4158f separate partitio... |
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 383 384 385 386 387 388 389 |
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 block: partition:... |
390 391 392 393 394 395 |
err = hd_ref_init(p); if (err) { if (flags & ADDPART_FLAG_WHOLEDISK) goto out_remove_file; goto out_del; } |
94ea4158f separate partitio... |
396 397 398 399 400 401 |
/* 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 block: partition:... |
402 |
return p; |
94ea4158f separate partitio... |
403 404 405 406 407 408 409 410 |
out_free_info: free_part_info(p); out_free_stats: free_part_stats(p); out_free: kfree(p); return ERR_PTR(err); |
b30a337ca block: partition:... |
411 412 |
out_remove_file: device_remove_file(pdev, &dev_attr_whole_disk); |
94ea4158f separate partitio... |
413 414 415 416 417 |
out_del: kobject_put(p->holder_dir); device_del(pdev); out_put: put_device(pdev); |
94ea4158f separate partitio... |
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
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 block: Fix NULL p... |
438 |
static int drop_partitions(struct gendisk *disk, struct block_device *bdev) |
94ea4158f separate partitio... |
439 |
{ |
94ea4158f separate partitio... |
440 441 |
struct disk_part_iter piter; struct hd_struct *part; |
fe316bf2d block: Fix NULL p... |
442 |
int res; |
94ea4158f separate partitio... |
443 |
|
77032ca66 Return EBUSY from... |
444 |
if (bdev->bd_part_count || bdev->bd_super) |
94ea4158f separate partitio... |
445 446 447 448 449 450 451 452 453 |
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 block: Fix NULL p... |
454 455 |
return 0; } |
b02d8aaea block: Check part... |
456 457 458 459 |
static bool part_zone_aligned(struct gendisk *disk, struct block_device *bdev, sector_t from, sector_t size) { |
f99e86485 block: Rename blk... |
460 |
unsigned int zone_sectors = bdev_zone_sectors(bdev); |
b02d8aaea block: Check part... |
461 462 463 464 465 466 467 468 469 470 471 |
/* * 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 block: Rename blk... |
472 |
if (!zone_sectors) |
b02d8aaea block: Check part... |
473 474 475 476 477 478 479 480 |
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 block: Rename blk... |
481 |
if (WARN_ON_ONCE(!is_power_of_2(zone_sectors))) { |
b02d8aaea block: Check part... |
482 |
u32 rem; |
f99e86485 block: Rename blk... |
483 |
div_u64_rem(from, zone_sectors, &rem); |
b02d8aaea block: Check part... |
484 485 486 |
if (rem) return false; if ((from + size) < get_capacity(disk)) { |
f99e86485 block: Rename blk... |
487 |
div_u64_rem(size, zone_sectors, &rem); |
b02d8aaea block: Check part... |
488 489 490 491 492 |
if (rem) return false; } } else { |
f99e86485 block: Rename blk... |
493 |
if (from & (zone_sectors - 1)) |
b02d8aaea block: Check part... |
494 495 |
return false; if ((from + size) < get_capacity(disk) && |
f99e86485 block: Rename blk... |
496 |
(size & (zone_sectors - 1))) |
b02d8aaea block: Check part... |
497 498 499 500 501 502 |
return false; } return true; } |
fe316bf2d block: Fix NULL p... |
503 504 505 506 507 508 509 |
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 block/partitions:... |
510 |
free_partitions(state); |
fe316bf2d block: Fix NULL p... |
511 512 513 514 515 516 |
state = NULL; } res = drop_partitions(disk, bdev); if (res) return res; |
94ea4158f separate partitio... |
517 518 |
if (disk->fops->revalidate_disk) disk->fops->revalidate_disk(disk); |
5afb78356 block: don't prin... |
519 |
check_disk_size_change(disk, bdev, true); |
94ea4158f separate partitio... |
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 559 560 561 562 563 564 565 |
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 separate partitio... |
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 592 593 594 595 596 597 598 |
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 block: Check part... |
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
/* * 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 separate partitio... |
614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
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 block/partitions:... |
628 |
free_partitions(state); |
94ea4158f separate partitio... |
629 630 |
return 0; } |
fe316bf2d block: Fix NULL p... |
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); |
5afb78356 block: don't prin... |
643 |
check_disk_size_change(disk, bdev, false); |
fe316bf2d block: Fix NULL p... |
644 645 646 647 648 649 |
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 block: use DAX fo... |
650 651 |
unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) { |
a41fe02b6 Revert "block: us... |
652 |
struct address_space *mapping = bdev->bd_inode->i_mapping; |
94ea4158f separate partitio... |
653 |
struct page *page; |
a41fe02b6 Revert "block: us... |
654 |
page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_SHIFT-9)), NULL); |
94ea4158f separate partitio... |
655 656 657 658 |
if (!IS_ERR(page)) { if (PageError(page)) goto fail; p->v = page; |
09cbfeaf1 mm, fs: get rid o... |
659 |
return (unsigned char *)page_address(page) + ((n & ((1 << (PAGE_SHIFT - 9)) - 1)) << 9); |
94ea4158f separate partitio... |
660 |
fail: |
09cbfeaf1 mm, fs: get rid o... |
661 |
put_page(page); |
94ea4158f separate partitio... |
662 663 664 665 666 667 |
} p->v = NULL; return NULL; } EXPORT_SYMBOL(read_dev_sector); |