2010-05-14 23:48:47 +04:00
/*
* Squashfs - a compressed read only filesystem for Linux
*
* Copyright ( c ) 2010
2011-05-26 13:39:56 +04:00
* Phillip Lougher < phillip @ squashfs . org . uk >
2010-05-14 23:48:47 +04:00
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2 ,
* or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
* xattr_id . c
*/
/*
* This file implements code to map the 32 - bit xattr id stored in the inode
* into the on disk location of the xattr data .
*/
# include <linux/fs.h>
# include <linux/vfs.h>
# include <linux/slab.h>
# include "squashfs_fs.h"
# include "squashfs_fs_sb.h"
# include "squashfs.h"
2010-10-25 03:17:24 +04:00
# include "xattr.h"
2010-05-14 23:48:47 +04:00
/*
* Map xattr id using the xattr id look up table
*/
int squashfs_xattr_lookup ( struct super_block * sb , unsigned int index ,
2010-05-14 03:32:21 +04:00
int * count , unsigned int * size , unsigned long long * xattr )
2010-05-14 23:48:47 +04:00
{
struct squashfs_sb_info * msblk = sb - > s_fs_info ;
int block = SQUASHFS_XATTR_BLOCK ( index ) ;
int offset = SQUASHFS_XATTR_BLOCK_OFFSET ( index ) ;
u64 start_block = le64_to_cpu ( msblk - > xattr_id_table [ block ] ) ;
struct squashfs_xattr_id id ;
int err ;
err = squashfs_read_metadata ( sb , & id , & start_block , & offset ,
sizeof ( id ) ) ;
if ( err < 0 )
return err ;
* xattr = le64_to_cpu ( id . xattr ) ;
* size = le32_to_cpu ( id . size ) ;
* count = le32_to_cpu ( id . count ) ;
return 0 ;
}
/*
* Read uncompressed xattr id lookup table indexes from disk into memory
*/
__le64 * squashfs_read_xattr_id_table ( struct super_block * sb , u64 start ,
u64 * xattr_table_start , int * xattr_ids )
{
unsigned int len ;
2011-05-20 05:26:43 +04:00
struct squashfs_xattr_id_table * id_table ;
id_table = squashfs_read_table ( sb , start , sizeof ( * id_table ) ) ;
if ( IS_ERR ( id_table ) )
return ( __le64 * ) id_table ;
2010-05-14 23:48:47 +04:00
2011-05-20 05:26:43 +04:00
* xattr_table_start = le64_to_cpu ( id_table - > xattr_table_start ) ;
* xattr_ids = le32_to_cpu ( id_table - > xattr_ids ) ;
kfree ( id_table ) ;
2011-05-24 06:20:27 +04:00
/* Sanity check values */
/* there is always at least one xattr id */
if ( * xattr_ids = = 0 )
return ERR_PTR ( - EINVAL ) ;
/* xattr_table should be less than start */
if ( * xattr_table_start > = start )
return ERR_PTR ( - EINVAL ) ;
2010-05-14 23:48:47 +04:00
len = SQUASHFS_XATTR_BLOCK_BYTES ( * xattr_ids ) ;
TRACE ( " In read_xattr_index_table, length %d \n " , len ) ;
2011-05-20 05:26:43 +04:00
return squashfs_read_table ( sb , start + sizeof ( * id_table ) , len ) ;
2010-05-14 23:48:47 +04:00
}