mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 21:51:05 +00:00
ipc: unify the syscalls code
This patch introduces a change into the sys_msgget(), sys_semget() and sys_shmget() routines: they now share a common code, which is better for maintainability. Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
7ca7e564e0
commit
7748dbfaa0
5 changed files with 215 additions and 139 deletions
101
ipc/util.c
101
ipc/util.c
|
@ -197,7 +197,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
|
|||
* If key is found ipc contains its ipc structure
|
||||
*/
|
||||
|
||||
struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
|
||||
static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
|
||||
{
|
||||
struct kern_ipc_perm *ipc;
|
||||
int next_id;
|
||||
|
@ -300,6 +300,105 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
|||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipcget_new - create a new ipc object
|
||||
* @ns: namespace
|
||||
* @ids: identifer set
|
||||
* @ops: the actual creation routine to call
|
||||
* @params: its parameters
|
||||
*
|
||||
* This routine is called sys_msgget, sys_semget() and sys_shmget() when
|
||||
* the key is IPC_PRIVATE
|
||||
*/
|
||||
int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
|
||||
struct ipc_ops *ops, struct ipc_params *params)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
|
||||
|
||||
if (!err)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&ids->mutex);
|
||||
err = ops->getnew(ns, params);
|
||||
mutex_unlock(&ids->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipc_check_perms - check security and permissions for an IPC
|
||||
* @ipcp: ipc permission set
|
||||
* @ids: identifer set
|
||||
* @ops: the actual security routine to call
|
||||
* @params: its parameters
|
||||
*/
|
||||
static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
|
||||
struct ipc_params *params)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (ipcperms(ipcp, params->flg))
|
||||
err = -EACCES;
|
||||
else {
|
||||
err = ops->associate(ipcp, params->flg);
|
||||
if (!err)
|
||||
err = ipcp->id;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipcget_public - get an ipc object or create a new one
|
||||
* @ns: namespace
|
||||
* @ids: identifer set
|
||||
* @ops: the actual creation routine to call
|
||||
* @params: its parameters
|
||||
*
|
||||
* This routine is called sys_msgget, sys_semget() and sys_shmget() when
|
||||
* the key is not IPC_PRIVATE
|
||||
*/
|
||||
int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
|
||||
struct ipc_ops *ops, struct ipc_params *params)
|
||||
{
|
||||
struct kern_ipc_perm *ipcp;
|
||||
int flg = params->flg;
|
||||
int err;
|
||||
|
||||
err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
|
||||
|
||||
mutex_lock(&ids->mutex);
|
||||
ipcp = ipc_findkey(ids, params->key);
|
||||
if (ipcp == NULL) {
|
||||
/* key not used */
|
||||
if (!(flg & IPC_CREAT))
|
||||
err = -ENOENT;
|
||||
else if (!err)
|
||||
err = -ENOMEM;
|
||||
else
|
||||
err = ops->getnew(ns, params);
|
||||
} else {
|
||||
/* ipc object has been locked by ipc_findkey() */
|
||||
|
||||
if (flg & IPC_CREAT && flg & IPC_EXCL)
|
||||
err = -EEXIST;
|
||||
else {
|
||||
err = 0;
|
||||
if (ops->more_checks)
|
||||
err = ops->more_checks(ipcp, params);
|
||||
if (!err)
|
||||
err = ipc_check_perms(ipcp, ops, params);
|
||||
}
|
||||
ipc_unlock(ipcp);
|
||||
}
|
||||
mutex_unlock(&ids->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ipc_rmid - remove an IPC identifier
|
||||
* @ids: identifier set
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue