in drivers/ubd_kern.c [237:340]
static int ubd_setup_common(char *str, int *index_out, char **error_out)
{
struct ubd *ubd_dev;
struct openflags flags = global_openflags;
char *file, *backing_file, *serial;
int n, err = 0, i;
if(index_out) *index_out = -1;
n = *str;
if(n == '='){
str++;
if(!strcmp(str, "sync")){
global_openflags = of_sync(global_openflags);
return err;
}
pr_warn("fake major not supported any more\n");
return 0;
}
n = parse_unit(&str);
if(n < 0){
*error_out = "Couldn't parse device number";
return -EINVAL;
}
if(n >= MAX_DEV){
*error_out = "Device number out of range";
return 1;
}
err = -EBUSY;
mutex_lock(&ubd_lock);
ubd_dev = &ubd_devs[n];
if(ubd_dev->file != NULL){
*error_out = "Device is already configured";
goto out;
}
if (index_out)
*index_out = n;
err = -EINVAL;
for (i = 0; i < sizeof("rscdt="); i++) {
switch (*str) {
case 'r':
flags.w = 0;
break;
case 's':
flags.s = 1;
break;
case 'd':
ubd_dev->no_cow = 1;
break;
case 'c':
ubd_dev->shared = 1;
break;
case 't':
ubd_dev->no_trim = 1;
break;
case '=':
str++;
goto break_loop;
default:
*error_out = "Expected '=' or flag letter "
"(r, s, c, t or d)";
goto out;
}
str++;
}
if (*str == '=')
*error_out = "Too many flags specified";
else
*error_out = "Missing '='";
goto out;
break_loop:
file = strsep(&str, ",:");
if (*file == '\0')
file = NULL;
backing_file = strsep(&str, ",:");
if (backing_file && *backing_file == '\0')
backing_file = NULL;
serial = strsep(&str, ",:");
if (serial && *serial == '\0')
serial = NULL;
if (backing_file && ubd_dev->no_cow) {
*error_out = "Can't specify both 'd' and a cow file";
goto out;
}
err = 0;
ubd_dev->file = file;
ubd_dev->cow.file = backing_file;
ubd_dev->serial = serial;
ubd_dev->boot_openflags = flags;
out:
mutex_unlock(&ubd_lock);
return err;
}