struct inode *dmfs_create_lv(struct super_block *sb, int mode, struct dentry *dentry) { struct inode *inode = dmfs_new_private_inode(sb, mode | S_IFDIR); struct mapped_device *md; const char *name = dentry->d_name.name; char tmp_name[DM_NAME_LEN + 1]; struct dm_table *table; int ret = -ENOMEM; if (inode) { ret = dm_table_create(&table); if (!ret) { ret = dm_table_complete(table); if (!ret) { inode->i_fop = &dmfs_lv_file_operations; inode->i_op = &dmfs_lv_inode_operations; memcpy(tmp_name, name, dentry->d_name.len); tmp_name[dentry->d_name.len] = 0; ret = dm_create(tmp_name, -1, table, &md); if (!ret) { DMFS_I(inode)->md = md; md->suspended = 1; return inode; } } dm_table_destroy(table); } iput(inode); } return ERR_PTR(ret); }
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); }