/* * Inode operation get_posix_acl(). * * inode->i_mutex: don't care */ static struct posix_acl * ext3_get_acl(struct inode *inode, int type) { struct ext3_inode_info *ei = EXT3_I(inode); int name_index; char *value = NULL; struct posix_acl *acl; int retval; if (!test_opt(inode->i_sb, POSIX_ACL)) return NULL; switch(type) { case ACL_TYPE_ACCESS: acl = ext3_iget_acl(inode, &ei->i_acl); if (acl != EXT3_ACL_NOT_CACHED) return acl; name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: acl = ext3_iget_acl(inode, &ei->i_default_acl); if (acl != EXT3_ACL_NOT_CACHED) return acl; name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; break; default: return ERR_PTR(-EINVAL); } retval = ext3_xattr_get(inode, name_index, "", NULL, 0); if (retval > 0) { value = kmalloc(retval, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); retval = ext3_xattr_get(inode, name_index, "", value, retval); } if (retval > 0) acl = ext3_acl_from_disk(value, retval); else if (retval == -ENODATA || retval == -ENOSYS) acl = NULL; else acl = ERR_PTR(retval); kfree(value); if (!IS_ERR(acl)) { switch(type) { case ACL_TYPE_ACCESS: ext3_iset_acl(inode, &ei->i_acl, acl); break; case ACL_TYPE_DEFAULT: ext3_iset_acl(inode, &ei->i_default_acl, acl); break; } } return acl; }
/* * Inode operation get_posix_acl(). * * inode->i_sem: don't care * BKL: held */ struct posix_acl * ext3_get_acl(struct inode *inode, int type) { const size_t max_size = ext3_acl_size(EXT3_ACL_MAX_ENTRIES); struct ext3_inode_info *ei = EXT3_I(inode); int name_index; char *value; struct posix_acl *acl; int retval; if (!IS_POSIXACL(inode)) return 0; switch(type) { case ACL_TYPE_ACCESS: if (ei->i_acl != EXT3_ACL_NOT_CACHED) return posix_acl_dup(ei->i_acl); name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: if (ei->i_default_acl != EXT3_ACL_NOT_CACHED) return posix_acl_dup(ei->i_default_acl); name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; break; default: return ERR_PTR(-EINVAL); } value = kmalloc(max_size, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); retval = ext3_xattr_get(inode, name_index, "", value, max_size); acl = ERR_PTR(retval); if (retval > 0) acl = ext3_acl_from_disk(value, retval); else if (retval == -ENODATA || retval == -ENOSYS) acl = NULL; kfree(value); if (!IS_ERR(acl)) { switch(type) { case ACL_TYPE_ACCESS: ei->i_acl = posix_acl_dup(acl); break; case ACL_TYPE_DEFAULT: ei->i_default_acl = posix_acl_dup(acl); break; } } return acl; }
/* * Inode operation get_posix_acl(). * * inode->i_mutex: don't care */ static struct posix_acl * ext3_get_acl(struct inode *inode, int type) { int name_index; char *value = NULL; struct posix_acl *acl; int retval; if (!test_opt(inode->i_sb, POSIX_ACL)) return NULL; acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; switch (type) { case ACL_TYPE_ACCESS: name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; break; default: BUG(); } retval = ext3_xattr_get(inode, name_index, "", NULL, 0); if (retval > 0) { value = kmalloc(retval, GFP_NOFS); if (!value) return ERR_PTR(-ENOMEM); retval = ext3_xattr_get(inode, name_index, "", value, retval); } if (retval > 0) acl = ext3_acl_from_disk(value, retval); else if (retval == -ENODATA || retval == -ENOSYS) acl = NULL; else acl = ERR_PTR(retval); kfree(value); if (!IS_ERR(acl)) set_cached_acl(inode, type, acl); return acl; }