diff options
Diffstat (limited to 'fs/partitions')
-rw-r--r-- | fs/partitions/check.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 68f3e41ae66f..16f98d824608 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -300,15 +300,6 @@ struct device_type part_type = { | |||
300 | .release = part_release, | 300 | .release = part_release, |
301 | }; | 301 | }; |
302 | 302 | ||
303 | static inline void partition_sysfs_add_subdir(struct hd_struct *p) | ||
304 | { | ||
305 | struct kobject *k; | ||
306 | |||
307 | k = kobject_get(&p->dev.kobj); | ||
308 | p->holder_dir = kobject_create_and_add("holders", k); | ||
309 | kobject_put(k); | ||
310 | } | ||
311 | |||
312 | static inline void disk_sysfs_add_subdirs(struct gendisk *disk) | 303 | static inline void disk_sysfs_add_subdirs(struct gendisk *disk) |
313 | { | 304 | { |
314 | struct kobject *k; | 305 | struct kobject *k; |
@@ -347,13 +338,16 @@ int add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, | |||
347 | struct hd_struct *p; | 338 | struct hd_struct *p; |
348 | int err; | 339 | int err; |
349 | 340 | ||
341 | if (disk->part[part - 1]) | ||
342 | return -EBUSY; | ||
343 | |||
350 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 344 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
351 | if (!p) | 345 | if (!p) |
352 | return -ENOMEM; | 346 | return -ENOMEM; |
353 | 347 | ||
354 | if (!init_part_stats(p)) { | 348 | if (!init_part_stats(p)) { |
355 | err = -ENOMEM; | 349 | err = -ENOMEM; |
356 | goto out0; | 350 | goto out_free; |
357 | } | 351 | } |
358 | p->start_sect = start; | 352 | p->start_sect = start; |
359 | p->nr_sects = len; | 353 | p->nr_sects = len; |
@@ -372,34 +366,42 @@ int add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, | |||
372 | p->dev.class = &block_class; | 366 | p->dev.class = &block_class; |
373 | p->dev.type = &part_type; | 367 | p->dev.type = &part_type; |
374 | p->dev.parent = &disk->dev; | 368 | p->dev.parent = &disk->dev; |
375 | disk->part[part-1] = p; | ||
376 | 369 | ||
377 | /* delay uevent until 'holders' subdir is created */ | 370 | /* delay uevent until 'holders' subdir is created */ |
378 | p->dev.uevent_suppress = 1; | 371 | p->dev.uevent_suppress = 1; |
379 | err = device_add(&p->dev); | 372 | err = device_add(&p->dev); |
380 | if (err) | 373 | if (err) |
381 | goto out1; | 374 | goto out_put; |
382 | partition_sysfs_add_subdir(p); | 375 | |
376 | err = -ENOMEM; | ||
377 | p->holder_dir = kobject_create_and_add("holders", &p->dev.kobj); | ||
378 | if (!p->holder_dir) | ||
379 | goto out_del; | ||
380 | |||
383 | p->dev.uevent_suppress = 0; | 381 | p->dev.uevent_suppress = 0; |
384 | if (flags & ADDPART_FLAG_WHOLEDISK) { | 382 | if (flags & ADDPART_FLAG_WHOLEDISK) { |
385 | err = device_create_file(&p->dev, &dev_attr_whole_disk); | 383 | err = device_create_file(&p->dev, &dev_attr_whole_disk); |
386 | if (err) | 384 | if (err) |
387 | goto out2; | 385 | goto out_del; |
388 | } | 386 | } |
389 | 387 | ||
388 | /* everything is up and running, commence */ | ||
389 | disk->part[part - 1] = p; | ||
390 | |||
390 | /* suppress uevent if the disk supresses it */ | 391 | /* suppress uevent if the disk supresses it */ |
391 | if (!disk->dev.uevent_suppress) | 392 | if (!disk->dev.uevent_suppress) |
392 | kobject_uevent(&p->dev.kobj, KOBJ_ADD); | 393 | kobject_uevent(&p->dev.kobj, KOBJ_ADD); |
393 | 394 | ||
394 | return 0; | 395 | return 0; |
395 | 396 | ||
396 | out2: | 397 | out_free: |
398 | kfree(p); | ||
399 | return err; | ||
400 | out_del: | ||
401 | kobject_put(p->holder_dir); | ||
397 | device_del(&p->dev); | 402 | device_del(&p->dev); |
398 | out1: | 403 | out_put: |
399 | put_device(&p->dev); | 404 | put_device(&p->dev); |
400 | free_part_stats(p); | ||
401 | out0: | ||
402 | kfree(p); | ||
403 | return err; | 405 | return err; |
404 | } | 406 | } |
405 | 407 | ||