IPC之msgutil.c源码解读
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* linux/ipc/msgutil.c
* Copyright (C) 1999, 2004 Manfred Spraul
*/ #include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/ipc.h>
#include <linux/msg.h>
#include <linux/ipc_namespace.h>
#include <linux/utsname.h>
#include <linux/proc_ns.h>
#include <linux/uaccess.h>
#include <linux/sched.h> #include "util.h" DEFINE_SPINLOCK(mq_lock); /*
* The next 2 defines are here bc this is the only file
* compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
* and not CONFIG_IPC_NS.
*/
struct ipc_namespace init_ipc_ns = {
.count = REFCOUNT_INIT(1),
.user_ns = &init_user_ns,
.ns.inum = PROC_IPC_INIT_INO,
#ifdef CONFIG_IPC_NS
.ns.ops = &ipcns_operations,
#endif
}; struct msg_msgseg {
struct msg_msgseg *next;
/* the next part of the message follows immediately */
}; #define DATALEN_MSG ((size_t)PAGE_SIZE-sizeof(struct msg_msg))
#define DATALEN_SEG ((size_t)PAGE_SIZE-sizeof(struct msg_msgseg)) static struct msg_msg *alloc_msg(size_t len)
{
struct msg_msg *msg;
struct msg_msgseg **pseg;
size_t alen; alen = min(len, DATALEN_MSG);
msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL_ACCOUNT);
if (msg == NULL)
return NULL; msg->next = NULL;
msg->security = NULL; len -= alen;
pseg = &msg->next;
while (len > 0) {
struct msg_msgseg *seg; cond_resched(); alen = min(len, DATALEN_SEG);
seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL_ACCOUNT);
if (seg == NULL)
goto out_err;
*pseg = seg;
seg->next = NULL;
pseg = &seg->next;
len -= alen;
} return msg; out_err:
free_msg(msg);
return NULL;
} struct msg_msg *load_msg(const void __user *src, size_t len)
{
struct msg_msg *msg;
struct msg_msgseg *seg;
int err = -EFAULT;
size_t alen; msg = alloc_msg(len);
if (msg == NULL)
return ERR_PTR(-ENOMEM); alen = min(len, DATALEN_MSG);
if (copy_from_user(msg + 1, src, alen))
goto out_err; for (seg = msg->next; seg != NULL; seg = seg->next) {
len -= alen;
src = (char __user *)src + alen;
alen = min(len, DATALEN_SEG);
if (copy_from_user(seg + 1, src, alen))
goto out_err;
} err = security_msg_msg_alloc(msg);
if (err)
goto out_err; return msg; out_err:
free_msg(msg);
return ERR_PTR(err);
}
#ifdef CONFIG_CHECKPOINT_RESTORE
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
{
struct msg_msgseg *dst_pseg, *src_pseg;
size_t len = src->m_ts;
size_t alen; if (src->m_ts > dst->m_ts)
return ERR_PTR(-EINVAL); alen = min(len, DATALEN_MSG);
memcpy(dst + 1, src + 1, alen); for (dst_pseg = dst->next, src_pseg = src->next;
src_pseg != NULL;
dst_pseg = dst_pseg->next, src_pseg = src_pseg->next) { len -= alen;
alen = min(len, DATALEN_SEG);
memcpy(dst_pseg + 1, src_pseg + 1, alen);
} dst->m_type = src->m_type;
dst->m_ts = src->m_ts; return dst;
}
#else
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
{
return ERR_PTR(-ENOSYS);
}
#endif
int store_msg(void __user *dest, struct msg_msg *msg, size_t len)
{
size_t alen;
struct msg_msgseg *seg; alen = min(len, DATALEN_MSG);
if (copy_to_user(dest, msg + 1, alen))
return -1; for (seg = msg->next; seg != NULL; seg = seg->next) {
len -= alen;
dest = (char __user *)dest + alen;
alen = min(len, DATALEN_SEG);
if (copy_to_user(dest, seg + 1, alen))
return -1;
}
return 0;
} void free_msg(struct msg_msg *msg)
{
struct msg_msgseg *seg; security_msg_msg_free(msg); seg = msg->next;
kfree(msg);
while (seg != NULL) {
struct msg_msgseg *tmp = seg->next; cond_resched();
kfree(seg);
seg = tmp;
}
}
IPC之msgutil.c源码解读的更多相关文章
- IPC之mqueue.c源码解读
队列的意思应该大家都清楚,不过还有有一些细节的地方不知道,下面是一个队列的源码,因该说这是队列的一部分,不是全部.而且是linux中队列,其他各种OS中队列大同小异. /* * POSIX messa ...
- IPC之ipc_sysctl.c源码解读
// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2007 * * Author: Eric Biederman <ebie ...
- IPC之util.h源码解读
/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/ipc/util.h * Copyright (C) 1999 Christoph Rohland ...
- IPC之util.c源码解读
// SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/util.c * Copyright (C) 1992 Krishna Balasubramani ...
- IPC之syscall.c源码解读
// SPDX-License-Identifier: GPL-2.0 /* * sys_ipc() is the old de-multiplexer for the SysV IPC calls. ...
- IPC之shm.c源码解读
// SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/shm.c * Copyright (C) 1992, 1993 Krishna Balasubr ...
- IPC之sem.c源码解读
// SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/sem.c * Copyright (C) 1992 Krishna Balasubramania ...
- IPC之namespace.c源码解读
// SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/namespace.c * Copyright (C) 2006 Pavel Emelyanov ...
- IPC之msg.c源码解读
// SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/msg.c * Copyright (C) 1992 Krishna Balasubramania ...
随机推荐
- innodb 隔离等级
前一段时间参加了一个国内知名公司的面试,被问及对数据库的了解,自感还不错,可谁知在隔离等级这种基本概念的点翻个船,也不是因为完全不懂,而是本来这里就比较晦涩,加之具体上次看这里的东西时候已经过了一年多 ...
- Linux学习笔记:shell
目录 通配符 特殊符号 变量 环境变量 默认变量 shell script case if for until while function 本文更新于2019-08-23. 通配符 *:0个至无穷多 ...
- windows端口映射
1. 查看netsh interface portproxy show all 2. 添加端口映射转发netsh interface portproxy add v4tov4 listenaddres ...
- python 安装第三方模块的各种方法
whl包的安装:pip install **.whl(要有pip 和 下载好的whl文件) tar.gz包的安装:python setup.py install (先将tar.gz解压到指定文件夹,在 ...
- 《Java语言程序设计》第三讲类与对象“动手动脑”
一.以下代码为何无法通过编译?哪儿出错了? 答: 如果类提供了一个自定义的构造方法,将导致系统不再提供默认构造方法. 二. (1)以下代码输出结果是什么? package xy; public cla ...
- 【miscellaneous】单播、广播和多播IP地址
转自:http://www.cnblogs.com/gaoxing/archive/2012/02/19/2358484.html 除地址类别外,还可根据传输的消息特征将IP地址分为单播.广播或多播. ...
- kubenetes 的svc从ClusterPort 改为NodePort
1.yaml文件如下 spec: clusterIP: 10.233.43.125 ports: - name: http-metrics port: protocol: TCP targetPort ...
- python列表一
1.列表数据类型 列表是一个值,它包含多个值构成,也可包含其他列表,其内的表项用逗号分隔 列表值:作为一个值可以保存在变量中,或传递给函数,像所有其他值一样. #不是指括号内的值 表项:列表中的值, ...
- ByteArrayInputStream类
一.说明 哈哈,这是学习Java之路的第一篇博文.虽然说接触学习Java有一段时间了,但是对流的概念一直并不是很清楚.也看了很多资料,但是感觉还是非常的抽象很难去理解.但是流又是Java中很重要的一部 ...
- C++中的bool类型
1.C++中的布尔类型 (1)C++在C语言的基础类型系统之上增加了bool: 1)C语言中,没有bool类型存在,往往都是用整型代替bool类型,常用0表示假,1表示真: 2)bool本来就有这样的 ...