[Btrfs-devel] [PATCH] Add btrfs acl checking

only flyer onlyflyer at gmail.com
Sat Jan 19 05:47:17 PST 2008


Hi:
This patch add btrfs acl checking. It makes btrfs's acl checking
really work if you mount btrfs by using "acl" option, e.g. mount -t
btrfs -o acl /dev/hda1 /mnt/

Thanks
LiuHui

diff -r 6c243ad8dddf acl.c
--- a/acl.c	Fri Jan 18 10:54:22 2008 -0500
+++ b/acl.c	Sat Jan 19 21:38:02 2008 +0800
@@ -26,6 +26,35 @@
 #define is_owner_or_cap(inode)	\
 	((current->fsuid == (inode)->i_uid) || capable(CAP_FOWNER))
 #endif
+
+struct posix_acl *btrfs_get_posix_acl(struct inode *inode, int type)
+{
+        int ret, len;
+        char *value = NULL;
+        struct posix_acl *acl;
+
+        len = btrfs_xattr_get(inode, type, "", NULL, 0);
+        if (len > 0) {
+                value = kmalloc(len, GFP_KERNEL);
+                if (!value) {
+                        return ERR_PTR(-ENOMEM);
+                }
+
+        } else {
+                return NULL;
+        }
+        ret = btrfs_xattr_get(inode, type, "", value, len);
+        if (ret > 0) {
+                acl = posix_acl_from_xattr(value, len);
+        } else if (-ENODATA == ret) {
+                acl = NULL;
+        } else {
+                acl = ERR_PTR(ret);
+        }
+
+        kfree(value);
+        return acl;
+}

 static int btrfs_xattr_set_acl(struct inode *inode, int type,
 			       const void *value, size_t size)
diff -r 6c243ad8dddf ctree.h
--- a/ctree.h	Fri Jan 18 10:54:22 2008 -0500
+++ b/ctree.h	Sat Jan 19 21:38:02 2008 +0800
@@ -446,6 +446,7 @@ struct btrfs_root {
 #define BTRFS_MOUNT_NODATACOW		(1 << 1)
 #define BTRFS_MOUNT_NOBARRIER		(1 << 2)
 #define BTRFS_MOUNT_SSD			(1 << 3)
+#define BTRFS_MOUNT_POSIX_ACL		(1 << 4)

 #define btrfs_clear_opt(o, opt)		((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)		((o) |= BTRFS_MOUNT_##opt)
diff -r 6c243ad8dddf inode.c
--- a/inode.c	Fri Jan 18 10:54:22 2008 -0500
+++ b/inode.c	Sat Jan 19 21:38:02 2008 +0800
@@ -33,12 +33,16 @@
 #include <linux/bit_spinlock.h>
 #include <linux/version.h>
 #include <linux/xattr.h>
+#include <linux/posix_acl.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
 #include "btrfs_inode.h"
 #include "ioctl.h"
 #include "print-tree.h"
+#include "xattr.h"
+
+extern struct posix_acl *btrfs_get_posix_acl(struct inode *inode, int type);

 struct btrfs_iget_args {
 	u64 ino;
@@ -2886,12 +2890,29 @@ out_fail:
 	btrfs_throttle(root);
 	return err;
 }
+
+static int btrfs_check_acl(struct inode *inode, int mask)
+{
+        struct posix_acl *acl;
+        acl = btrfs_get_posix_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS);
+
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl) {
+		int error = posix_acl_permission(inode, acl, mask);
+		posix_acl_release(acl);
+		return error;
+	}
+
+	return -EAGAIN;
+}
+
 static int btrfs_permission(struct inode *inode, int mask,
 			    struct nameidata *nd)
 {
 	if (btrfs_test_flag(inode, READONLY) && (mask & MAY_WRITE))
 		return -EACCES;
-	return generic_permission(inode, mask, NULL);
+	return generic_permission(inode, mask, btrfs_check_acl);
 }

 static struct inode_operations btrfs_dir_inode_operations = {
diff -r 6c243ad8dddf super.c
--- a/super.c	Fri Jan 18 10:54:22 2008 -0500
+++ b/super.c	Sat Jan 19 21:38:02 2008 +0800
@@ -64,7 +64,7 @@ static void btrfs_put_super (struct supe

 enum {
 	Opt_subvol, Opt_nodatasum, Opt_nodatacow, Opt_max_extent,
-	Opt_alloc_start, Opt_nobarrier, Opt_ssd, Opt_err,
+	Opt_alloc_start, Opt_nobarrier, Opt_ssd, Opt_posix_acl, Opt_err,
 };

 static match_table_t tokens = {
@@ -75,6 +75,7 @@ static match_table_t tokens = {
 	{Opt_max_extent, "max_extent=%s"},
 	{Opt_alloc_start, "alloc_start=%s"},
 	{Opt_ssd, "ssd"},
+        {Opt_posix_acl, "acl"},
 	{Opt_err, NULL}
 };

@@ -162,6 +163,14 @@ static int parse_options (char * options
 				btrfs_set_opt(info->mount_opt, NOBARRIER);
 			}
 			break;
+
+                case Opt_posix_acl:
+                        if (info) {
+                                printk("btrfs: enabling posix acl\n");
+                                btrfs_set_opt(info->mount_opt, POSIX_ACL);
+                        }
+                        break;
+
 		case Opt_max_extent:
 			if (info) {
 				char *num = match_strdup(&args[0]);
@@ -247,6 +256,12 @@ static int btrfs_fill_super(struct super
 	}

 	parse_options((char *)data, tree_root, NULL);
+
+        if (tree_root->fs_info->mount_opt & BTRFS_MOUNT_POSIX_ACL) {
+                sb->s_flags |= MS_POSIXACL;
+        } else {
+                sb->s_flags = sb->s_flags & ~MS_POSIXACL;
+        }

 	/* this does the super kobj at the same time */
 	err = btrfs_sysfs_add_super(tree_root->fs_info);



More information about the Btrfs-devel mailing list