Hello, This patch only fixes ACls setting and getting, ACLs still have no effect on access checks. Regards YZ --- diff -r 067ba546ac2c acl.c --- a/acl.c Wed Jan 09 15:55:33 2008 -0500 +++ b/acl.c Fri Jan 11 19:39:42 2008 +0800 @@ -23,51 +23,26 @@ #include "ctree.h" #include "xattr.h" -/* - * FIXME: At this point this is all place holder stuff, we just return - * -EOPNOTSUPP so cp won't complain when it tries to copy over a file with an - * acl on it. - */ - -static int btrfs_xattr_acl_access_get(struct inode *inode, const char *name, - void *value, size_t size) -{ - /* - return btrfs_xattr_get(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, name, - value, size); - */ - return -EOPNOTSUPP; +#define BTRFS_XATTR_SETGET_FUNCS(name, index) \ +static int btrfs_xattr_##name##_get(struct inode *inode, \ + const char *name, void *value, \ + size_t size) \ +{ \ + if (*name != '\0') \ + return -EINVAL; \ + return btrfs_xattr_get(inode, index, name, value, size); \ +} \ +static int btrfs_xattr_##name##_set(struct inode *inode, \ + const char *name, const void *value,\ + size_t size, int flags) \ +{ \ + if (*name != '\0') \ + return -EINVAL; \ + return btrfs_xattr_set(inode, index, name, value, size, flags); \ } -static int btrfs_xattr_acl_access_set(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - /* - return btrfs_xattr_set(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, name, - value, size, flags); - */ - return -EOPNOTSUPP; -} - -static int btrfs_xattr_acl_default_get(struct inode *inode, const char *name, - void *value, size_t size) -{ - /* - return btrfs_xattr_get(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, - name, value, size); - */ - return -EOPNOTSUPP; -} - -static int btrfs_xattr_acl_default_set(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - /* - return btrfs_xattr_set(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, - name, value, size, flags); - */ - return -EOPNOTSUPP; -} +BTRFS_XATTR_SETGET_FUNCS(acl_access, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS) +BTRFS_XATTR_SETGET_FUNCS(acl_default, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT) struct xattr_handler btrfs_xattr_acl_default_handler = { .prefix = POSIX_ACL_XATTR_DEFAULT, diff -r 067ba546ac2c dir-item.c --- a/dir-item.c Wed Jan 09 15:55:33 2008 -0500 +++ b/dir-item.c Fri Jan 11 19:39:42 2008 +0800 @@ -77,6 +77,10 @@ int btrfs_insert_xattr_item(struct btrfs if (!path) return -ENOMEM; + if (name_len + data_len + sizeof(struct btrfs_dir_item) > + BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item)) + return -E2BIG; + data_size = sizeof(*dir_item) + name_len + data_len; dir_item = insert_with_overflow(trans, root, path, &key, data_size, name, name_len); diff -r 067ba546ac2c xattr.c --- a/xattr.c Wed Jan 09 15:55:33 2008 -0500 +++ b/xattr.c Fri Jan 11 19:39:42 2008 +0800 @@ -142,10 +142,6 @@ ssize_t btrfs_xattr_get(struct inode *in if (!handler) return -EOPNOTSUPP; - /* just in case... */ - if (*attr_name == '\0') - return -EINVAL; - name = get_name(attr_name, name_index); if (!name) return -ENOMEM; @@ -204,10 +200,6 @@ int btrfs_xattr_set(struct inode *inode, if (!handler) return -EOPNOTSUPP; - - /* just in case... */ - if (*attr_name == '\0') - return -EINVAL; name = get_name(attr_name, name_index); if (!name) @@ -454,12 +446,16 @@ static int btrfs_xattr_##name##_get(stru const char *name, void *value, \ size_t size) \ { \ + if (*name == '\0') \ + return -EINVAL; \ return btrfs_xattr_get(inode, index, name, value, size); \ } \ static int btrfs_xattr_##name##_set(struct inode *inode, \ const char *name, const void *value,\ size_t size, int flags) \ { \ + if (*name == '\0') \ + return -EINVAL; \ return btrfs_xattr_set(inode, index, name, value, size, flags); \ } \
Hello, There is a mistake in previous patch, the code should return ENOSPC instead of E2BIG when xattr is too large. Regards YZ --- diff -r 067ba546ac2c acl.c --- a/acl.c Wed Jan 09 15:55:33 2008 -0500 +++ b/acl.c Sat Jan 12 00:47:54 2008 +0800 @@ -23,51 +23,26 @@ #include "ctree.h" #include "xattr.h" -/* - * FIXME: At this point this is all place holder stuff, we just return - * -EOPNOTSUPP so cp won't complain when it tries to copy over a file with an - * acl on it. - */ - -static int btrfs_xattr_acl_access_get(struct inode *inode, const char *name, - void *value, size_t size) -{ - /* - return btrfs_xattr_get(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, name, - value, size); - */ - return -EOPNOTSUPP; +#define BTRFS_XATTR_SETGET_FUNCS(name, index) \ +static int btrfs_xattr_##name##_get(struct inode *inode, \ + const char *name, void *value, \ + size_t size) \ +{ \ + if (*name != '\0') \ + return -EINVAL; \ + return btrfs_xattr_get(inode, index, name, value, size); \ +} \ +static int btrfs_xattr_##name##_set(struct inode *inode, \ + const char *name, const void *value,\ + size_t size, int flags) \ +{ \ + if (*name != '\0') \ + return -EINVAL; \ + return btrfs_xattr_set(inode, index, name, value, size, flags); \ } -static int btrfs_xattr_acl_access_set(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - /* - return btrfs_xattr_set(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, name, - value, size, flags); - */ - return -EOPNOTSUPP; -} - -static int btrfs_xattr_acl_default_get(struct inode *inode, const char *name, - void *value, size_t size) -{ - /* - return btrfs_xattr_get(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, - name, value, size); - */ - return -EOPNOTSUPP; -} - -static int btrfs_xattr_acl_default_set(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - /* - return btrfs_xattr_set(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, - name, value, size, flags); - */ - return -EOPNOTSUPP; -} +BTRFS_XATTR_SETGET_FUNCS(acl_access, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS) +BTRFS_XATTR_SETGET_FUNCS(acl_default, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT) struct xattr_handler btrfs_xattr_acl_default_handler = { .prefix = POSIX_ACL_XATTR_DEFAULT, diff -r 067ba546ac2c dir-item.c --- a/dir-item.c Wed Jan 09 15:55:33 2008 -0500 +++ b/dir-item.c Sat Jan 12 00:47:54 2008 +0800 @@ -77,6 +77,10 @@ int btrfs_insert_xattr_item(struct btrfs if (!path) return -ENOMEM; + if (name_len + data_len + sizeof(struct btrfs_dir_item) > + BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item)) + return -ENOSPC; + data_size = sizeof(*dir_item) + name_len + data_len; dir_item = insert_with_overflow(trans, root, path, &key, data_size, name, name_len); diff -r 067ba546ac2c xattr.c --- a/xattr.c Wed Jan 09 15:55:33 2008 -0500 +++ b/xattr.c Sat Jan 12 00:47:54 2008 +0800 @@ -142,10 +142,6 @@ ssize_t btrfs_xattr_get(struct inode *in if (!handler) return -EOPNOTSUPP; - /* just in case... */ - if (*attr_name == '\0') - return -EINVAL; - name = get_name(attr_name, name_index); if (!name) return -ENOMEM; @@ -204,10 +200,6 @@ int btrfs_xattr_set(struct inode *inode, if (!handler) return -EOPNOTSUPP; - - /* just in case... */ - if (*attr_name == '\0') - return -EINVAL; name = get_name(attr_name, name_index); if (!name) @@ -454,12 +446,16 @@ static int btrfs_xattr_##name##_get(stru const char *name, void *value, \ size_t size) \ { \ + if (*name == '\0') \ + return -EINVAL; \ return btrfs_xattr_get(inode, index, name, value, size); \ } \ static int btrfs_xattr_##name##_set(struct inode *inode, \ const char *name, const void *value,\ size_t size, int flags) \ { \ + if (*name == '\0') \ + return -EINVAL; \ return btrfs_xattr_set(inode, index, name, value, size, flags); \ } \
Hello, Next round of patch, this version adds validity checks. As stated in previous one, the patch only fixes ACls setting and getting (ACLs still have no effect on access checks). Regards YZ --- diff -r 067ba546ac2c acl.c --- a/acl.c Wed Jan 09 15:55:33 2008 -0500 +++ b/acl.c Mon Jan 14 14:25:50 2008 +0800 @@ -23,50 +23,71 @@ #include "ctree.h" #include "xattr.h" -/* - * FIXME: At this point this is all place holder stuff, we just return - * -EOPNOTSUPP so cp won't complain when it tries to copy over a file with an - * acl on it. - */ +static int btrfs_xattr_set_acl(struct inode *inode, int type, + const void *value, size_t size) +{ + int ret = 0; + struct posix_acl *acl; + + if (!is_owner_or_cap(inode)) + return -EPERM; + if (value) { + acl = posix_acl_from_xattr(value, size); + if (acl == NULL) { + value = NULL; + size = 0; + } else if (IS_ERR(acl)) { + ret = PTR_ERR(acl); + } else { + ret = posix_acl_valid(acl); + posix_acl_release(acl); + } + if (ret) + return ret; + } + return btrfs_xattr_set(inode, type, "", value, size, 0); +} + +static int btrfs_xattr_get_acl(struct inode *inode, int type, + void *value, size_t size) +{ + return btrfs_xattr_get(inode, type, "", value, size); +} static int btrfs_xattr_acl_access_get(struct inode *inode, const char *name, void *value, size_t size) { - /* - return btrfs_xattr_get(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, name, - value, size); - */ - return -EOPNOTSUPP; + if (*name != '\0') + return -EINVAL; + return btrfs_xattr_get_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, + value, size); } static int btrfs_xattr_acl_access_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - /* - return btrfs_xattr_set(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, name, - value, size, flags); - */ - return -EOPNOTSUPP; + if (*name != '\0') + return -EINVAL; + return btrfs_xattr_set_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS, + value, size); } static int btrfs_xattr_acl_default_get(struct inode *inode, const char *name, void *value, size_t size) { - /* - return btrfs_xattr_get(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, - name, value, size); - */ - return -EOPNOTSUPP; + if (*name != '\0') + return -EINVAL; + return btrfs_xattr_get_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, + value, size); } static int btrfs_xattr_acl_default_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - /* - return btrfs_xattr_set(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, - name, value, size, flags); - */ - return -EOPNOTSUPP; + if (*name != '\0') + return -EINVAL; + return btrfs_xattr_set_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT, + value, size); } struct xattr_handler btrfs_xattr_acl_default_handler = { diff -r 067ba546ac2c dir-item.c --- a/dir-item.c Wed Jan 09 15:55:33 2008 -0500 +++ b/dir-item.c Mon Jan 14 14:25:50 2008 +0800 @@ -77,6 +77,10 @@ int btrfs_insert_xattr_item(struct btrfs if (!path) return -ENOMEM; + if (name_len + data_len + sizeof(struct btrfs_dir_item) > + BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item)) + return -ENOSPC; + data_size = sizeof(*dir_item) + name_len + data_len; dir_item = insert_with_overflow(trans, root, path, &key, data_size, name, name_len); diff -r 067ba546ac2c xattr.c --- a/xattr.c Wed Jan 09 15:55:33 2008 -0500 +++ b/xattr.c Mon Jan 14 14:25:50 2008 +0800 @@ -142,10 +142,6 @@ ssize_t btrfs_xattr_get(struct inode *in if (!handler) return -EOPNOTSUPP; - /* just in case... */ - if (*attr_name == '\0') - return -EINVAL; - name = get_name(attr_name, name_index); if (!name) return -ENOMEM; @@ -204,10 +200,6 @@ int btrfs_xattr_set(struct inode *inode, if (!handler) return -EOPNOTSUPP; - - /* just in case... */ - if (*attr_name == '\0') - return -EINVAL; name = get_name(attr_name, name_index); if (!name) @@ -454,12 +446,16 @@ static int btrfs_xattr_##name##_get(stru const char *name, void *value, \ size_t size) \ { \ + if (*name == '\0') \ + return -EINVAL; \ return btrfs_xattr_get(inode, index, name, value, size); \ } \ static int btrfs_xattr_##name##_set(struct inode *inode, \ const char *name, const void *value,\ size_t size, int flags) \ { \ + if (*name == '\0') \ + return -EINVAL; \ return btrfs_xattr_set(inode, index, name, value, size, flags); \ } \