Don't try so hard to make the lower 16 bits of fsids unique. It tended
to recycle full fsids after only 16 mount/unmount's. This is probably too often for exported fsids. Now we recycle the full fsids only after 2^16 mount/ umount's and only ensure uniqueness in the lower 16 bits if there have been <= 256 calls to vfs_getnewfsid() since the system started.
This commit is contained in:
parent
44dfd6a858
commit
05ecdd7037
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=58059
@ -328,40 +328,31 @@ vfs_getvfs(fsid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a new unique fsid. Try to make its val[0] unique mod 2^16, since
|
* Get a new unique fsid. Try to make its val[0] unique, since this value
|
||||||
* this value may be used to create fake device numbers for stat(), and
|
* will be used to create fake device numbers for stat(). Also try (but
|
||||||
* some emulators only support 16-bit device numbers.
|
* not so hard) make its val[0] unique mod 2^16, since some emulators only
|
||||||
|
* support 16-bit device numbers. We end up with unique val[0]'s for the
|
||||||
|
* first 2^16 calls and unique val[0]'s mod 2^16 for the first 2^8 calls.
|
||||||
*
|
*
|
||||||
* Keep in mind that several mounts may be running in parallel. Starting
|
* Keep in mind that several mounts may be running in parallel. Starting
|
||||||
* the search one past where the previous search terminated (mod 0x10) is
|
* the search one past where the previous search terminated is both a
|
||||||
* both a micro-optimization and (incomplete) defense against returning
|
* micro-optimization and a defense against returning the same fsid to
|
||||||
* the same fsid to different mounts.
|
* different mounts.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vfs_getnewfsid(mp)
|
vfs_getnewfsid(mp)
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
{
|
{
|
||||||
static u_int mntid_base;
|
static u_int16_t mntid_base;
|
||||||
fsid_t tfsid;
|
fsid_t tfsid;
|
||||||
u_int i;
|
int mtype;
|
||||||
int mtype, mynor;
|
|
||||||
|
|
||||||
simple_lock(&mntid_slock);
|
simple_lock(&mntid_slock);
|
||||||
mtype = mp->mnt_vfc->vfc_typenum;
|
mtype = mp->mnt_vfc->vfc_typenum;
|
||||||
tfsid.val[1] = mtype;
|
tfsid.val[1] = mtype;
|
||||||
for (i = 0; ; i++) {
|
mtype = (mtype & 0xFF) << 16;
|
||||||
/*
|
for (;;) {
|
||||||
* mtype needs to be uniquely encoded in the minor number
|
tfsid.val[0] = makeudev(255, mtype | mntid_base++);
|
||||||
* so that uniqueness of the full fsid implies uniqueness
|
|
||||||
* of the device number. We are short of bits and only
|
|
||||||
* guarantee uniqueness of the device number mod 2^16 if
|
|
||||||
* mtype is always < 16 and there are never more than
|
|
||||||
* 16 mounts per vfs type.
|
|
||||||
*/
|
|
||||||
mynor = ((mntid_base++ & 0xFFFFF) << 4) | (mtype & 0xF);
|
|
||||||
if (i < 0x10)
|
|
||||||
mynor &= 0xFF;
|
|
||||||
tfsid.val[0] = makeudev(255, mynor);
|
|
||||||
if (vfs_getvfs(&tfsid) == NULL)
|
if (vfs_getvfs(&tfsid) == NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -328,40 +328,31 @@ vfs_getvfs(fsid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a new unique fsid. Try to make its val[0] unique mod 2^16, since
|
* Get a new unique fsid. Try to make its val[0] unique, since this value
|
||||||
* this value may be used to create fake device numbers for stat(), and
|
* will be used to create fake device numbers for stat(). Also try (but
|
||||||
* some emulators only support 16-bit device numbers.
|
* not so hard) make its val[0] unique mod 2^16, since some emulators only
|
||||||
|
* support 16-bit device numbers. We end up with unique val[0]'s for the
|
||||||
|
* first 2^16 calls and unique val[0]'s mod 2^16 for the first 2^8 calls.
|
||||||
*
|
*
|
||||||
* Keep in mind that several mounts may be running in parallel. Starting
|
* Keep in mind that several mounts may be running in parallel. Starting
|
||||||
* the search one past where the previous search terminated (mod 0x10) is
|
* the search one past where the previous search terminated is both a
|
||||||
* both a micro-optimization and (incomplete) defense against returning
|
* micro-optimization and a defense against returning the same fsid to
|
||||||
* the same fsid to different mounts.
|
* different mounts.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vfs_getnewfsid(mp)
|
vfs_getnewfsid(mp)
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
{
|
{
|
||||||
static u_int mntid_base;
|
static u_int16_t mntid_base;
|
||||||
fsid_t tfsid;
|
fsid_t tfsid;
|
||||||
u_int i;
|
int mtype;
|
||||||
int mtype, mynor;
|
|
||||||
|
|
||||||
simple_lock(&mntid_slock);
|
simple_lock(&mntid_slock);
|
||||||
mtype = mp->mnt_vfc->vfc_typenum;
|
mtype = mp->mnt_vfc->vfc_typenum;
|
||||||
tfsid.val[1] = mtype;
|
tfsid.val[1] = mtype;
|
||||||
for (i = 0; ; i++) {
|
mtype = (mtype & 0xFF) << 16;
|
||||||
/*
|
for (;;) {
|
||||||
* mtype needs to be uniquely encoded in the minor number
|
tfsid.val[0] = makeudev(255, mtype | mntid_base++);
|
||||||
* so that uniqueness of the full fsid implies uniqueness
|
|
||||||
* of the device number. We are short of bits and only
|
|
||||||
* guarantee uniqueness of the device number mod 2^16 if
|
|
||||||
* mtype is always < 16 and there are never more than
|
|
||||||
* 16 mounts per vfs type.
|
|
||||||
*/
|
|
||||||
mynor = ((mntid_base++ & 0xFFFFF) << 4) | (mtype & 0xF);
|
|
||||||
if (i < 0x10)
|
|
||||||
mynor &= 0xFF;
|
|
||||||
tfsid.val[0] = makeudev(255, mynor);
|
|
||||||
if (vfs_getvfs(&tfsid) == NULL)
|
if (vfs_getvfs(&tfsid) == NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user