aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/jbd/commit.c2
-rw-r--r--fs/jbd2/commit.c2
-rw-r--r--fs/partitions/check.c35
-rw-r--r--fs/partitions/check.h3
-rw-r--r--fs/partitions/efi.c25
5 files changed, 62 insertions, 5 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 95d8c11c929e..3f030e9efea6 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -318,7 +318,7 @@ void journal_commit_transaction(journal_t *journal)
318 int first_tag = 0; 318 int first_tag = 0;
319 int tag_flag; 319 int tag_flag;
320 int i; 320 int i;
321 int write_op = WRITE; 321 int write_op = WRITE_SYNC;
322 322
323 /* 323 /*
324 * First job: lock down the current transaction and wait for 324 * First job: lock down the current transaction and wait for
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 7c068c189d80..80910f51d4b4 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -360,7 +360,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
360 int tag_bytes = journal_tag_bytes(journal); 360 int tag_bytes = journal_tag_bytes(journal);
361 struct buffer_head *cbh = NULL; /* For transactional checksums */ 361 struct buffer_head *cbh = NULL; /* For transactional checksums */
362 __u32 crc32_sum = ~0; 362 __u32 crc32_sum = ~0;
363 int write_op = WRITE; 363 int write_op = WRITE_SYNC;
364 364
365 /* 365 /*
366 * First job: lock down the current transaction and wait for 366 * First job: lock down the current transaction and wait for
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 79fbf3f390f0..30f46c2cb9d5 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -352,6 +352,7 @@ static void part_release(struct device *dev)
352{ 352{
353 struct hd_struct *p = dev_to_part(dev); 353 struct hd_struct *p = dev_to_part(dev);
354 free_part_stats(p); 354 free_part_stats(p);
355 free_part_info(p);
355 kfree(p); 356 kfree(p);
356} 357}
357 358
@@ -364,17 +365,25 @@ struct device_type part_type = {
364static void delete_partition_rcu_cb(struct rcu_head *head) 365static void delete_partition_rcu_cb(struct rcu_head *head)
365{ 366{
366 struct hd_struct *part = container_of(head, struct hd_struct, rcu_head); 367 struct hd_struct *part = container_of(head, struct hd_struct, rcu_head);
368 struct gendisk *disk = part_to_disk(part);
369 struct request_queue *q = disk->queue;
370 unsigned long flags;
367 371
368 part->start_sect = 0; 372 part->start_sect = 0;
369 part->nr_sects = 0; 373 part->nr_sects = 0;
370 part_stat_set_all(part, 0); 374 part_stat_set_all(part, 0);
371 put_device(part_to_dev(part)); 375 put_device(part_to_dev(part));
376
377 spin_lock_irqsave(q->queue_lock, flags);
378 elv_quiesce_end(q);
379 spin_unlock_irqrestore(q->queue_lock, flags);
372} 380}
373 381
374void delete_partition(struct gendisk *disk, int partno) 382void delete_partition(struct gendisk *disk, int partno)
375{ 383{
376 struct disk_part_tbl *ptbl = disk->part_tbl; 384 struct disk_part_tbl *ptbl = disk->part_tbl;
377 struct hd_struct *part; 385 struct hd_struct *part;
386 struct request_queue *q = disk->queue;
378 387
379 if (partno >= ptbl->len) 388 if (partno >= ptbl->len)
380 return; 389 return;
@@ -389,6 +398,10 @@ void delete_partition(struct gendisk *disk, int partno)
389 kobject_put(part->holder_dir); 398 kobject_put(part->holder_dir);
390 device_del(part_to_dev(part)); 399 device_del(part_to_dev(part));
391 400
401 spin_lock_irq(q->queue_lock);
402 elv_quiesce_start(q);
403 spin_unlock_irq(q->queue_lock);
404
392 call_rcu(&part->rcu_head, delete_partition_rcu_cb); 405 call_rcu(&part->rcu_head, delete_partition_rcu_cb);
393} 406}
394 407
@@ -401,7 +414,8 @@ static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH,
401 whole_disk_show, NULL); 414 whole_disk_show, NULL);
402 415
403struct hd_struct *add_partition(struct gendisk *disk, int partno, 416struct hd_struct *add_partition(struct gendisk *disk, int partno,
404 sector_t start, sector_t len, int flags) 417 sector_t start, sector_t len, int flags,
418 struct partition_meta_info *info)
405{ 419{
406 struct hd_struct *p; 420 struct hd_struct *p;
407 dev_t devt = MKDEV(0, 0); 421 dev_t devt = MKDEV(0, 0);
@@ -438,6 +452,14 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
438 p->partno = partno; 452 p->partno = partno;
439 p->policy = get_disk_ro(disk); 453 p->policy = get_disk_ro(disk);
440 454
455 if (info) {
456 struct partition_meta_info *pinfo = alloc_part_info(disk);
457 if (!pinfo)
458 goto out_free_stats;
459 memcpy(pinfo, info, sizeof(*info));
460 p->info = pinfo;
461 }
462
441 dname = dev_name(ddev); 463 dname = dev_name(ddev);
442 if (isdigit(dname[strlen(dname) - 1])) 464 if (isdigit(dname[strlen(dname) - 1]))
443 dev_set_name(pdev, "%sp%d", dname, partno); 465 dev_set_name(pdev, "%sp%d", dname, partno);
@@ -451,7 +473,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
451 473
452 err = blk_alloc_devt(p, &devt); 474 err = blk_alloc_devt(p, &devt);
453 if (err) 475 if (err)
454 goto out_free_stats; 476 goto out_free_info;
455 pdev->devt = devt; 477 pdev->devt = devt;
456 478
457 /* delay uevent until 'holders' subdir is created */ 479 /* delay uevent until 'holders' subdir is created */
@@ -481,6 +503,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
481 503
482 return p; 504 return p;
483 505
506out_free_info:
507 free_part_info(p);
484out_free_stats: 508out_free_stats:
485 free_part_stats(p); 509 free_part_stats(p);
486out_free: 510out_free:
@@ -642,6 +666,7 @@ rescan:
642 /* add partitions */ 666 /* add partitions */
643 for (p = 1; p < state->limit; p++) { 667 for (p = 1; p < state->limit; p++) {
644 sector_t size, from; 668 sector_t size, from;
669 struct partition_meta_info *info = NULL;
645 670
646 size = state->parts[p].size; 671 size = state->parts[p].size;
647 if (!size) 672 if (!size)
@@ -675,8 +700,12 @@ rescan:
675 size = get_capacity(disk) - from; 700 size = get_capacity(disk) - from;
676 } 701 }
677 } 702 }
703
704 if (state->parts[p].has_info)
705 info = &state->parts[p].info;
678 part = add_partition(disk, p, from, size, 706 part = add_partition(disk, p, from, size,
679 state->parts[p].flags); 707 state->parts[p].flags,
708 &state->parts[p].info);
680 if (IS_ERR(part)) { 709 if (IS_ERR(part)) {
681 printk(KERN_ERR " %s: p%d could not be added: %ld\n", 710 printk(KERN_ERR " %s: p%d could not be added: %ld\n",
682 disk->disk_name, p, -PTR_ERR(part)); 711 disk->disk_name, p, -PTR_ERR(part));
diff --git a/fs/partitions/check.h b/fs/partitions/check.h
index 8e4e103ba216..d68bf4dc3bc2 100644
--- a/fs/partitions/check.h
+++ b/fs/partitions/check.h
@@ -1,5 +1,6 @@
1#include <linux/pagemap.h> 1#include <linux/pagemap.h>
2#include <linux/blkdev.h> 2#include <linux/blkdev.h>
3#include <linux/genhd.h>
3 4
4/* 5/*
5 * add_gd_partition adds a partitions details to the devices partition 6 * add_gd_partition adds a partitions details to the devices partition
@@ -12,6 +13,8 @@ struct parsed_partitions {
12 sector_t from; 13 sector_t from;
13 sector_t size; 14 sector_t size;
14 int flags; 15 int flags;
16 bool has_info;
17 struct partition_meta_info info;
15 } parts[DISK_MAX_PARTS]; 18 } parts[DISK_MAX_PARTS];
16 int next; 19 int next;
17 int limit; 20 int limit;
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
index dbb44d4bb8a7..ac0ccb5026a2 100644
--- a/fs/partitions/efi.c
+++ b/fs/partitions/efi.c
@@ -94,6 +94,7 @@
94 * 94 *
95 ************************************************************/ 95 ************************************************************/
96#include <linux/crc32.h> 96#include <linux/crc32.h>
97#include <linux/ctype.h>
97#include <linux/math64.h> 98#include <linux/math64.h>
98#include <linux/slab.h> 99#include <linux/slab.h>
99#include "check.h" 100#include "check.h"
@@ -604,6 +605,7 @@ int efi_partition(struct parsed_partitions *state)
604 gpt_entry *ptes = NULL; 605 gpt_entry *ptes = NULL;
605 u32 i; 606 u32 i;
606 unsigned ssz = bdev_logical_block_size(state->bdev) / 512; 607 unsigned ssz = bdev_logical_block_size(state->bdev) / 512;
608 u8 unparsed_guid[37];
607 609
608 if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { 610 if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
609 kfree(gpt); 611 kfree(gpt);
@@ -614,6 +616,9 @@ int efi_partition(struct parsed_partitions *state)
614 pr_debug("GUID Partition Table is valid! Yea!\n"); 616 pr_debug("GUID Partition Table is valid! Yea!\n");
615 617
616 for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { 618 for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
619 struct partition_meta_info *info;
620 unsigned label_count = 0;
621 unsigned label_max;
617 u64 start = le64_to_cpu(ptes[i].starting_lba); 622 u64 start = le64_to_cpu(ptes[i].starting_lba);
618 u64 size = le64_to_cpu(ptes[i].ending_lba) - 623 u64 size = le64_to_cpu(ptes[i].ending_lba) -
619 le64_to_cpu(ptes[i].starting_lba) + 1ULL; 624 le64_to_cpu(ptes[i].starting_lba) + 1ULL;
@@ -627,6 +632,26 @@ int efi_partition(struct parsed_partitions *state)
627 if (!efi_guidcmp(ptes[i].partition_type_guid, 632 if (!efi_guidcmp(ptes[i].partition_type_guid,
628 PARTITION_LINUX_RAID_GUID)) 633 PARTITION_LINUX_RAID_GUID))
629 state->parts[i + 1].flags = ADDPART_FLAG_RAID; 634 state->parts[i + 1].flags = ADDPART_FLAG_RAID;
635
636 info = &state->parts[i + 1].info;
637 /* Instead of doing a manual swap to big endian, reuse the
638 * common ASCII hex format as the interim.
639 */
640 efi_guid_unparse(&ptes[i].unique_partition_guid, unparsed_guid);
641 part_pack_uuid(unparsed_guid, info->uuid);
642
643 /* Naively convert UTF16-LE to 7 bits. */
644 label_max = min(sizeof(info->volname) - 1,
645 sizeof(ptes[i].partition_name));
646 info->volname[label_max] = 0;
647 while (label_count < label_max) {
648 u8 c = ptes[i].partition_name[label_count] & 0xff;
649 if (c && !isprint(c))
650 c = '!';
651 info->volname[label_count] = c;
652 label_count++;
653 }
654 state->parts[i + 1].has_info = true;
630 } 655 }
631 kfree(ptes); 656 kfree(ptes);
632 kfree(gpt); 657 kfree(gpt);