-0.91.02-cvs (2002-01-04)
+0.92.00-cvs (2002-01-10)
static int __check_name(const char *name)
{
- if (strchr(name, '/')) {
+ if (strchr(name, '/') || strlen(name) > DM_NAME_LEN) {
DMWARN("invalid device name");
return -1;
}
dm_unlock_w();
}
+/*
+ * Renames the device
+ */
+int dm_set_name(struct mapped_device *md, const char *newname)
+{
+ int r;
+
+ dm_lock_w();
+
+ if (__check_name(newname) < 0) {
+ r = -EINVAL;
+ goto err;
+ }
+
+ r = unregister_device(md);
+ if (r)
+ goto err;
+
+ strcpy(md->name, newname);
+
+ r = register_device(md);
+ if (r)
+ goto err;
+
+ err:
+ dm_unlock_w();
+ return r;
+}
+
+
/*
* Requeue the deferred buffer_heads by calling generic_make_request.
*/
#ifndef DM_INTERNAL_H
#define DM_INTERNAL_H
+
#include <linux/config.h>
#include <linux/version.h>
#include <linux/major.h>
struct mapped_device **result);
int dm_destroy(struct mapped_device *md);
void dm_set_ro(struct mapped_device *md, int ro);
+int dm_set_name(struct mapped_device *md, const char *newname);
/*
* The device must be suspended before calling this method.
/*
* Targets for linear and striped mappings
*/
+
int dm_linear_init(void);
void dm_linear_exit(void);
+
int dm_stripe_init(void);
void dm_stripe_exit(void);
-
#endif
}
/*
- * check a string doesn't overrun the chunk of
+ * Check a string doesn't overrun the chunk of
* memory we copied from userland.
+ * Returns 1 if OK.
*/
static int valid_str(char *str, void *begin, void *end)
{
*spec = (struct dm_target_spec *) (a + 1);
*params = (char *) (*spec + 1);
- return valid_str(*params, begin, end);
+ return !valid_str(*params, begin, end);
}
static int next_target(struct dm_target_spec *last, void *begin, void *end,
(((unsigned char *) last) + last->next);
*params = (char *) (*spec + 1);
- return valid_str(*params, begin, end);
+ return !valid_str(*params, begin, end);
}
void dm_error(const char *message)
r = first ? first_target(args, begin, end, &spec, ¶ms) :
next_target(spec, begin, end, &spec, ¶ms);
- if (!r)
+ if (r)
PARSE_ERROR("unable to find target");
/* Look up the target type */
return r;
}
+static int rename(struct dm_ioctl *param)
+{
+ char *newname = (char *) (param + 1);
+ struct mapped_device *md = dm_get(param->name);
+
+ if (!md)
+ return -ENXIO;
+
+ if (!valid_str(newname, (void *)param,
+ (void *)param + param->data_size) ||
+ dm_set_name(md, newname)) {
+ dm_error("Invalid new logical volume name supplied.");
+ return -EINVAL;
+ }
+
+ dm_put(md);
+ return 0;
+}
+
static int ctl_open(struct inode *inode, struct file *file)
{
/* only root can open this */
r = info(p->name, (struct dm_ioctl *) a);
break;
+ case DM_RENAME:
+ r = rename(p);
+ break;
+
default:
DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
r = -EINVAL;
#define DM_SUSPEND _IOW(DM_IOCTL, 0x02, struct dm_ioctl)
#define DM_RELOAD _IOWR(DM_IOCTL, 0x03, struct dm_ioctl)
#define DM_INFO _IOWR(DM_IOCTL, 0x04, struct dm_ioctl)
+#define DM_RENAME _IOWR(DM_IOCTL, 0x05, struct dm_ioctl)
#define DM_IOCTL_VERSION @DM_IOCTL_VERSION@
free(t);
}
+ if (dmt->newname)
+ free(dmt->newname);
+
if (dmt->dmi)
free(dmt->dmi);
return 1;
}
+int dm_task_set_newname(struct dm_task *dmt, const char *newname)
+{
+ if (!(dmt->newname = strdup(newname))) {
+ log("dm_task_set_newname: strdup(%s) failed", newname);
+ return 0;
+ }
+
+ return 1;
+}
+
struct target *create_target(uint64_t start,
uint64_t len,
const char *type, const char *params)
count++;
}
+ if (count && dmt->newname) {
+ log("targets and newname are incompatible");
+ return NULL;
+ }
+
+ if (dmt->newname)
+ len += strlen(dmt->newname) + 1;
+
if (!(dmi = malloc(len)))
return NULL;
if (!(b = _add_target(t, b, e)))
goto bad;
+ if (dmt->newname)
+ strcpy(b, dmt->newname);
+
return dmi;
bad:
command = DM_INFO;
break;
+ case DM_DEVICE_RENAME:
+ command = DM_RENAME;
+ break;
+
default:
log("Internal error: unknown device-mapper task %d",
dmt->type);
int read_only;
struct dm_ioctl *dmi;
+ char *newname;
};
DM_DEVICE_RESUME,
DM_DEVICE_INFO,
+ DM_DEVICE_RENAME,
};
int dm_task_set_ro(struct dm_task *dmt);
+int dm_task_set_newname(struct dm_task *dmt, const char *newname);
+
/*
* Use these to prepare for a create or reload.
*/