Loading drivers/md/dm-table.c +43 −95 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ struct dm_table { * These are optimistic limits taken from all the * targets, some targets will need smaller limits. */ struct io_restrictions limits; struct queue_limits limits; /* events get handed up using this callback */ void (*event_fn)(void *); Loading @@ -88,43 +88,6 @@ static unsigned int int_log(unsigned int n, unsigned int base) return result; } /* * Returns the minimum that is _not_ zero, unless both are zero. */ #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) /* * Combine two io_restrictions, always taking the lower value. */ static void combine_restrictions_low(struct io_restrictions *lhs, struct io_restrictions *rhs) { lhs->max_sectors = min_not_zero(lhs->max_sectors, rhs->max_sectors); lhs->max_phys_segments = min_not_zero(lhs->max_phys_segments, rhs->max_phys_segments); lhs->max_hw_segments = min_not_zero(lhs->max_hw_segments, rhs->max_hw_segments); lhs->logical_block_size = max(lhs->logical_block_size, rhs->logical_block_size); lhs->max_segment_size = min_not_zero(lhs->max_segment_size, rhs->max_segment_size); lhs->max_hw_sectors = min_not_zero(lhs->max_hw_sectors, rhs->max_hw_sectors); lhs->seg_boundary_mask = min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask); lhs->bounce_pfn = min_not_zero(lhs->bounce_pfn, rhs->bounce_pfn); lhs->no_cluster |= rhs->no_cluster; } /* * Calculate the index of the child node of the n'th node k'th key. */ Loading Loading @@ -511,10 +474,14 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, return 0; } /* * Returns the minimum that is _not_ zero, unless both are zero. */ #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); struct io_restrictions *rs = &ti->limits; char b[BDEVNAME_SIZE]; if (unlikely(!q)) { Loading @@ -523,15 +490,9 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) return; } /* * Combine the device limits low. * * FIXME: if we move an io_restriction struct * into q this would just be a call to * combine_restrictions_low() */ rs->max_sectors = min_not_zero(rs->max_sectors, queue_max_sectors(q)); if (blk_stack_limits(&ti->limits, &q->limits, 0) < 0) DMWARN("%s: target device %s is misaligned", dm_device_name(ti->table->md), bdevname(bdev, b)); /* * Check if merge fn is supported. Loading @@ -540,33 +501,9 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) */ if (q->merge_bvec_fn && !ti->type->merge) rs->max_sectors = min_not_zero(rs->max_sectors, ti->limits.max_sectors = min_not_zero(ti->limits.max_sectors, (unsigned int) (PAGE_SIZE >> 9)); rs->max_phys_segments = min_not_zero(rs->max_phys_segments, queue_max_phys_segments(q)); rs->max_hw_segments = min_not_zero(rs->max_hw_segments, queue_max_hw_segments(q)); rs->logical_block_size = max(rs->logical_block_size, queue_logical_block_size(q)); rs->max_segment_size = min_not_zero(rs->max_segment_size, queue_max_segment_size(q)); rs->max_hw_sectors = min_not_zero(rs->max_hw_sectors, queue_max_hw_sectors(q)); rs->seg_boundary_mask = min_not_zero(rs->seg_boundary_mask, queue_segment_boundary(q)); rs->bounce_pfn = min_not_zero(rs->bounce_pfn, queue_bounce_pfn(q)); rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); } EXPORT_SYMBOL_GPL(dm_set_device_limits); Loading Loading @@ -704,24 +641,32 @@ int dm_split_args(int *argc, char ***argvp, char *input) return 0; } static void check_for_valid_limits(struct io_restrictions *rs) static void init_valid_queue_limits(struct queue_limits *limits) { if (!rs->max_sectors) rs->max_sectors = SAFE_MAX_SECTORS; if (!rs->max_hw_sectors) rs->max_hw_sectors = SAFE_MAX_SECTORS; if (!rs->max_phys_segments) rs->max_phys_segments = MAX_PHYS_SEGMENTS; if (!rs->max_hw_segments) rs->max_hw_segments = MAX_HW_SEGMENTS; if (!rs->logical_block_size) rs->logical_block_size = 1 << SECTOR_SHIFT; if (!rs->max_segment_size) rs->max_segment_size = MAX_SEGMENT_SIZE; if (!rs->seg_boundary_mask) rs->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; if (!rs->bounce_pfn) rs->bounce_pfn = -1; if (!limits->max_sectors) limits->max_sectors = SAFE_MAX_SECTORS; if (!limits->max_hw_sectors) limits->max_hw_sectors = SAFE_MAX_SECTORS; if (!limits->max_phys_segments) limits->max_phys_segments = MAX_PHYS_SEGMENTS; if (!limits->max_hw_segments) limits->max_hw_segments = MAX_HW_SEGMENTS; if (!limits->logical_block_size) limits->logical_block_size = 1 << SECTOR_SHIFT; if (!limits->physical_block_size) limits->physical_block_size = 1 << SECTOR_SHIFT; if (!limits->io_min) limits->io_min = 1 << SECTOR_SHIFT; if (!limits->max_segment_size) limits->max_segment_size = MAX_SEGMENT_SIZE; if (!limits->seg_boundary_mask) limits->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; if (!limits->bounce_pfn) limits->bounce_pfn = -1; /* * The other fields (alignment_offset, io_opt, misaligned) * hold 0 from the kzalloc(). */ } /* Loading Loading @@ -841,9 +786,12 @@ int dm_table_add_target(struct dm_table *t, const char *type, t->highs[t->num_targets++] = tgt->begin + tgt->len - 1; /* FIXME: the plan is to combine high here and then have * the merge fn apply the target level restrictions. */ combine_restrictions_low(&t->limits, &tgt->limits); if (blk_stack_limits(&t->limits, &tgt->limits, 0) < 0) DMWARN("%s: target device (start sect %llu len %llu) " "is misaligned", dm_device_name(t->md), (unsigned long long) tgt->begin, (unsigned long long) tgt->len); return 0; bad: Loading Loading @@ -886,7 +834,7 @@ int dm_table_complete(struct dm_table *t) int r = 0; unsigned int leaf_nodes; check_for_valid_limits(&t->limits); init_valid_queue_limits(&t->limits); r = validate_hardware_logical_block_alignment(t); if (r) Loading include/linux/device-mapper.h +2 −14 Original line number Diff line number Diff line Loading @@ -144,18 +144,6 @@ struct target_type { struct list_head list; }; struct io_restrictions { unsigned long bounce_pfn; unsigned long seg_boundary_mask; unsigned max_hw_sectors; unsigned max_sectors; unsigned max_segment_size; unsigned short logical_block_size; unsigned short max_hw_segments; unsigned short max_phys_segments; unsigned char no_cluster; /* inverted so that 0 is default */ }; struct dm_target { struct dm_table *table; struct target_type *type; Loading @@ -164,7 +152,7 @@ struct dm_target { sector_t begin; sector_t len; /* FIXME: turn this into a mask, and merge with io_restrictions */ /* FIXME: turn this into a mask, and merge with queue_limits */ /* Always a power of 2 */ sector_t split_io; Loading @@ -182,7 +170,7 @@ struct dm_target { * These are automatically filled in by * dm_table_get_device. */ struct io_restrictions limits; struct queue_limits limits; /* target specific data */ void *private; Loading Loading
drivers/md/dm-table.c +43 −95 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ struct dm_table { * These are optimistic limits taken from all the * targets, some targets will need smaller limits. */ struct io_restrictions limits; struct queue_limits limits; /* events get handed up using this callback */ void (*event_fn)(void *); Loading @@ -88,43 +88,6 @@ static unsigned int int_log(unsigned int n, unsigned int base) return result; } /* * Returns the minimum that is _not_ zero, unless both are zero. */ #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) /* * Combine two io_restrictions, always taking the lower value. */ static void combine_restrictions_low(struct io_restrictions *lhs, struct io_restrictions *rhs) { lhs->max_sectors = min_not_zero(lhs->max_sectors, rhs->max_sectors); lhs->max_phys_segments = min_not_zero(lhs->max_phys_segments, rhs->max_phys_segments); lhs->max_hw_segments = min_not_zero(lhs->max_hw_segments, rhs->max_hw_segments); lhs->logical_block_size = max(lhs->logical_block_size, rhs->logical_block_size); lhs->max_segment_size = min_not_zero(lhs->max_segment_size, rhs->max_segment_size); lhs->max_hw_sectors = min_not_zero(lhs->max_hw_sectors, rhs->max_hw_sectors); lhs->seg_boundary_mask = min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask); lhs->bounce_pfn = min_not_zero(lhs->bounce_pfn, rhs->bounce_pfn); lhs->no_cluster |= rhs->no_cluster; } /* * Calculate the index of the child node of the n'th node k'th key. */ Loading Loading @@ -511,10 +474,14 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, return 0; } /* * Returns the minimum that is _not_ zero, unless both are zero. */ #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); struct io_restrictions *rs = &ti->limits; char b[BDEVNAME_SIZE]; if (unlikely(!q)) { Loading @@ -523,15 +490,9 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) return; } /* * Combine the device limits low. * * FIXME: if we move an io_restriction struct * into q this would just be a call to * combine_restrictions_low() */ rs->max_sectors = min_not_zero(rs->max_sectors, queue_max_sectors(q)); if (blk_stack_limits(&ti->limits, &q->limits, 0) < 0) DMWARN("%s: target device %s is misaligned", dm_device_name(ti->table->md), bdevname(bdev, b)); /* * Check if merge fn is supported. Loading @@ -540,33 +501,9 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) */ if (q->merge_bvec_fn && !ti->type->merge) rs->max_sectors = min_not_zero(rs->max_sectors, ti->limits.max_sectors = min_not_zero(ti->limits.max_sectors, (unsigned int) (PAGE_SIZE >> 9)); rs->max_phys_segments = min_not_zero(rs->max_phys_segments, queue_max_phys_segments(q)); rs->max_hw_segments = min_not_zero(rs->max_hw_segments, queue_max_hw_segments(q)); rs->logical_block_size = max(rs->logical_block_size, queue_logical_block_size(q)); rs->max_segment_size = min_not_zero(rs->max_segment_size, queue_max_segment_size(q)); rs->max_hw_sectors = min_not_zero(rs->max_hw_sectors, queue_max_hw_sectors(q)); rs->seg_boundary_mask = min_not_zero(rs->seg_boundary_mask, queue_segment_boundary(q)); rs->bounce_pfn = min_not_zero(rs->bounce_pfn, queue_bounce_pfn(q)); rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); } EXPORT_SYMBOL_GPL(dm_set_device_limits); Loading Loading @@ -704,24 +641,32 @@ int dm_split_args(int *argc, char ***argvp, char *input) return 0; } static void check_for_valid_limits(struct io_restrictions *rs) static void init_valid_queue_limits(struct queue_limits *limits) { if (!rs->max_sectors) rs->max_sectors = SAFE_MAX_SECTORS; if (!rs->max_hw_sectors) rs->max_hw_sectors = SAFE_MAX_SECTORS; if (!rs->max_phys_segments) rs->max_phys_segments = MAX_PHYS_SEGMENTS; if (!rs->max_hw_segments) rs->max_hw_segments = MAX_HW_SEGMENTS; if (!rs->logical_block_size) rs->logical_block_size = 1 << SECTOR_SHIFT; if (!rs->max_segment_size) rs->max_segment_size = MAX_SEGMENT_SIZE; if (!rs->seg_boundary_mask) rs->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; if (!rs->bounce_pfn) rs->bounce_pfn = -1; if (!limits->max_sectors) limits->max_sectors = SAFE_MAX_SECTORS; if (!limits->max_hw_sectors) limits->max_hw_sectors = SAFE_MAX_SECTORS; if (!limits->max_phys_segments) limits->max_phys_segments = MAX_PHYS_SEGMENTS; if (!limits->max_hw_segments) limits->max_hw_segments = MAX_HW_SEGMENTS; if (!limits->logical_block_size) limits->logical_block_size = 1 << SECTOR_SHIFT; if (!limits->physical_block_size) limits->physical_block_size = 1 << SECTOR_SHIFT; if (!limits->io_min) limits->io_min = 1 << SECTOR_SHIFT; if (!limits->max_segment_size) limits->max_segment_size = MAX_SEGMENT_SIZE; if (!limits->seg_boundary_mask) limits->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; if (!limits->bounce_pfn) limits->bounce_pfn = -1; /* * The other fields (alignment_offset, io_opt, misaligned) * hold 0 from the kzalloc(). */ } /* Loading Loading @@ -841,9 +786,12 @@ int dm_table_add_target(struct dm_table *t, const char *type, t->highs[t->num_targets++] = tgt->begin + tgt->len - 1; /* FIXME: the plan is to combine high here and then have * the merge fn apply the target level restrictions. */ combine_restrictions_low(&t->limits, &tgt->limits); if (blk_stack_limits(&t->limits, &tgt->limits, 0) < 0) DMWARN("%s: target device (start sect %llu len %llu) " "is misaligned", dm_device_name(t->md), (unsigned long long) tgt->begin, (unsigned long long) tgt->len); return 0; bad: Loading Loading @@ -886,7 +834,7 @@ int dm_table_complete(struct dm_table *t) int r = 0; unsigned int leaf_nodes; check_for_valid_limits(&t->limits); init_valid_queue_limits(&t->limits); r = validate_hardware_logical_block_alignment(t); if (r) Loading
include/linux/device-mapper.h +2 −14 Original line number Diff line number Diff line Loading @@ -144,18 +144,6 @@ struct target_type { struct list_head list; }; struct io_restrictions { unsigned long bounce_pfn; unsigned long seg_boundary_mask; unsigned max_hw_sectors; unsigned max_sectors; unsigned max_segment_size; unsigned short logical_block_size; unsigned short max_hw_segments; unsigned short max_phys_segments; unsigned char no_cluster; /* inverted so that 0 is default */ }; struct dm_target { struct dm_table *table; struct target_type *type; Loading @@ -164,7 +152,7 @@ struct dm_target { sector_t begin; sector_t len; /* FIXME: turn this into a mask, and merge with io_restrictions */ /* FIXME: turn this into a mask, and merge with queue_limits */ /* Always a power of 2 */ sector_t split_io; Loading @@ -182,7 +170,7 @@ struct dm_target { * These are automatically filled in by * dm_table_get_device. */ struct io_restrictions limits; struct queue_limits limits; /* target specific data */ void *private; Loading