@@ -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,44 +5133,51 @@ 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
- struct rbd_spec * parent_spec ;
5138
- struct rbd_client * rbdc ;
5139
5144
int ret ;
5140
5145
5141
5146
if (!rbd_dev -> parent_spec )
5142
5147
return 0 ;
5143
- /*
5144
- * We need to pass a reference to the client and the parent
5145
- * spec when creating the parent rbd_dev. Images related by
5146
- * parent/child relationships always share both.
5147
- */
5148
- parent_spec = rbd_spec_get (rbd_dev -> parent_spec );
5149
- rbdc = __rbd_get_client (rbd_dev -> rbd_client );
5150
5148
5151
- ret = - ENOMEM ;
5152
- parent = rbd_dev_create (rbdc , parent_spec , NULL );
5153
- if (!parent )
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
+
5155
+ parent = rbd_dev_create (rbd_dev -> rbd_client , rbd_dev -> parent_spec ,
5156
+ NULL );
5157
+ if (!parent ) {
5158
+ ret = - ENOMEM ;
5154
5159
goto out_err ;
5160
+ }
5161
+
5162
+ /*
5163
+ * Images related by parent/child relationships always share
5164
+ * rbd_client and spec/parent_spec, so bump their refcounts.
5165
+ */
5166
+ __rbd_get_client (rbd_dev -> rbd_client );
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 ;
5172
+
5159
5173
rbd_dev -> parent = parent ;
5160
5174
atomic_set (& rbd_dev -> parent_ref , 1 );
5161
-
5162
5175
return 0 ;
5176
+
5163
5177
out_err :
5164
- if ( parent ) {
5165
- rbd_dev_unparent ( rbd_dev );
5178
+ rbd_dev_unparent ( rbd_dev );
5179
+ if ( parent )
5166
5180
rbd_dev_destroy (parent );
5167
- } else {
5168
- rbd_put_client (rbdc );
5169
- rbd_spec_put (parent_spec );
5170
- }
5171
-
5172
5181
return ret ;
5173
5182
}
5174
5183
@@ -5286,7 +5295,7 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
5286
5295
* parent), initiate a watch on its header object before using that
5287
5296
* object to get detailed information about the rbd image.
5288
5297
*/
5289
- 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 )
5290
5299
{
5291
5300
int ret ;
5292
5301
@@ -5304,7 +5313,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5304
5313
if (ret )
5305
5314
goto err_out_format ;
5306
5315
5307
- if (mapping ) {
5316
+ if (! depth ) {
5308
5317
ret = rbd_dev_header_watch_sync (rbd_dev );
5309
5318
if (ret ) {
5310
5319
if (ret == - ENOENT )
@@ -5325,7 +5334,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5325
5334
* Otherwise this is a parent image, identified by pool, image
5326
5335
* and snap ids - need to fill in names for those ids.
5327
5336
*/
5328
- if (mapping )
5337
+ if (! depth )
5329
5338
ret = rbd_spec_fill_snap_id (rbd_dev );
5330
5339
else
5331
5340
ret = rbd_spec_fill_names (rbd_dev );
@@ -5347,12 +5356,12 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5347
5356
* Need to warn users if this image is the one being
5348
5357
* mapped and has a parent.
5349
5358
*/
5350
- if (mapping && rbd_dev -> parent_spec )
5359
+ if (! depth && rbd_dev -> parent_spec )
5351
5360
rbd_warn (rbd_dev ,
5352
5361
"WARNING: kernel layering is EXPERIMENTAL!" );
5353
5362
}
5354
5363
5355
- ret = rbd_dev_probe_parent (rbd_dev );
5364
+ ret = rbd_dev_probe_parent (rbd_dev , depth );
5356
5365
if (ret )
5357
5366
goto err_out_probe ;
5358
5367
@@ -5363,7 +5372,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
5363
5372
err_out_probe :
5364
5373
rbd_dev_unprobe (rbd_dev );
5365
5374
err_out_watch :
5366
- if (mapping )
5375
+ if (! depth )
5367
5376
rbd_dev_header_unwatch_sync (rbd_dev );
5368
5377
out_header_name :
5369
5378
kfree (rbd_dev -> header_name );
@@ -5426,7 +5435,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
5426
5435
spec = NULL ; /* rbd_dev now owns this */
5427
5436
rbd_opts = NULL ; /* rbd_dev now owns this */
5428
5437
5429
- rc = rbd_dev_image_probe (rbd_dev , true );
5438
+ rc = rbd_dev_image_probe (rbd_dev , 0 );
5430
5439
if (rc < 0 )
5431
5440
goto err_out_rbd_dev ;
5432
5441
0 commit comments