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:
parent
f05641cf7a
commit
f2e55eccfb
15
mapfile.c
15
mapfile.c
|
@ -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;
|
||||
}
|
||||
|
|
3
mdadm.h
3
mdadm.h
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
32
mdopen.c
32
mdopen.c
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue