Use a unit number allocator to provide suitable st_dev and st_ino values
for POSIX shared memory descriptors. The implementation is similar to that used for pipes. MFC after: 1 week
This commit is contained in:
parent
ea463f2dc0
commit
610a2b3c45
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/capsicum.h>
|
#include <sys/capsicum.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/filedesc.h>
|
#include <sys/filedesc.h>
|
||||||
@ -101,6 +102,8 @@ static LIST_HEAD(, shm_mapping) *shm_dictionary;
|
|||||||
static struct sx shm_dict_lock;
|
static struct sx shm_dict_lock;
|
||||||
static struct mtx shm_timestamp_lock;
|
static struct mtx shm_timestamp_lock;
|
||||||
static u_long shm_hash;
|
static u_long shm_hash;
|
||||||
|
static struct unrhdr *shm_ino_unr;
|
||||||
|
static dev_t shm_dev_ino;
|
||||||
|
|
||||||
#define SHM_HASH(fnv) (&shm_dictionary[(fnv) & shm_hash])
|
#define SHM_HASH(fnv) (&shm_dictionary[(fnv) & shm_hash])
|
||||||
|
|
||||||
@ -408,6 +411,8 @@ shm_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
|
|||||||
sb->st_uid = shmfd->shm_uid;
|
sb->st_uid = shmfd->shm_uid;
|
||||||
sb->st_gid = shmfd->shm_gid;
|
sb->st_gid = shmfd->shm_gid;
|
||||||
mtx_unlock(&shm_timestamp_lock);
|
mtx_unlock(&shm_timestamp_lock);
|
||||||
|
sb->st_dev = shm_dev_ino;
|
||||||
|
sb->st_ino = shmfd->shm_ino;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -539,6 +544,7 @@ static struct shmfd *
|
|||||||
shm_alloc(struct ucred *ucred, mode_t mode)
|
shm_alloc(struct ucred *ucred, mode_t mode)
|
||||||
{
|
{
|
||||||
struct shmfd *shmfd;
|
struct shmfd *shmfd;
|
||||||
|
int ino;
|
||||||
|
|
||||||
shmfd = malloc(sizeof(*shmfd), M_SHMFD, M_WAITOK | M_ZERO);
|
shmfd = malloc(sizeof(*shmfd), M_SHMFD, M_WAITOK | M_ZERO);
|
||||||
shmfd->shm_size = 0;
|
shmfd->shm_size = 0;
|
||||||
@ -555,6 +561,11 @@ shm_alloc(struct ucred *ucred, mode_t mode)
|
|||||||
vfs_timestamp(&shmfd->shm_birthtime);
|
vfs_timestamp(&shmfd->shm_birthtime);
|
||||||
shmfd->shm_atime = shmfd->shm_mtime = shmfd->shm_ctime =
|
shmfd->shm_atime = shmfd->shm_mtime = shmfd->shm_ctime =
|
||||||
shmfd->shm_birthtime;
|
shmfd->shm_birthtime;
|
||||||
|
ino = alloc_unr(shm_ino_unr);
|
||||||
|
if (ino == -1)
|
||||||
|
shmfd->shm_ino = 0;
|
||||||
|
else
|
||||||
|
shmfd->shm_ino = ino;
|
||||||
refcount_init(&shmfd->shm_refs, 1);
|
refcount_init(&shmfd->shm_refs, 1);
|
||||||
mtx_init(&shmfd->shm_mtx, "shmrl", NULL, MTX_DEF);
|
mtx_init(&shmfd->shm_mtx, "shmrl", NULL, MTX_DEF);
|
||||||
rangelock_init(&shmfd->shm_rl);
|
rangelock_init(&shmfd->shm_rl);
|
||||||
@ -585,6 +596,8 @@ shm_drop(struct shmfd *shmfd)
|
|||||||
rangelock_destroy(&shmfd->shm_rl);
|
rangelock_destroy(&shmfd->shm_rl);
|
||||||
mtx_destroy(&shmfd->shm_mtx);
|
mtx_destroy(&shmfd->shm_mtx);
|
||||||
vm_object_deallocate(shmfd->shm_object);
|
vm_object_deallocate(shmfd->shm_object);
|
||||||
|
if (shmfd->shm_ino != 0)
|
||||||
|
free_unr(shm_ino_unr, shmfd->shm_ino);
|
||||||
free(shmfd, M_SHMFD);
|
free(shmfd, M_SHMFD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,14 +630,18 @@ shm_access(struct shmfd *shmfd, struct ucred *ucred, int flags)
|
|||||||
* the mappings in a hash table.
|
* the mappings in a hash table.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
shm_dict_init(void *arg)
|
shm_init(void *arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
mtx_init(&shm_timestamp_lock, "shm timestamps", NULL, MTX_DEF);
|
mtx_init(&shm_timestamp_lock, "shm timestamps", NULL, MTX_DEF);
|
||||||
sx_init(&shm_dict_lock, "shm dictionary");
|
sx_init(&shm_dict_lock, "shm dictionary");
|
||||||
shm_dictionary = hashinit(1024, M_SHMFD, &shm_hash);
|
shm_dictionary = hashinit(1024, M_SHMFD, &shm_hash);
|
||||||
|
shm_ino_unr = new_unrhdr(1, INT32_MAX, NULL);
|
||||||
|
KASSERT(shm_ino_unr != NULL, ("shm fake inodes not initialized"));
|
||||||
|
shm_dev_ino = devfs_alloc_cdp_inode();
|
||||||
|
KASSERT(shm_dev_ino > 0, ("shm dev inode not initialized"));
|
||||||
}
|
}
|
||||||
SYSINIT(shm_dict_init, SI_SUB_SYSV_SHM, SI_ORDER_ANY, shm_dict_init, NULL);
|
SYSINIT(shm_init, SI_SUB_SYSV_SHM, SI_ORDER_ANY, shm_init, NULL);
|
||||||
|
|
||||||
static struct shmfd *
|
static struct shmfd *
|
||||||
shm_lookup(char *path, Fnv32_t fnv)
|
shm_lookup(char *path, Fnv32_t fnv)
|
||||||
|
Loading…
Reference in New Issue
Block a user