mqueue: fold mq_attr_ok() into mqueue_get_inode()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
af4a5372e4
commit
05c1b29038
71
ipc/mqueue.c
71
ipc/mqueue.c
|
@ -270,13 +270,30 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
|
|||
* that means the min(mq_maxmsg, max_priorities) * struct
|
||||
* posix_msg_tree_node.
|
||||
*/
|
||||
|
||||
ret = -EINVAL;
|
||||
if (info->attr.mq_maxmsg <= 0 || info->attr.mq_msgsize <= 0)
|
||||
goto out_inode;
|
||||
if (capable(CAP_SYS_RESOURCE)) {
|
||||
if (info->attr.mq_maxmsg > HARD_MSGMAX ||
|
||||
info->attr.mq_msgsize > HARD_MSGSIZEMAX)
|
||||
goto out_inode;
|
||||
} else {
|
||||
if (info->attr.mq_maxmsg > ipc_ns->mq_msg_max ||
|
||||
info->attr.mq_msgsize > ipc_ns->mq_msgsize_max)
|
||||
goto out_inode;
|
||||
}
|
||||
ret = -EOVERFLOW;
|
||||
/* check for overflow */
|
||||
if (info->attr.mq_msgsize > ULONG_MAX/info->attr.mq_maxmsg)
|
||||
goto out_inode;
|
||||
mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) +
|
||||
min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) *
|
||||
sizeof(struct posix_msg_tree_node);
|
||||
|
||||
mq_bytes = mq_treesize + (info->attr.mq_maxmsg *
|
||||
info->attr.mq_msgsize);
|
||||
|
||||
mq_bytes = info->attr.mq_maxmsg * info->attr.mq_msgsize;
|
||||
if (mq_bytes + mq_treesize < mq_bytes)
|
||||
goto out_inode;
|
||||
mq_bytes += mq_treesize;
|
||||
spin_lock(&mq_lock);
|
||||
if (u->mq_bytes + mq_bytes < u->mq_bytes ||
|
||||
u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
|
||||
|
@ -696,34 +713,6 @@ static void remove_notification(struct mqueue_inode_info *info)
|
|||
info->notify_user_ns = NULL;
|
||||
}
|
||||
|
||||
static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
|
||||
{
|
||||
int mq_treesize;
|
||||
unsigned long total_size;
|
||||
|
||||
if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
|
||||
return -EINVAL;
|
||||
if (capable(CAP_SYS_RESOURCE)) {
|
||||
if (attr->mq_maxmsg > HARD_MSGMAX ||
|
||||
attr->mq_msgsize > HARD_MSGSIZEMAX)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (attr->mq_maxmsg > ipc_ns->mq_msg_max ||
|
||||
attr->mq_msgsize > ipc_ns->mq_msgsize_max)
|
||||
return -EINVAL;
|
||||
}
|
||||
/* check for overflow */
|
||||
if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg)
|
||||
return -EOVERFLOW;
|
||||
mq_treesize = attr->mq_maxmsg * sizeof(struct msg_msg) +
|
||||
min_t(unsigned int, attr->mq_maxmsg, MQ_PRIO_MAX) *
|
||||
sizeof(struct posix_msg_tree_node);
|
||||
total_size = attr->mq_maxmsg * attr->mq_msgsize;
|
||||
if (total_size + mq_treesize < total_size)
|
||||
return -EOVERFLOW;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoked when creating a new queue via sys_mq_open
|
||||
*/
|
||||
|
@ -731,24 +720,6 @@ static int do_create(struct ipc_namespace *ipc_ns, struct inode *dir,
|
|||
struct path *path, int oflag, umode_t mode,
|
||||
struct mq_attr *attr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (attr) {
|
||||
ret = mq_attr_ok(ipc_ns, attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
struct mq_attr def_attr;
|
||||
|
||||
def_attr.mq_maxmsg = min(ipc_ns->mq_msg_max,
|
||||
ipc_ns->mq_msg_default);
|
||||
def_attr.mq_msgsize = min(ipc_ns->mq_msgsize_max,
|
||||
ipc_ns->mq_msgsize_default);
|
||||
ret = mq_attr_ok(ipc_ns, &def_attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return vfs_mkobj(path->dentry, mode & ~current_umask(),
|
||||
mqueue_create_attr, attr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue