@@ -161,15 +161,6 @@ static void part_in_flight_rw(struct block_device *part,
161161 inflight [1 ] = 0 ;
162162}
163163
164- static struct block_device * __disk_get_part (struct gendisk * disk , int partno )
165- {
166- struct disk_part_tbl * ptbl = rcu_dereference (disk -> part_tbl );
167-
168- if (unlikely (partno < 0 || partno >= ptbl -> len ))
169- return NULL ;
170- return rcu_dereference (ptbl -> part [partno ]);
171- }
172-
173164/**
174165 * disk_part_iter_init - initialize partition iterator
175166 * @piter: iterator to initialize
@@ -204,41 +195,26 @@ void disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
204195 */
205196struct block_device * disk_part_iter_next (struct disk_part_iter * piter )
206197{
207- struct disk_part_tbl * ptbl ;
198+ struct block_device * part ;
199+ unsigned long idx ;
208200
209201 /* put the last partition */
210202 disk_part_iter_exit (piter );
211203
212- /* get part_tbl */
213204 rcu_read_lock ();
214- ptbl = rcu_dereference (piter -> disk -> part_tbl );
215-
216- /* iterate to the next partition */
217- for (; piter -> idx != ptbl -> len ; piter -> idx += 1 ) {
218- struct block_device * part ;
219-
220- part = rcu_dereference (ptbl -> part [piter -> idx ]);
221- if (!part )
222- continue ;
223- piter -> part = bdgrab (part );
224- if (!piter -> part )
225- continue ;
205+ xa_for_each_start (& piter -> disk -> part_tbl , idx , part , piter -> idx ) {
226206 if (!bdev_nr_sectors (part ) &&
227207 !(piter -> flags & DISK_PITER_INCL_EMPTY ) &&
228208 !(piter -> flags & DISK_PITER_INCL_EMPTY_PART0 &&
229- piter -> idx == 0 )) {
230- bdput (piter -> part );
231- piter -> part = NULL ;
209+ piter -> idx == 0 ))
232210 continue ;
233- }
234211
235212 piter -> part = bdgrab (part );
236213 if (!piter -> part )
237214 continue ;
238- piter -> idx += 1 ;
215+ piter -> idx = idx + 1 ;
239216 break ;
240217 }
241-
242218 rcu_read_unlock ();
243219
244220 return piter -> part ;
@@ -260,42 +236,6 @@ void disk_part_iter_exit(struct disk_part_iter *piter)
260236 piter -> part = NULL ;
261237}
262238
263- /**
264- * disk_has_partitions
265- * @disk: gendisk of interest
266- *
267- * Walk through the partition table and check if valid partition exists.
268- *
269- * CONTEXT:
270- * Don't care.
271- *
272- * RETURNS:
273- * True if the gendisk has at least one valid non-zero size partition.
274- * Otherwise false.
275- */
276- bool disk_has_partitions (struct gendisk * disk )
277- {
278- struct disk_part_tbl * ptbl ;
279- int i ;
280- bool ret = false;
281-
282- rcu_read_lock ();
283- ptbl = rcu_dereference (disk -> part_tbl );
284-
285- /* Iterate partitions skipping the whole device at index 0 */
286- for (i = 1 ; i < ptbl -> len ; i ++ ) {
287- if (rcu_dereference (ptbl -> part [i ])) {
288- ret = true;
289- break ;
290- }
291- }
292-
293- rcu_read_unlock ();
294-
295- return ret ;
296- }
297- EXPORT_SYMBOL_GPL (disk_has_partitions );
298-
299239/*
300240 * Can be deleted altogether. Later.
301241 *
@@ -858,7 +798,7 @@ struct block_device *bdget_disk(struct gendisk *disk, int partno)
858798 struct block_device * bdev = NULL ;
859799
860800 rcu_read_lock ();
861- bdev = __disk_get_part ( disk , partno );
801+ bdev = xa_load ( & disk -> part_tbl , partno );
862802 if (bdev && !bdgrab (bdev ))
863803 bdev = NULL ;
864804 rcu_read_unlock ();
@@ -1248,83 +1188,6 @@ static const struct attribute_group *disk_attr_groups[] = {
12481188 NULL
12491189};
12501190
1251- /**
1252- * disk_replace_part_tbl - replace disk->part_tbl in RCU-safe way
1253- * @disk: disk to replace part_tbl for
1254- * @new_ptbl: new part_tbl to install
1255- *
1256- * Replace disk->part_tbl with @new_ptbl in RCU-safe way. The
1257- * original ptbl is freed using RCU callback.
1258- *
1259- * LOCKING:
1260- * Matching bd_mutex locked or the caller is the only user of @disk.
1261- */
1262- static void disk_replace_part_tbl (struct gendisk * disk ,
1263- struct disk_part_tbl * new_ptbl )
1264- {
1265- struct disk_part_tbl * old_ptbl =
1266- rcu_dereference_protected (disk -> part_tbl , 1 );
1267-
1268- rcu_assign_pointer (disk -> part_tbl , new_ptbl );
1269-
1270- if (old_ptbl ) {
1271- rcu_assign_pointer (old_ptbl -> last_lookup , NULL );
1272- kfree_rcu (old_ptbl , rcu_head );
1273- }
1274- }
1275-
1276- /**
1277- * disk_expand_part_tbl - expand disk->part_tbl
1278- * @disk: disk to expand part_tbl for
1279- * @partno: expand such that this partno can fit in
1280- *
1281- * Expand disk->part_tbl such that @partno can fit in. disk->part_tbl
1282- * uses RCU to allow unlocked dereferencing for stats and other stuff.
1283- *
1284- * LOCKING:
1285- * Matching bd_mutex locked or the caller is the only user of @disk.
1286- * Might sleep.
1287- *
1288- * RETURNS:
1289- * 0 on success, -errno on failure.
1290- */
1291- int disk_expand_part_tbl (struct gendisk * disk , int partno )
1292- {
1293- struct disk_part_tbl * old_ptbl =
1294- rcu_dereference_protected (disk -> part_tbl , 1 );
1295- struct disk_part_tbl * new_ptbl ;
1296- int len = old_ptbl ? old_ptbl -> len : 0 ;
1297- int i , target ;
1298-
1299- /*
1300- * check for int overflow, since we can get here from blkpg_ioctl()
1301- * with a user passed 'partno'.
1302- */
1303- target = partno + 1 ;
1304- if (target < 0 )
1305- return - EINVAL ;
1306-
1307- /* disk_max_parts() is zero during initialization, ignore if so */
1308- if (disk_max_parts (disk ) && target > disk_max_parts (disk ))
1309- return - EINVAL ;
1310-
1311- if (target <= len )
1312- return 0 ;
1313-
1314- new_ptbl = kzalloc_node (struct_size (new_ptbl , part , target ), GFP_KERNEL ,
1315- disk -> node_id );
1316- if (!new_ptbl )
1317- return - ENOMEM ;
1318-
1319- new_ptbl -> len = target ;
1320-
1321- for (i = 0 ; i < len ; i ++ )
1322- rcu_assign_pointer (new_ptbl -> part [i ], old_ptbl -> part [i ]);
1323-
1324- disk_replace_part_tbl (disk , new_ptbl );
1325- return 0 ;
1326- }
1327-
13281191/**
13291192 * disk_release - releases all allocated resources of the gendisk
13301193 * @dev: the device representing this disk
@@ -1348,7 +1211,7 @@ static void disk_release(struct device *dev)
13481211 blk_free_devt (dev -> devt );
13491212 disk_release_events (disk );
13501213 kfree (disk -> random );
1351- disk_replace_part_tbl ( disk , NULL );
1214+ xa_destroy ( & disk -> part_tbl );
13521215 bdput (disk -> part0 );
13531216 if (disk -> queue )
13541217 blk_put_queue (disk -> queue );
@@ -1501,7 +1364,6 @@ dev_t blk_lookup_devt(const char *name, int partno)
15011364struct gendisk * __alloc_disk_node (int minors , int node_id )
15021365{
15031366 struct gendisk * disk ;
1504- struct disk_part_tbl * ptbl ;
15051367
15061368 if (minors > DISK_MAX_PARTS ) {
15071369 printk (KERN_ERR
@@ -1519,11 +1381,9 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
15191381 goto out_free_disk ;
15201382
15211383 disk -> node_id = node_id ;
1522- if (disk_expand_part_tbl (disk , 0 ))
1523- goto out_bdput ;
1524-
1525- ptbl = rcu_dereference_protected (disk -> part_tbl , 1 );
1526- rcu_assign_pointer (ptbl -> part [0 ], disk -> part0 );
1384+ xa_init (& disk -> part_tbl );
1385+ if (xa_insert (& disk -> part_tbl , 0 , disk -> part0 , GFP_KERNEL ))
1386+ goto out_destroy_part_tbl ;
15271387
15281388 disk -> minors = minors ;
15291389 rand_initialize_disk (disk );
@@ -1532,7 +1392,8 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
15321392 device_initialize (disk_to_dev (disk ));
15331393 return disk ;
15341394
1535- out_bdput :
1395+ out_destroy_part_tbl :
1396+ xa_destroy (& disk -> part_tbl );
15361397 bdput (disk -> part0 );
15371398out_free_disk :
15381399 kfree (disk );
0 commit comments