/* * Convert from filesystem to in-memory representation.
*/ staticstruct posix_acl *
ext4_acl_from_disk(constvoid *value, size_t size)
{ constchar *end = (char *)value + size; int n, count; struct posix_acl *acl;
if (!value) return NULL; if (size < sizeof(ext4_acl_header)) return ERR_PTR(-EINVAL); if (((ext4_acl_header *)value)->a_version !=
cpu_to_le32(EXT4_ACL_VERSION)) return ERR_PTR(-EINVAL);
value = (char *)value + sizeof(ext4_acl_header);
count = ext4_acl_count(size); if (count < 0) return ERR_PTR(-EINVAL); if (count == 0) return NULL;
acl = posix_acl_alloc(count, GFP_NOFS); if (!acl) return ERR_PTR(-ENOMEM); for (n = 0; n < count; n++) {
ext4_acl_entry *entry =
(ext4_acl_entry *)value; if ((char *)value + sizeof(ext4_acl_entry_short) > end) goto fail;
acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag);
acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
switch (acl->a_entries[n].e_tag) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER:
value = (char *)value + sizeof(ext4_acl_entry_short); break;
case ACL_USER:
value = (char *)value + sizeof(ext4_acl_entry); if ((char *)value > end) goto fail;
acl->a_entries[n].e_uid =
make_kuid(&init_user_ns,
le32_to_cpu(entry->e_id)); break; case ACL_GROUP:
value = (char *)value + sizeof(ext4_acl_entry); if ((char *)value > end) goto fail;
acl->a_entries[n].e_gid =
make_kgid(&init_user_ns,
le32_to_cpu(entry->e_id)); break;
/* * Set the access or default ACL of an inode. * * inode->i_rwsem: down unless called from ext4_new_inode
*/ staticint
__ext4_set_acl(handle_t *handle, struct inode *inode, int type, struct posix_acl *acl, int xattr_flags)
{ int name_index; void *value = NULL;
size_t size = 0; int error;
switch (type) { case ACL_TYPE_ACCESS:
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; break;
case ACL_TYPE_DEFAULT:
name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break;
default: return -EINVAL;
} if (acl) {
value = ext4_acl_to_disk(acl, &size); if (IS_ERR(value)) return (int)PTR_ERR(value);
}
/* * Initialize the ACLs of a new inode. Called from ext4_new_inode. * * dir->i_rwsem: down * inode->i_rwsem: up (access to inode is still exclusive)
*/ int
ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
{ struct posix_acl *default_acl, *acl; int error;
error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); if (error) return error;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.