@@ -96,6 +96,8 @@ static int atomic_dec_return_safe(atomic_t *v)
96
96
#define RBD_MINORS_PER_MAJOR 256
97
97
#define RBD_SINGLE_MAJOR_PART_SHIFT 4
98
98
99
+ #define RBD_MAX_PARENT_CHAIN_LEN 16
100
+
99
101
#define RBD_SNAP_DEV_NAME_PREFIX "snap_"
100
102
#define RBD_MAX_SNAP_NAME_LEN \
101
103
(NAME_MAX - (sizeof (RBD_SNAP_DEV_NAME_PREFIX) - 1))
@@ -426,7 +428,7 @@ static ssize_t rbd_add_single_major(struct bus_type *bus, const char *buf,
426
428
size_t count );
427
429
static ssize_t rbd_remove_single_major (struct bus_type * bus , const char * buf ,
428
430
size_t count );
429
- static int rbd_dev_image_probe (struct rbd_device * rbd_dev , bool mapping );
431
+ static int rbd_dev_image_probe (struct rbd_device * rbd_dev , int depth );
430
432
static void rbd_spec_put (struct rbd_spec * spec );
431
433
432
434
static int rbd_dev_id_to_minor (int dev_id )
@@ -5131,14 +5133,25 @@ static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
5131
5133
return ret ;
5132
5134
}
5133
5135
5134
- static int rbd_dev_probe_parent (struct rbd_device * rbd_dev )
5136
+ /*
5137
+ * @depth is rbd_dev_image_probe() -> rbd_dev_probe_parent() ->
5138
+ * rbd_dev_image_probe() recursion depth, which means it's also the
5139
+ * length of the already discovered part of the parent chain.
5140
+ */
5141
+ static int rbd_dev_probe_parent (struct rbd_device * rbd_dev , int depth )
5135
5142
{
5136
5143
struct rbd_device * parent = NULL ;
5137
5144
int ret ;
5138
5145
5139
5146
if (!rbd_dev -> parent_spec )
5140
5147
return 0 ;
5141
5148
5149
+ if (++ depth > RBD_MAX_PARENT_CHAIN_LEN ) {
5150
+ pr_info ("parent chain is too long (%d)\n" , depth );
5151
+ ret = - EINVAL ;
5152
+ goto out_err ;
5153
+ }
5154
+
5142
5155
parent = rbd_dev_create (rbd_dev -> rbd_client , rbd_dev -> parent_spec ,
5143
5156
NULL );
5144
5157
if (!parent ) {
@@ -5153,7 +5166,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
5153
5166
__rbd_get_client (rbd_dev -> rbd_client );
5154
5167
rbd_spec_get (rbd_dev -> parent_spec );
5155
5168
5156
- ret = rbd_dev_image_probe (parent , false );
5169
+ ret = rbd_dev_image_probe (parent , depth );
5157
5170
if (ret < 0 )
5158
5171
goto out_err ;
5159
5172
@@ -5282,7 +5295,7 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
5282
5295
* parent), initiate a watch on its header object before using that
5283
5296
* object to get detailed information about the rbd image.
5284
5297
*/
5285
- static int rbd_dev_image_probe (struct rbd_device * rbd_dev , bool mapping )
5298
+ static int rbd_dev_image_probe (struct rbd_device * rbd_dev , int depth )
5286
5299
{
5287
5300
int ret ;
5288
5301
@@ -5300,7 +5313,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5300
5313
if (ret )
5301
5314
goto err_out_format ;
5302
5315
5303
- if (mapping ) {
5316
+ if (! depth ) {
5304
5317
ret = rbd_dev_header_watch_sync (rbd_dev );
5305
5318
if (ret ) {
5306
5319
if (ret == - ENOENT )
@@ -5321,7 +5334,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5321
5334
* Otherwise this is a parent image, identified by pool, image
5322
5335
* and snap ids - need to fill in names for those ids.
5323
5336
*/
5324
- if (mapping )
5337
+ if (! depth )
5325
5338
ret = rbd_spec_fill_snap_id (rbd_dev );
5326
5339
else
5327
5340
ret = rbd_spec_fill_names (rbd_dev );
@@ -5343,12 +5356,12 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5343
5356
* Need to warn users if this image is the one being
5344
5357
* mapped and has a parent.
5345
5358
*/
5346
- if (mapping && rbd_dev -> parent_spec )
5359
+ if (! depth && rbd_dev -> parent_spec )
5347
5360
rbd_warn (rbd_dev ,
5348
5361
"WARNING: kernel layering is EXPERIMENTAL!" );
5349
5362
}
5350
5363
5351
- ret = rbd_dev_probe_parent (rbd_dev );
5364
+ ret = rbd_dev_probe_parent (rbd_dev , depth );
5352
5365
if (ret )
5353
5366
goto err_out_probe ;
5354
5367
@@ -5359,7 +5372,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5359
5372
err_out_probe :
5360
5373
rbd_dev_unprobe (rbd_dev );
5361
5374
err_out_watch :
5362
- if (mapping )
5375
+ if (! depth )
5363
5376
rbd_dev_header_unwatch_sync (rbd_dev );
5364
5377
out_header_name :
5365
5378
kfree (rbd_dev -> header_name );
@@ -5422,7 +5435,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
5422
5435
spec = NULL ; /* rbd_dev now owns this */
5423
5436
rbd_opts = NULL ; /* rbd_dev now owns this */
5424
5437
5425
- rc = rbd_dev_image_probe (rbd_dev , true );
5438
+ rc = rbd_dev_image_probe (rbd_dev , 0 );
5426
5439
if (rc < 0 )
5427
5440
goto err_out_rbd_dev ;
5428
5441
0 commit comments