diff options
| -rw-r--r-- | drivers/md/dm-bufio.c | 12 | ||||
| -rw-r--r-- | drivers/md/dm-raid.c | 17 | ||||
| -rw-r--r-- | drivers/md/dm-stripe.c | 4 | ||||
| -rw-r--r-- | drivers/md/dm-thin.c | 16 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-btree-internal.h | 6 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-btree-spine.c | 2 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-btree.c | 24 | ||||
| -rw-r--r-- | kernel/audit.c | 2 | ||||
| -rw-r--r-- | kernel/audit_tree.c | 1 |
9 files changed, 52 insertions, 32 deletions
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 825ca1f87639..afe79719ea32 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
| @@ -1434,9 +1434,9 @@ static void drop_buffers(struct dm_bufio_client *c) | |||
| 1434 | 1434 | ||
| 1435 | /* | 1435 | /* |
| 1436 | * Test if the buffer is unused and too old, and commit it. | 1436 | * Test if the buffer is unused and too old, and commit it. |
| 1437 | * At if noio is set, we must not do any I/O because we hold | 1437 | * And if GFP_NOFS is used, we must not do any I/O because we hold |
| 1438 | * dm_bufio_clients_lock and we would risk deadlock if the I/O gets rerouted to | 1438 | * dm_bufio_clients_lock and we would risk deadlock if the I/O gets |
| 1439 | * different bufio client. | 1439 | * rerouted to different bufio client. |
| 1440 | */ | 1440 | */ |
| 1441 | static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp, | 1441 | static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp, |
| 1442 | unsigned long max_jiffies) | 1442 | unsigned long max_jiffies) |
| @@ -1444,7 +1444,7 @@ static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp, | |||
| 1444 | if (jiffies - b->last_accessed < max_jiffies) | 1444 | if (jiffies - b->last_accessed < max_jiffies) |
| 1445 | return 0; | 1445 | return 0; |
| 1446 | 1446 | ||
| 1447 | if (!(gfp & __GFP_IO)) { | 1447 | if (!(gfp & __GFP_FS)) { |
| 1448 | if (test_bit(B_READING, &b->state) || | 1448 | if (test_bit(B_READING, &b->state) || |
| 1449 | test_bit(B_WRITING, &b->state) || | 1449 | test_bit(B_WRITING, &b->state) || |
| 1450 | test_bit(B_DIRTY, &b->state)) | 1450 | test_bit(B_DIRTY, &b->state)) |
| @@ -1486,7 +1486,7 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | |||
| 1486 | unsigned long freed; | 1486 | unsigned long freed; |
| 1487 | 1487 | ||
| 1488 | c = container_of(shrink, struct dm_bufio_client, shrinker); | 1488 | c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1489 | if (sc->gfp_mask & __GFP_IO) | 1489 | if (sc->gfp_mask & __GFP_FS) |
| 1490 | dm_bufio_lock(c); | 1490 | dm_bufio_lock(c); |
| 1491 | else if (!dm_bufio_trylock(c)) | 1491 | else if (!dm_bufio_trylock(c)) |
| 1492 | return SHRINK_STOP; | 1492 | return SHRINK_STOP; |
| @@ -1503,7 +1503,7 @@ dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) | |||
| 1503 | unsigned long count; | 1503 | unsigned long count; |
| 1504 | 1504 | ||
| 1505 | c = container_of(shrink, struct dm_bufio_client, shrinker); | 1505 | c = container_of(shrink, struct dm_bufio_client, shrinker); |
| 1506 | if (sc->gfp_mask & __GFP_IO) | 1506 | if (sc->gfp_mask & __GFP_FS) |
| 1507 | dm_bufio_lock(c); | 1507 | dm_bufio_lock(c); |
| 1508 | else if (!dm_bufio_trylock(c)) | 1508 | else if (!dm_bufio_trylock(c)) |
| 1509 | return 0; | 1509 | return 0; |
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 4857fa4a5484..07c0fa0fa284 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
| @@ -789,8 +789,7 @@ struct dm_raid_superblock { | |||
| 789 | __le32 layout; | 789 | __le32 layout; |
| 790 | __le32 stripe_sectors; | 790 | __le32 stripe_sectors; |
| 791 | 791 | ||
| 792 | __u8 pad[452]; /* Round struct to 512 bytes. */ | 792 | /* Remainder of a logical block is zero-filled when writing (see super_sync()). */ |
| 793 | /* Always set to 0 when writing. */ | ||
| 794 | } __packed; | 793 | } __packed; |
| 795 | 794 | ||
| 796 | static int read_disk_sb(struct md_rdev *rdev, int size) | 795 | static int read_disk_sb(struct md_rdev *rdev, int size) |
| @@ -827,7 +826,7 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev) | |||
| 827 | test_bit(Faulty, &(rs->dev[i].rdev.flags))) | 826 | test_bit(Faulty, &(rs->dev[i].rdev.flags))) |
| 828 | failed_devices |= (1ULL << i); | 827 | failed_devices |= (1ULL << i); |
| 829 | 828 | ||
| 830 | memset(sb, 0, sizeof(*sb)); | 829 | memset(sb + 1, 0, rdev->sb_size - sizeof(*sb)); |
| 831 | 830 | ||
| 832 | sb->magic = cpu_to_le32(DM_RAID_MAGIC); | 831 | sb->magic = cpu_to_le32(DM_RAID_MAGIC); |
| 833 | sb->features = cpu_to_le32(0); /* No features yet */ | 832 | sb->features = cpu_to_le32(0); /* No features yet */ |
| @@ -862,7 +861,11 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev) | |||
| 862 | uint64_t events_sb, events_refsb; | 861 | uint64_t events_sb, events_refsb; |
| 863 | 862 | ||
| 864 | rdev->sb_start = 0; | 863 | rdev->sb_start = 0; |
| 865 | rdev->sb_size = sizeof(*sb); | 864 | rdev->sb_size = bdev_logical_block_size(rdev->meta_bdev); |
| 865 | if (rdev->sb_size < sizeof(*sb) || rdev->sb_size > PAGE_SIZE) { | ||
| 866 | DMERR("superblock size of a logical block is no longer valid"); | ||
| 867 | return -EINVAL; | ||
| 868 | } | ||
| 866 | 869 | ||
| 867 | ret = read_disk_sb(rdev, rdev->sb_size); | 870 | ret = read_disk_sb(rdev, rdev->sb_size); |
| 868 | if (ret) | 871 | if (ret) |
| @@ -1169,8 +1172,12 @@ static void configure_discard_support(struct dm_target *ti, struct raid_set *rs) | |||
| 1169 | raid456 = (rs->md.level == 4 || rs->md.level == 5 || rs->md.level == 6); | 1172 | raid456 = (rs->md.level == 4 || rs->md.level == 5 || rs->md.level == 6); |
| 1170 | 1173 | ||
| 1171 | for (i = 0; i < rs->md.raid_disks; i++) { | 1174 | for (i = 0; i < rs->md.raid_disks; i++) { |
| 1172 | struct request_queue *q = bdev_get_queue(rs->dev[i].rdev.bdev); | 1175 | struct request_queue *q; |
| 1176 | |||
| 1177 | if (!rs->dev[i].rdev.bdev) | ||
| 1178 | continue; | ||
| 1173 | 1179 | ||
| 1180 | q = bdev_get_queue(rs->dev[i].rdev.bdev); | ||
| 1174 | if (!q || !blk_queue_discard(q)) | 1181 | if (!q || !blk_queue_discard(q)) |
| 1175 | return; | 1182 | return; |
| 1176 | 1183 | ||
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index d1600d2aa2e2..f8b37d4c05d8 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
| @@ -159,8 +159,10 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 159 | sc->stripes_shift = __ffs(stripes); | 159 | sc->stripes_shift = __ffs(stripes); |
| 160 | 160 | ||
| 161 | r = dm_set_target_max_io_len(ti, chunk_size); | 161 | r = dm_set_target_max_io_len(ti, chunk_size); |
| 162 | if (r) | 162 | if (r) { |
| 163 | kfree(sc); | ||
| 163 | return r; | 164 | return r; |
| 165 | } | ||
| 164 | 166 | ||
| 165 | ti->num_flush_bios = stripes; | 167 | ti->num_flush_bios = stripes; |
| 166 | ti->num_discard_bios = stripes; | 168 | ti->num_discard_bios = stripes; |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 4843801173fe..0f86d802b533 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -1936,6 +1936,14 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1936 | return DM_MAPIO_SUBMITTED; | 1936 | return DM_MAPIO_SUBMITTED; |
| 1937 | } | 1937 | } |
| 1938 | 1938 | ||
| 1939 | /* | ||
| 1940 | * We must hold the virtual cell before doing the lookup, otherwise | ||
| 1941 | * there's a race with discard. | ||
| 1942 | */ | ||
| 1943 | build_virtual_key(tc->td, block, &key); | ||
| 1944 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result)) | ||
| 1945 | return DM_MAPIO_SUBMITTED; | ||
| 1946 | |||
| 1939 | r = dm_thin_find_block(td, block, 0, &result); | 1947 | r = dm_thin_find_block(td, block, 0, &result); |
| 1940 | 1948 | ||
| 1941 | /* | 1949 | /* |
| @@ -1959,13 +1967,10 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1959 | * shared flag will be set in their case. | 1967 | * shared flag will be set in their case. |
| 1960 | */ | 1968 | */ |
| 1961 | thin_defer_bio(tc, bio); | 1969 | thin_defer_bio(tc, bio); |
| 1970 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 1962 | return DM_MAPIO_SUBMITTED; | 1971 | return DM_MAPIO_SUBMITTED; |
| 1963 | } | 1972 | } |
| 1964 | 1973 | ||
| 1965 | build_virtual_key(tc->td, block, &key); | ||
| 1966 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result)) | ||
| 1967 | return DM_MAPIO_SUBMITTED; | ||
| 1968 | |||
| 1969 | build_data_key(tc->td, result.block, &key); | 1974 | build_data_key(tc->td, result.block, &key); |
| 1970 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) { | 1975 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) { |
| 1971 | cell_defer_no_holder_no_free(tc, &cell1); | 1976 | cell_defer_no_holder_no_free(tc, &cell1); |
| @@ -1986,6 +1991,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1986 | * of doing so. | 1991 | * of doing so. |
| 1987 | */ | 1992 | */ |
| 1988 | handle_unserviceable_bio(tc->pool, bio); | 1993 | handle_unserviceable_bio(tc->pool, bio); |
| 1994 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 1989 | return DM_MAPIO_SUBMITTED; | 1995 | return DM_MAPIO_SUBMITTED; |
| 1990 | } | 1996 | } |
| 1991 | /* fall through */ | 1997 | /* fall through */ |
| @@ -1996,6 +2002,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1996 | * provide the hint to load the metadata into cache. | 2002 | * provide the hint to load the metadata into cache. |
| 1997 | */ | 2003 | */ |
| 1998 | thin_defer_bio(tc, bio); | 2004 | thin_defer_bio(tc, bio); |
| 2005 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 1999 | return DM_MAPIO_SUBMITTED; | 2006 | return DM_MAPIO_SUBMITTED; |
| 2000 | 2007 | ||
| 2001 | default: | 2008 | default: |
| @@ -2005,6 +2012,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 2005 | * pool is switched to fail-io mode. | 2012 | * pool is switched to fail-io mode. |
| 2006 | */ | 2013 | */ |
| 2007 | bio_io_error(bio); | 2014 | bio_io_error(bio); |
| 2015 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 2008 | return DM_MAPIO_SUBMITTED; | 2016 | return DM_MAPIO_SUBMITTED; |
| 2009 | } | 2017 | } |
| 2010 | } | 2018 | } |
diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/persistent-data/dm-btree-internal.h index 37d367bb9aa8..bf2b80d5c470 100644 --- a/drivers/md/persistent-data/dm-btree-internal.h +++ b/drivers/md/persistent-data/dm-btree-internal.h | |||
| @@ -42,6 +42,12 @@ struct btree_node { | |||
| 42 | } __packed; | 42 | } __packed; |
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | /* | ||
| 46 | * Locks a block using the btree node validator. | ||
| 47 | */ | ||
| 48 | int bn_read_lock(struct dm_btree_info *info, dm_block_t b, | ||
| 49 | struct dm_block **result); | ||
| 50 | |||
| 45 | void inc_children(struct dm_transaction_manager *tm, struct btree_node *n, | 51 | void inc_children(struct dm_transaction_manager *tm, struct btree_node *n, |
| 46 | struct dm_btree_value_type *vt); | 52 | struct dm_btree_value_type *vt); |
| 47 | 53 | ||
diff --git a/drivers/md/persistent-data/dm-btree-spine.c b/drivers/md/persistent-data/dm-btree-spine.c index cf9fd676ae44..1b5e13ec7f96 100644 --- a/drivers/md/persistent-data/dm-btree-spine.c +++ b/drivers/md/persistent-data/dm-btree-spine.c | |||
| @@ -92,7 +92,7 @@ struct dm_block_validator btree_node_validator = { | |||
| 92 | 92 | ||
| 93 | /*----------------------------------------------------------------*/ | 93 | /*----------------------------------------------------------------*/ |
| 94 | 94 | ||
| 95 | static int bn_read_lock(struct dm_btree_info *info, dm_block_t b, | 95 | int bn_read_lock(struct dm_btree_info *info, dm_block_t b, |
| 96 | struct dm_block **result) | 96 | struct dm_block **result) |
| 97 | { | 97 | { |
| 98 | return dm_tm_read_lock(info->tm, b, &btree_node_validator, result); | 98 | return dm_tm_read_lock(info->tm, b, &btree_node_validator, result); |
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c index 416060c25709..200ac12a1d40 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c | |||
| @@ -847,22 +847,26 @@ EXPORT_SYMBOL_GPL(dm_btree_find_lowest_key); | |||
| 847 | * FIXME: We shouldn't use a recursive algorithm when we have limited stack | 847 | * FIXME: We shouldn't use a recursive algorithm when we have limited stack |
| 848 | * space. Also this only works for single level trees. | 848 | * space. Also this only works for single level trees. |
| 849 | */ | 849 | */ |
| 850 | static int walk_node(struct ro_spine *s, dm_block_t block, | 850 | static int walk_node(struct dm_btree_info *info, dm_block_t block, |
| 851 | int (*fn)(void *context, uint64_t *keys, void *leaf), | 851 | int (*fn)(void *context, uint64_t *keys, void *leaf), |
| 852 | void *context) | 852 | void *context) |
| 853 | { | 853 | { |
| 854 | int r; | 854 | int r; |
| 855 | unsigned i, nr; | 855 | unsigned i, nr; |
| 856 | struct dm_block *node; | ||
| 856 | struct btree_node *n; | 857 | struct btree_node *n; |
| 857 | uint64_t keys; | 858 | uint64_t keys; |
| 858 | 859 | ||
| 859 | r = ro_step(s, block); | 860 | r = bn_read_lock(info, block, &node); |
| 860 | n = ro_node(s); | 861 | if (r) |
| 862 | return r; | ||
| 863 | |||
| 864 | n = dm_block_data(node); | ||
| 861 | 865 | ||
| 862 | nr = le32_to_cpu(n->header.nr_entries); | 866 | nr = le32_to_cpu(n->header.nr_entries); |
| 863 | for (i = 0; i < nr; i++) { | 867 | for (i = 0; i < nr; i++) { |
| 864 | if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) { | 868 | if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) { |
| 865 | r = walk_node(s, value64(n, i), fn, context); | 869 | r = walk_node(info, value64(n, i), fn, context); |
| 866 | if (r) | 870 | if (r) |
| 867 | goto out; | 871 | goto out; |
| 868 | } else { | 872 | } else { |
| @@ -874,7 +878,7 @@ static int walk_node(struct ro_spine *s, dm_block_t block, | |||
| 874 | } | 878 | } |
| 875 | 879 | ||
| 876 | out: | 880 | out: |
| 877 | ro_pop(s); | 881 | dm_tm_unlock(info->tm, node); |
| 878 | return r; | 882 | return r; |
| 879 | } | 883 | } |
| 880 | 884 | ||
| @@ -882,15 +886,7 @@ int dm_btree_walk(struct dm_btree_info *info, dm_block_t root, | |||
| 882 | int (*fn)(void *context, uint64_t *keys, void *leaf), | 886 | int (*fn)(void *context, uint64_t *keys, void *leaf), |
| 883 | void *context) | 887 | void *context) |
| 884 | { | 888 | { |
| 885 | int r; | ||
| 886 | struct ro_spine spine; | ||
| 887 | |||
| 888 | BUG_ON(info->levels > 1); | 889 | BUG_ON(info->levels > 1); |
| 889 | 890 | return walk_node(info, root, fn, context); | |
| 890 | init_ro_spine(&spine, info); | ||
| 891 | r = walk_node(&spine, root, fn, context); | ||
| 892 | exit_ro_spine(&spine); | ||
| 893 | |||
| 894 | return r; | ||
| 895 | } | 891 | } |
| 896 | EXPORT_SYMBOL_GPL(dm_btree_walk); | 892 | EXPORT_SYMBOL_GPL(dm_btree_walk); |
diff --git a/kernel/audit.c b/kernel/audit.c index 80983df92cd4..cebb11db4d34 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -739,7 +739,7 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature | |||
| 739 | 739 | ||
| 740 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); | 740 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); |
| 741 | audit_log_task_info(ab, current); | 741 | audit_log_task_info(ab, current); |
| 742 | audit_log_format(ab, "feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", | 742 | audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", |
| 743 | audit_feature_names[which], !!old_feature, !!new_feature, | 743 | audit_feature_names[which], !!old_feature, !!new_feature, |
| 744 | !!old_lock, !!new_lock, res); | 744 | !!old_lock, !!new_lock, res); |
| 745 | audit_log_end(ab); | 745 | audit_log_end(ab); |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index e242e3a9864a..80f29e015570 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
| @@ -154,6 +154,7 @@ static struct audit_chunk *alloc_chunk(int count) | |||
| 154 | chunk->owners[i].index = i; | 154 | chunk->owners[i].index = i; |
| 155 | } | 155 | } |
| 156 | fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch); | 156 | fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch); |
| 157 | chunk->mark.mask = FS_IN_IGNORED; | ||
| 157 | return chunk; | 158 | return chunk; |
| 158 | } | 159 | } |
| 159 | 160 | ||
