1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Squashfs - a compressed read only filesystem for Linux 4 * 5 * Copyright (c) 2010 6 * Phillip Lougher <phillip@squashfs.org.uk> 7 * 8 * xattr_id.c 9 */ 10 11 /* 12 * This file implements code to map the 32-bit xattr id stored in the inode 13 * into the on disk location of the xattr data. 14 */ 15 16 #include <linux/fs.h> 17 #include <linux/vfs.h> 18 #include <linux/slab.h> 19 20 #include "squashfs_fs.h" 21 #include "squashfs_fs_sb.h" 22 #include "squashfs.h" 23 #include "xattr.h" 24 25 /* 26 * Map xattr id using the xattr id look up table 27 */ 28 int squashfs_xattr_lookup(struct super_block *sb, unsigned int index, 29 int *count, unsigned int *size, unsigned long long *xattr) 30 { 31 struct squashfs_sb_info *msblk = sb->s_fs_info; 32 int block = SQUASHFS_XATTR_BLOCK(index); 33 int offset = SQUASHFS_XATTR_BLOCK_OFFSET(index); 34 u64 start_block = le64_to_cpu(msblk->xattr_id_table[block]); 35 struct squashfs_xattr_id id; 36 int err; 37 38 err = squashfs_read_metadata(sb, &id, &start_block, &offset, 39 sizeof(id)); 40 if (err < 0) 41 return err; 42 43 *xattr = le64_to_cpu(id.xattr); 44 *size = le32_to_cpu(id.size); 45 *count = le32_to_cpu(id.count); 46 return 0; 47 } 48 49 50 /* 51 * Read uncompressed xattr id lookup table indexes from disk into memory 52 */ 53 __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start, 54 u64 *xattr_table_start, int *xattr_ids) 55 { 56 unsigned int len; 57 struct squashfs_xattr_id_table *id_table; 58 59 id_table = squashfs_read_table(sb, start, sizeof(*id_table)); 60 if (IS_ERR(id_table)) 61 return (__le64 *) id_table; 62 63 *xattr_table_start = le64_to_cpu(id_table->xattr_table_start); 64 *xattr_ids = le32_to_cpu(id_table->xattr_ids); 65 kfree(id_table); 66 67 /* Sanity check values */ 68 69 /* there is always at least one xattr id */ 70 if (*xattr_ids == 0) 71 return ERR_PTR(-EINVAL); 72 73 /* xattr_table should be less than start */ 74 if (*xattr_table_start >= start) 75 return ERR_PTR(-EINVAL); 76 77 len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); 78 79 TRACE("In read_xattr_index_table, length %d\n", len); 80 81 return squashfs_read_table(sb, start + sizeof(*id_table), len); 82 } 83