diff options
Diffstat (limited to 'ipc/mqueue.c')
| -rw-r--r-- | ipc/mqueue.c | 107 | 
1 files changed, 54 insertions, 53 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 14fb6d67e6a..d43c30f72f1 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -115,69 +115,70 @@ static struct inode *mqueue_get_inode(struct super_block *sb,  	struct inode *inode;  	inode = new_inode(sb); -	if (inode) { -		inode->i_ino = get_next_ino(); -		inode->i_mode = mode; -		inode->i_uid = current_fsuid(); -		inode->i_gid = current_fsgid(); -		inode->i_mtime = inode->i_ctime = inode->i_atime = -				CURRENT_TIME; +	if (!inode) +		goto err; -		if (S_ISREG(mode)) { -			struct mqueue_inode_info *info; -			struct task_struct *p = current; -			unsigned long mq_bytes, mq_msg_tblsz; +	inode->i_ino = get_next_ino(); +	inode->i_mode = mode; +	inode->i_uid = current_fsuid(); +	inode->i_gid = current_fsgid(); +	inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME; -			inode->i_fop = &mqueue_file_operations; -			inode->i_size = FILENT_SIZE; -			/* mqueue specific info */ -			info = MQUEUE_I(inode); -			spin_lock_init(&info->lock); -			init_waitqueue_head(&info->wait_q); -			INIT_LIST_HEAD(&info->e_wait_q[0].list); -			INIT_LIST_HEAD(&info->e_wait_q[1].list); -			info->notify_owner = NULL; -			info->qsize = 0; -			info->user = NULL;	/* set when all is ok */ -			memset(&info->attr, 0, sizeof(info->attr)); -			info->attr.mq_maxmsg = ipc_ns->mq_msg_max; -			info->attr.mq_msgsize = ipc_ns->mq_msgsize_max; -			if (attr) { -				info->attr.mq_maxmsg = attr->mq_maxmsg; -				info->attr.mq_msgsize = attr->mq_msgsize; -			} -			mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *); -			info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); -			if (!info->messages) -				goto out_inode; +	if (S_ISREG(mode)) { +		struct mqueue_inode_info *info; +		struct task_struct *p = current; +		unsigned long mq_bytes, mq_msg_tblsz; -			mq_bytes = (mq_msg_tblsz + -				(info->attr.mq_maxmsg * info->attr.mq_msgsize)); +		inode->i_fop = &mqueue_file_operations; +		inode->i_size = FILENT_SIZE; +		/* mqueue specific info */ +		info = MQUEUE_I(inode); +		spin_lock_init(&info->lock); +		init_waitqueue_head(&info->wait_q); +		INIT_LIST_HEAD(&info->e_wait_q[0].list); +		INIT_LIST_HEAD(&info->e_wait_q[1].list); +		info->notify_owner = NULL; +		info->qsize = 0; +		info->user = NULL;	/* set when all is ok */ +		memset(&info->attr, 0, sizeof(info->attr)); +		info->attr.mq_maxmsg = ipc_ns->mq_msg_max; +		info->attr.mq_msgsize = ipc_ns->mq_msgsize_max; +		if (attr) { +			info->attr.mq_maxmsg = attr->mq_maxmsg; +			info->attr.mq_msgsize = attr->mq_msgsize; +		} +		mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *); +		info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); +		if (!info->messages) +			goto out_inode; -			spin_lock(&mq_lock); -			if (u->mq_bytes + mq_bytes < u->mq_bytes || -		 	    u->mq_bytes + mq_bytes > -			    task_rlimit(p, RLIMIT_MSGQUEUE)) { -				spin_unlock(&mq_lock); -				/* mqueue_evict_inode() releases info->messages */ -				goto out_inode; -			} -			u->mq_bytes += mq_bytes; -			spin_unlock(&mq_lock); +		mq_bytes = (mq_msg_tblsz + +			(info->attr.mq_maxmsg * info->attr.mq_msgsize)); -			/* all is ok */ -			info->user = get_uid(u); -		} else if (S_ISDIR(mode)) { -			inc_nlink(inode); -			/* Some things misbehave if size == 0 on a directory */ -			inode->i_size = 2 * DIRENT_SIZE; -			inode->i_op = &mqueue_dir_inode_operations; -			inode->i_fop = &simple_dir_operations; +		spin_lock(&mq_lock); +		if (u->mq_bytes + mq_bytes < u->mq_bytes || +		    u->mq_bytes + mq_bytes > task_rlimit(p, RLIMIT_MSGQUEUE)) { +			spin_unlock(&mq_lock); +			/* mqueue_evict_inode() releases info->messages */ +			goto out_inode;  		} +		u->mq_bytes += mq_bytes; +		spin_unlock(&mq_lock); + +		/* all is ok */ +		info->user = get_uid(u); +	} else if (S_ISDIR(mode)) { +		inc_nlink(inode); +		/* Some things misbehave if size == 0 on a directory */ +		inode->i_size = 2 * DIRENT_SIZE; +		inode->i_op = &mqueue_dir_inode_operations; +		inode->i_fop = &simple_dir_operations;  	} +  	return inode;  out_inode:  	iput(inode); +err:  	return NULL;  }  |