/* * POSIX message queues filesystem for Linux. * * Copyright (C) 2003,2004 Krzysztof Benedyczak (golbi@mat.uni.torun.pl) * Michal Wronski (michal.wronski@gmail.com) * * Spinlocks: Mohamed Abbas (abbas.mohamed@intel.com) * Lockless receive & send, fd based notify: * Manfred Spraul (manfred@colorfullife.com) * * Audit: George Wilson (ltcgcw@us.ibm.com) * * This file is released under the GPL. */#include<linux/capability.h>#include<linux/init.h>#include<linux/pagemap.h>#include<linux/file.h>#include<linux/mount.h>#include<linux/namei.h>#include<linux/sysctl.h>#include<linux/poll.h>#include<linux/mqueue.h>#include<linux/msg.h>#include<linux/skbuff.h>#include<linux/netlink.h>#include<linux/syscalls.h>#include<linux/audit.h>#include<linux/signal.h>#include<linux/mutex.h>#include<linux/nsproxy.h>#include<linux/pid.h>#include<linux/ipc_namespace.h>#include<linux/ima.h>#include<net/sock.h>#include"util.h"#define MQUEUE_MAGIC 0x19800202#define DIRENT_SIZE 20#define FILENT_SIZE 80#define SEND 0#define RECV 1#define STATE_NONE 0#define STATE_PENDING 1#define STATE_READY 2structext_wait_queue{/* queue of sleeping tasks */structtask_struct*task;structlist_headlist;structmsg_msg*msg;/* ptr of loaded message */intstate;/* one of STATE_* values */};structmqueue_inode_info{spinlock_tlock;structinodevfs_inode;wait_queue_head_twait_q;structmsg_msg**messages;structmq_attrattr;structsigeventnotify;structpid*notify_owner;structuser_struct*user;/* user who created, for accounting */structsock*notify_sock;structsk_buff*notify_cookie;/* for tasks waiting for free space and messages, respectively */structext_wait_queuee_wait_q[2];unsignedlongqsize;/* size of queue in memory (sum of all msgs) */};staticconststructinode_operationsmqueue_dir_inode_operations;staticconststructfile_operationsmqueue_file_operations;staticconststructsuper_operationsmqueue_super_ops;staticvoidremove_notification(structmqueue_inode_info*info);staticstructkmem_cache*mqueue_inode_cachep;staticstructctl_table_header*mq_sysctl_table;staticinlinestructmqueue_inode_info*MQUEUE_I(structinode*inode){returncontainer_of(inode,structmqueue_inode_info,vfs_inode);}/* * This routine should be called with the mq_lock held. */staticinlinestructipc_namespace*__get_ns_from_inode(structinode*inode){returnget_ipc_ns(inode->i_sb->s_fs_info);}staticstructipc_namespace*get_ns_from_inode(structinode*inode){structipc_namespace*ns;spin_lock(&mq_lock);ns=__get_ns_from_inode(inode);spin_unlock(&mq_lock);