mdopen: use small sequence number for uniquifying array names.

Rather than appending the md minor number, we now append a small
sequence number to make sure name in /dev/md/ that aren't LOCAL are
unique.  As the map file is locked while we do this, we are sure
of no losing any races.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2008-11-04 20:51:12 +11:00
parent f05641cf7a
commit f2e55eccfb
4 changed files with 44 additions and 10 deletions

View File

@ -245,3 +245,18 @@ struct map_ent *map_by_devnum(struct map_ent **map, int devnum)
return mp;
return NULL;
}
struct map_ent *map_by_name(struct map_ent **map, char *name)
{
struct map_ent *mp;
if (!*map)
map_read(map);
for (mp = *map ; mp ; mp = mp->next) {
if (strncmp(mp->path, "/dev/md/", 8) != 0)
continue;
if (strcmp(mp->path+8, name) == 0)
return mp;
}
return NULL;
}

View File

@ -320,7 +320,8 @@ struct map_ent {
extern int map_update(struct map_ent **mpp, int devnum, char *metadata,
int uuid[4], char *path);
extern struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]);
struct map_ent *map_by_devnum(struct map_ent **map, int devnum);
extern struct map_ent *map_by_devnum(struct map_ent **map, int devnum);
extern struct map_ent *map_by_name(struct map_ent **map, char *name);
extern void map_read(struct map_ent **melp);
extern int map_write(struct map_ent *mel);
extern void map_delete(struct map_ent **mapp, int devnum);

View File

@ -84,6 +84,10 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata,
{
return 0;
}
struct map_ent *map_by_name(struct map_ent **mpp, char *name)
{
return NULL;
}
int rv;
int mdfd = -1;

View File

@ -269,19 +269,33 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
* reasonable length and remove '/'
*/
char *cp;
struct map_ent *map = NULL;
int conflict = 1;
int unum = 0;
int cnlen;
strncpy(cname, name, 200);
cname[200] = 0;
while ((cp = strchr(cname, '/')) != NULL)
*cp = '-';
if (trustworthy == METADATA)
/* always add device number to metadata */
sprintf(cname+strlen(cname), "%d", num);
else if (trustworthy == FOREIGN &&
strchr(cname, ':') == NULL)
/* add _%d to FOREIGN array that don't have
* a 'host:' prefix
*/
sprintf(cname+strlen(cname), "_%d", num<0?(-1-num):num);
if (trustworthy == LOCAL ||
(trustworthy == FOREIGN && strchr(cname, ':') != NULL)) {
/* Only need suffix if there is a conflict */
if (map_by_name(&map, cname) == NULL)
conflict = 0;
}
cnlen = strlen(cname);
while (conflict) {
if (trustworthy == METADATA)
sprintf(cname+cnlen, "%d", unum);
else
/* add _%d to FOREIGN array that don't
* a 'host:' prefix
*/
sprintf(cname+cnlen, "_%d", unum);
unum++;
if (map_by_name(&map, cname) == NULL)
conflict = 0;
}
}
if (cname[0] == 0)
strcpy(chosen, devname);