diff -r ab5eb3e7d582 -r cd2e9206a81f fs/Kconfig
--- a/fs/Kconfig	Sat Mar 20 12:41:12 2010 +0800
+++ b/fs/Kconfig	Mon Mar 22 19:57:54 2010 +0800
@@ -133,6 +133,13 @@
 
 	  If you don't know what Access Control Lists are, say N.
 
+config MQUEUE_POSIX_ACL
+       bool "Mqueue POSIX Access Control Lists support"
+       select GENERIC_ACL
+       help
+         Mqueue is a file system which is used to suport POSIX msg queue.
+	 Say y to get Access Control Lists support for mqueue file system.
+	  
 config HUGETLBFS
 	bool "HugeTLB file system support"
 	depends on X86 || IA64 || SPARC64 || (S390 && 64BIT) || \
diff -r ab5eb3e7d582 -r cd2e9206a81f include/linux/mqueue.h
--- a/include/linux/mqueue.h	Sat Mar 20 12:41:12 2010 +0800
+++ b/include/linux/mqueue.h	Mon Mar 22 19:57:54 2010 +0800
@@ -1,4 +1,5 @@
 /* Copyright (C) 2003 Krzysztof Benedyczak & Michal Wronski
+   Add ACL support by  Zhou Peng (ailvpeng25@gmail.com), 2010
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -50,4 +51,12 @@
 
 #define NOTIFY_COOKIE_LEN	32
 
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+int mqueue_check_acl(struct inode *inode, int mask);
+int mqueue_acl_init(struct inode *inode, struct inode *dir);
+
+extern struct xattr_handler mqueue_xattr_acl_access_handler;
+extern struct xattr_handler mqueue_xattr_acl_default_handler;
 #endif
+
+#endif
diff -r ab5eb3e7d582 -r cd2e9206a81f ipc/Makefile
--- a/ipc/Makefile	Sat Mar 20 12:41:12 2010 +0800
+++ b/ipc/Makefile	Mon Mar 22 19:57:54 2010 +0800
@@ -10,3 +10,4 @@
 obj-$(CONFIG_IPC_NS) += namespace.o
 obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
 
+obj-$(CONFIG_MQUEUE_POSIX_ACL) += mqueue_acl.o
diff -r ab5eb3e7d582 -r cd2e9206a81f ipc/mqueue.c
--- a/ipc/mqueue.c	Sat Mar 20 12:41:12 2010 +0800
+++ b/ipc/mqueue.c	Mon Mar 22 19:57:54 2010 +0800
@@ -10,6 +10,8 @@
  *
  * Audit:                   George Wilson           (ltcgcw@us.ibm.com)
  *
+ * ACL by  Zhou Peng (ailvpeng25@gmail.com), 2010
+ *
  * This file is released under the GPL.
  */
 
@@ -33,6 +35,8 @@
 #include <linux/pid.h>
 #include <linux/ipc_namespace.h>
 #include <linux/ima.h>
+#include <linux/generic_acl.h>
+#include <linux/xattr.h>
 
 #include <net/sock.h>
 #include "util.h"
@@ -77,6 +81,9 @@
 
 static const struct inode_operations mqueue_dir_inode_operations;
 static const struct file_operations mqueue_file_operations;
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+static const struct inode_operations mqueue_inode_operations;
+#endif
 static const struct super_operations mqueue_super_ops;
 static void remove_notification(struct mqueue_inode_info *info);
 
