static struct posix_acl *__f2fs_get_acl(struct inode *inode, int type, struct page *dpage) { int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT; void *value = NULL; struct posix_acl *acl; int retval; if (type == ACL_TYPE_ACCESS) name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; retval = f2fs_getxattr(inode, name_index, "", NULL, 0, dpage); if (retval > 0) { value = f2fs_kmalloc(F2FS_I_SB(inode), retval, GFP_F2FS_ZERO); if (!value) return ERR_PTR(-ENOMEM); retval = f2fs_getxattr(inode, name_index, "", value, retval, dpage); } if (retval > 0) acl = f2fs_acl_from_disk(value, retval); else if (retval == -ENODATA) acl = NULL; else acl = ERR_PTR(retval); kfree(value); return acl; }
static void *f2fs_acl_to_disk(struct f2fs_sb_info *sbi, const struct posix_acl *acl, size_t *size) { struct f2fs_acl_header *f2fs_acl; struct f2fs_acl_entry *entry; int i; f2fs_acl = f2fs_kmalloc(sbi, sizeof(struct f2fs_acl_header) + acl->a_count * sizeof(struct f2fs_acl_entry), GFP_NOFS); if (!f2fs_acl) return ERR_PTR(-ENOMEM); f2fs_acl->a_version = cpu_to_le32(F2FS_ACL_VERSION); entry = (struct f2fs_acl_entry *)(f2fs_acl + 1); for (i = 0; i < acl->a_count; i++) { entry->e_tag = cpu_to_le16(acl->a_entries[i].e_tag); entry->e_perm = cpu_to_le16(acl->a_entries[i].e_perm); switch (acl->a_entries[i].e_tag) { case ACL_USER: entry->e_id = cpu_to_le32( from_kuid(&init_user_ns, acl->a_entries[i].e_uid)); entry = (struct f2fs_acl_entry *)((char *)entry + sizeof(struct f2fs_acl_entry)); break; case ACL_GROUP: entry->e_id = cpu_to_le32( from_kgid(&init_user_ns, acl->a_entries[i].e_gid)); entry = (struct f2fs_acl_entry *)((char *)entry + sizeof(struct f2fs_acl_entry)); break; case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER: entry = (struct f2fs_acl_entry *)((char *)entry + sizeof(struct f2fs_acl_entry_short)); break; default: goto fail; } } *size = f2fs_acl_size(acl->a_count); return (void *)f2fs_acl; fail: kfree(f2fs_acl); return ERR_PTR(-EINVAL); }
static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage, struct f2fs_inline_dentry *inline_dentry) { struct f2fs_inline_dentry *backup_dentry; int err; backup_dentry = f2fs_kmalloc(F2FS_I_SB(dir), sizeof(struct f2fs_inline_dentry), GFP_F2FS_ZERO); if (!backup_dentry) { f2fs_put_page(ipage, 1); return -ENOMEM; } memcpy(backup_dentry, inline_dentry, MAX_INLINE_DATA); truncate_inline_inode(dir, ipage, 0); unlock_page(ipage); err = f2fs_add_inline_entries(dir, backup_dentry); if (err) goto recover; lock_page(ipage); stat_dec_inline_dir(dir); clear_inode_flag(dir, FI_INLINE_DENTRY); kfree(backup_dentry); return 0; recover: lock_page(ipage); memcpy(inline_dentry, backup_dentry, MAX_INLINE_DATA); f2fs_i_depth_write(dir, 0); f2fs_i_size_write(dir, MAX_INLINE_DATA); set_page_dirty(ipage); f2fs_put_page(ipage, 1); kfree(backup_dentry); return err; }