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:
Bruce Evans 2000-03-14 14:19:49 +00:00
parent 44dfd6a858
commit 05ecdd7037
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=58059
2 changed files with 26 additions and 44 deletions

View File

@ -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;
} }

View File

@ -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;
} }