@@ -84,6 +91,53 @@
 
 static struct ctl_table_header * mq_sysctl_table;
 
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+/*
+ * Superblocks without xattr inode operations will get security.* xattr
+ * support from the VFS "for free". As soon as we have any other xattrs
+ * like ACLs, we also need to implement the security.* handlers at
+ * filesystem level, though.
+ */
+
+static size_t mqueue_xattr_security_list(struct inode *inode, char *list,
+					size_t list_len, const char *name,
+					size_t name_len)
+{
+	return security_inode_listsecurity(inode, list, list_len);
+}
+
+static int mqueue_xattr_security_get(struct inode *inode, const char *name,
+				    void *buffer, size_t size)
+{
+	if (strcmp(name, "") == 0)
+		return -EINVAL;
+	return xattr_getsecurity(inode, name, buffer, size);
+}
+
+static int mqueue_xattr_security_set(struct inode *inode, const char *name,
+				    const void *value, size_t size, int flags)
+{
+	if (strcmp(name, "") == 0)
+		return -EINVAL;
+	return security_inode_setsecurity(inode, name, value, size, flags);
+}
+
+static struct xattr_handler mqueue_xattr_security_handler = {
+	.prefix = XATTR_SECURITY_PREFIX,
+	.list   = mqueue_xattr_security_list,
+	.get    = mqueue_xattr_security_get,
+	.set    = mqueue_xattr_security_set,
+};
+
+
+static struct xattr_handler *mqueue_xattr_handlers[] = {
+	&mqueue_xattr_acl_access_handler,
+	&mqueue_xattr_acl_default_handler,
+	&mqueue_xattr_security_handler,
+	NULL
+};
+#endif
+
 static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode)
 {
 	return container_of(inode, struct mqueue_inode_info, vfs_inode);
@@ -121,12 +175,18 @@
 		inode->i_gid = current_fsgid();
 		inode->i_mtime = inode->i_ctime = inode->i_atime =
 				CURRENT_TIME;
-
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+		cache_no_acl(inode);
+#endif
+		
 		if (S_ISREG(mode)) {
 			struct mqueue_inode_info *info;
 			struct task_struct *p = current;
 			unsigned long mq_bytes, mq_msg_tblsz;
 
+#ifdef CONFIG_MQUEUE_POSIX_ACL			
+			inode->i_op = &mqueue_inode_operations;
+#endif
 			inode->i_fop = &mqueue_file_operations;
 			inode->i_size = FILENT_SIZE;
 			/* mqueue specific info */
@@ -195,6 +255,11 @@
 	sb->s_magic = MQUEUE_MAGIC;
 	sb->s_op = &mqueue_super_ops;
 
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+	sb->s_xattr = mqueue_xattr_handlers;
+	sb->s_flags |= MS_POSIXACL;
+#endif
+
 	inode = mqueue_get_inode(sb, ns, S_IFDIR | S_ISVTX | S_IRWXUGO,
 				NULL);
 	if (!inode) {
@@ -316,6 +381,13 @@
 		goto out_unlock;
 	}
 
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+	error = mqueue_acl_init(inode, dir);
+	if (error) {
+	    iput(inode);
+	    goto out_unlock;
+	}
+#endif	
 	put_ipc_ns(ipc_ns);
 	dir->i_size += DIRENT_SIZE;
 	dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
@@ -1216,6 +1288,23 @@
 	.lookup = simple_lookup,
 	.create = mqueue_create,
 	.unlink = mqueue_unlink,
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+	.setxattr    = generic_setxattr,
+	.getxattr    = generic_getxattr,
+	.listxattr   = generic_listxattr,
+	.removexattr = generic_removexattr,
+	.check_acl   = mqueue_check_acl,
+#endif
+};
+
+static const struct inode_operations mqueue_inode_operations = {
+#ifdef CONFIG_MQUEUE_POSIX_ACL
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= generic_listxattr,
+	.removexattr	= generic_removexattr,
+	.check_acl	= mqueue_check_acl,
+#endif
 };
 
 static const struct file_operations mqueue_file_operations = {
diff -r ab5eb3e7d582 -r cd2e9206a81f ipc/mqueue_acl.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipc/mqueue_acl.c	Mon Mar 22 19:57:54 2010 +0800
@@ -0,0 +1,172 @@
+/*
+ * ipc/mqueue_acl.c
+ *
+ * Copyright (C) 2010 ZhouPeng <ailvpeng25@gmail.com>
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+#include <linux/xattr.h>
+#include <linux/generic_acl.h>
+
+/**
+ * mqueue_get_acl  -   generic_acl_operations->getacl() operation
+ */
+static struct posix_acl *
+mqueue_get_acl(struct inode *inode, int type)
+{
+	struct posix_acl *acl = NULL;
+
+	spin_lock(&inode->i_lock);
+
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			acl = posix_acl_dup(inode->i_acl);
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			acl = posix_acl_dup(inode->i_default_acl);
+			break;
+	}
+	spin_unlock(&inode->i_lock);
+
+	return acl;
+}
+
+/**
+ * mqueue_set_acl  -   generic_acl_operations->setacl() operation
+ */
+static void
+mqueue_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+	struct posix_acl *free = NULL;
+
+	spin_lock(&inode->i_lock);
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			free = inode->i_acl;
+			inode->i_acl = posix_acl_dup(acl);
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			free = inode->i_default_acl;
+			inode->i_default_acl = posix_acl_dup(acl);
+			break;
+	}
+	spin_unlock(&inode->i_lock);
+	posix_acl_release(free);
+}
+
+struct generic_acl_operations mqueue_acl_ops = {
+	.getacl = mqueue_get_acl,
+	.setacl = mqueue_set_acl,
+};
+
+/**
+ * mqueue_list_acl_access, mqueue_get_acl_access, mqueue_set_acl_access,
+ * mqueue_xattr_acl_access_handler  -  plumbing code to implement the
+ * system.posix_acl_access xattr using the generic acl functions.
+ */
+
+static size_t
+mqueue_list_acl_access(struct inode *inode, char *list, size_t list_size,
+		      const char *name, size_t name_len)
+{
+	return generic_acl_list(inode, &mqueue_acl_ops, ACL_TYPE_ACCESS,
+				list, list_size);
+}
+
+static int
+mqueue_get_acl_access(struct inode *inode, const char *name, void *buffer,
+		     size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_get(inode, &mqueue_acl_ops, ACL_TYPE_ACCESS, buffer,
+			       size);
+}
+
+static int
+mqueue_set_acl_access(struct inode *inode, const char *name, const void *value,
+		     size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_set(inode, &mqueue_acl_ops, ACL_TYPE_ACCESS, value,
+			       size);
+}
+
+struct xattr_handler mqueue_xattr_acl_access_handler = {
+	.prefix = POSIX_ACL_XATTR_ACCESS,
+	.list	= mqueue_list_acl_access,
+	.get	= mqueue_get_acl_access,
+	.set	= mqueue_set_acl_access,
+};
+
+/**
+ * mqueue_list_acl_default, mqueue_get_acl_default, mqueue_set_acl_default,
+ * mqueue_xattr_acl_default_handler  -  plumbing code to implement the
+ * system.posix_acl_default xattr using the generic acl functions.
+ */
+
+static size_t
+mqueue_list_acl_default(struct inode *inode, char *list, size_t list_size,
+		       const char *name, size_t name_len)
+{
+	return generic_acl_list(inode, &mqueue_acl_ops, ACL_TYPE_DEFAULT,
+				list, list_size);
+}
+
+static int
+mqueue_get_acl_default(struct inode *inode, const char *name, void *buffer,
+		      size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_get(inode, &mqueue_acl_ops, ACL_TYPE_DEFAULT, buffer,
+			       size);
+}
+
+static int
+mqueue_set_acl_default(struct inode *inode, const char *name, const void *value,
+		      size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return generic_acl_set(inode, &mqueue_acl_ops, ACL_TYPE_DEFAULT, value,
+			       size);
+}
+
+struct xattr_handler mqueue_xattr_acl_default_handler = {
+	.prefix = POSIX_ACL_XATTR_DEFAULT,
+	.list	= mqueue_list_acl_default,
+	.get	= mqueue_get_acl_default,
+	.set	= mqueue_set_acl_default,
+};
+
+/**
+ * mqueue_acl_init  -  Inizialize the acl(s) of a new inode
+ */
+int
+mqueue_acl_init(struct inode *inode, struct inode *dir)
+{
+	return generic_acl_init(inode, dir, &mqueue_acl_ops);
+}
+
+/**
+ * mqueue_check_acl  -  check_acl() callback for generic_permission()
+ */
+int
+mqueue_check_acl(struct inode *inode, int mask)
+{
+	struct posix_acl *acl = mqueue_get_acl(inode, ACL_TYPE_ACCESS);
+
+	if (acl) {
+		int error = posix_acl_permission(inode, acl, mask);
+		posix_acl_release(acl);
+		return error;
+	}
+	return -EAGAIN;
+}
