int dm_create_error_table(struct dm_table **result, struct mapped_device *md) { struct dm_table *t; sector_t dev_size = 1; int r; /* * Find current size of device. * Default to 1 sector if inactive. */ t = dm_get_table(md); if (t) { dev_size = dm_table_get_size(t); dm_table_put(t); } r = dm_table_create(&t, FMODE_READ, 1, md); if (r) return r; r = dm_table_add_target(t, "error", 0, dev_size, NULL); if (r) goto out; r = dm_table_complete(t); if (r) goto out; *result = t; out: if (r) dm_table_put(t); return r; }
static void __init dm_setup_drive(void) { struct mapped_device *md = NULL; struct dm_table *table = NULL; struct dm_setup_target *target; char *uuid = dm_setup_args.uuid; fmode_t fmode = FMODE_READ; /* Finish parsing the targets. */ if (dm_setup_parse_targets(dm_setup_args.targets)) goto parse_fail; if (dm_create(dm_setup_args.minor, &md)) { DMDEBUG("failed to create the device"); goto dm_create_fail; } DMDEBUG("created device '%s'", dm_device_name(md)); /* In addition to flagging the table below, the disk must be * set explicitly ro/rw. */ set_disk_ro(dm_disk(md), dm_setup_args.ro); if (!dm_setup_args.ro) fmode |= FMODE_WRITE; if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) { DMDEBUG("failed to create the table"); goto dm_table_create_fail; } target = dm_setup_args.target; while (target) { DMINFO("adding target '%llu %llu %s %s'", (unsigned long long) target->begin, (unsigned long long) target->length, target->type, target->params); if (dm_table_add_target(table, target->type, target->begin, target->length, target->params)) { DMDEBUG("failed to add the target to the table"); goto add_target_fail; } target = target->next; } if (dm_table_complete(table)) { DMDEBUG("failed to complete the table"); goto table_complete_fail; } /* Suspend the device so that we can bind it to the table. */ if (dm_suspend(md, 0)) { DMDEBUG("failed to suspend the device pre-bind"); goto suspend_fail; } /* Bind the table to the device. This is the only way to associate * md->map with the table and set the disk capacity directly. */ if (dm_swap_table(md, table)) { /* should return NULL. */ DMDEBUG("failed to bind the device to the table"); goto table_bind_fail; } /* Finally, resume and the device should be ready. */ if (dm_resume(md)) { DMDEBUG("failed to resume the device"); goto resume_fail; } /* Export the dm device via the ioctl interface */ if (!strcmp(DM_NO_UUID, dm_setup_args.uuid)) uuid = NULL; if (dm_ioctl_export(md, dm_setup_args.name, uuid)) { DMDEBUG("failed to export device with given name and uuid"); goto export_fail; } printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor); dm_setup_cleanup(); return; export_fail: resume_fail: table_bind_fail: suspend_fail: table_complete_fail: add_target_fail: dm_table_put(table); dm_table_create_fail: dm_put(md); dm_create_fail: dm_setup_cleanup(); parse_fail: printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n", dm_setup_args.minor, dm_setup_args.name); }