2005-04-26 05:32:12 +04:00
# include <linux/fs.h>
# include <linux/buffer_head.h>
2007-07-17 15:04:28 +04:00
# include <linux/exportfs.h>
2005-04-26 05:32:12 +04:00
# include <linux/iso_fs.h>
# include <asm/unaligned.h>
enum isofs_file_format {
isofs_file_normal = 0 ,
isofs_file_sparse = 1 ,
isofs_file_compressed = 2 ,
} ;
/*
* iso fs inode data in memory
*/
struct iso_inode_info {
unsigned long i_iget5_block ;
unsigned long i_iget5_offset ;
unsigned int i_first_extent ;
unsigned char i_file_format ;
unsigned char i_format_parm [ 3 ] ;
unsigned long i_next_section_block ;
unsigned long i_next_section_offset ;
off_t i_section_size ;
struct inode vfs_inode ;
} ;
/*
* iso9660 super - block data in memory
*/
struct isofs_sb_info {
unsigned long s_ninodes ;
unsigned long s_nzones ;
unsigned long s_firstdatazone ;
unsigned long s_log_zone_size ;
unsigned long s_max_size ;
int s_rock_offset ; /* offset of SUSP fields within SU area */
unsigned char s_joliet_level ;
2009-06-18 03:26:27 +04:00
unsigned char s_mapping ;
unsigned int s_high_sierra : 1 ;
unsigned int s_rock : 2 ;
unsigned int s_utf8 : 1 ;
unsigned int s_cruft : 1 ; /* Broken disks with high byte of length
* containing junk */
unsigned int s_nocompress : 1 ;
unsigned int s_hide : 1 ;
unsigned int s_showassoc : 1 ;
unsigned int s_overriderockperm : 1 ;
unsigned int s_uid_set : 1 ;
unsigned int s_gid_set : 1 ;
2005-04-26 05:32:12 +04:00
2011-07-26 11:19:52 +04:00
umode_t s_fmode ;
umode_t s_dmode ;
2012-02-10 23:35:50 +04:00
kgid_t s_gid ;
kuid_t s_uid ;
2005-04-26 05:32:12 +04:00
struct nls_table * s_nls_iocharset ; /* Native language support table */
} ;
2011-07-26 11:19:52 +04:00
# define ISOFS_INVALID_MODE ((umode_t) -1)
2009-06-18 03:26:25 +04:00
2005-04-26 05:32:12 +04:00
static inline struct isofs_sb_info * ISOFS_SB ( struct super_block * sb )
{
return sb - > s_fs_info ;
}
static inline struct iso_inode_info * ISOFS_I ( struct inode * inode )
{
return container_of ( inode , struct iso_inode_info , vfs_inode ) ;
}
static inline int isonum_711 ( char * p )
{
return * ( u8 * ) p ;
}
static inline int isonum_712 ( char * p )
{
return * ( s8 * ) p ;
}
static inline unsigned int isonum_721 ( char * p )
{
2008-04-29 12:03:44 +04:00
return get_unaligned_le16 ( p ) ;
2005-04-26 05:32:12 +04:00
}
static inline unsigned int isonum_722 ( char * p )
{
2008-04-29 12:03:44 +04:00
return get_unaligned_be16 ( p ) ;
2005-04-26 05:32:12 +04:00
}
static inline unsigned int isonum_723 ( char * p )
{
/* Ignore bigendian datum due to broken mastering programs */
2008-04-29 12:03:44 +04:00
return get_unaligned_le16 ( p ) ;
2005-04-26 05:32:12 +04:00
}
static inline unsigned int isonum_731 ( char * p )
{
2008-04-29 12:03:44 +04:00
return get_unaligned_le32 ( p ) ;
2005-04-26 05:32:12 +04:00
}
static inline unsigned int isonum_732 ( char * p )
{
2008-04-29 12:03:44 +04:00
return get_unaligned_be32 ( p ) ;
2005-04-26 05:32:12 +04:00
}
static inline unsigned int isonum_733 ( char * p )
{
/* Ignore bigendian datum due to broken mastering programs */
2008-04-29 12:03:44 +04:00
return get_unaligned_le32 ( p ) ;
2005-04-26 05:32:12 +04:00
}
extern int iso_date ( char * , int ) ;
struct inode ; /* To make gcc happy */
2014-08-17 13:49:57 +04:00
extern int parse_rock_ridge_inode ( struct iso_directory_record * , struct inode * , int relocated ) ;
2005-04-26 05:32:12 +04:00
extern int get_rock_ridge_filename ( struct iso_directory_record * , char * , struct inode * ) ;
extern int isofs_name_translate ( struct iso_directory_record * , char * , struct inode * ) ;
int get_joliet_filename ( struct iso_directory_record * , unsigned char * , struct inode * ) ;
int get_acorn_filename ( struct iso_directory_record * , char * , struct inode * ) ;
2012-06-11 01:13:09 +04:00
extern struct dentry * isofs_lookup ( struct inode * , struct dentry * , unsigned int flags ) ;
2005-04-26 05:32:12 +04:00
extern struct buffer_head * isofs_bread ( struct inode * , sector_t ) ;
extern int isofs_get_blocks ( struct inode * , sector_t , struct buffer_head * * , unsigned long ) ;
2014-08-17 13:49:57 +04:00
struct inode * __isofs_iget ( struct super_block * sb ,
unsigned long block ,
unsigned long offset ,
int relocated ) ;
static inline struct inode * isofs_iget ( struct super_block * sb ,
unsigned long block ,
unsigned long offset )
{
return __isofs_iget ( sb , block , offset , 0 ) ;
}
static inline struct inode * isofs_iget_reloc ( struct super_block * sb ,
unsigned long block ,
unsigned long offset )
{
return __isofs_iget ( sb , block , offset , 1 ) ;
}
2005-04-26 05:32:12 +04:00
/* Because the inode number is no longer relevant to finding the
* underlying meta - data for an inode , we are free to choose a more
* convenient 32 - bit number as the inode number . The inode numbering
* scheme was recommended by Sergey Vlasov and Eric Lammerts . */
static inline unsigned long isofs_get_ino ( unsigned long block ,
unsigned long offset ,
unsigned long bufbits )
{
return ( block < < ( bufbits - 5 ) ) | ( offset > > 5 ) ;
}
/* Every directory can have many redundant directory entries scattered
* throughout the directory tree . First there is the directory entry
* with the name of the directory stored in the parent directory .
* Then , there is the " . " directory entry stored in the directory
* itself . Finally , there are possibly many " .. " directory entries
* stored in all the subdirectories .
*
* In order for the NFS get_parent ( ) method to work and for the
* general consistency of the dcache , we need to make sure the
* " i_iget5_block " and " i_iget5_offset " all point to exactly one of
* the many redundant entries for each directory . We normalize the
* block and offset by always making them point to the " . " directory .
*
* Notice that we do not use the entry for the directory with the name
* that is located in the parent directory . Even though choosing this
* first directory is more natural , it is much easier to find the " . "
* entry in the NFS get_parent ( ) method because it is implicitly
* encoded in the " extent + ext_attr_length " fields of _all_ the
* redundant entries for the directory . Thus , it can always be
* reached regardless of which directory entry you have in hand .
*
* This works because the " . " entry is simply the first directory
* record when you start reading the file that holds all the directory
* records , and this file starts at " extent + ext_attr_length " blocks .
* Because the " . " entry is always the first entry listed in the
* directories file , the normalized " offset " value is always 0.
*
* You should pass the directory entry in " de " . On return , " block "
* and " offset " will hold normalized values . Only directories are
* affected making it safe to call even for non - directory file
* types . */
static inline void
isofs_normalize_block_and_offset ( struct iso_directory_record * de ,
unsigned long * block ,
unsigned long * offset )
{
/* Only directories are normalized. */
if ( de - > flags [ 0 ] & 2 ) {
* offset = 0 ;
* block = ( unsigned long ) isonum_733 ( de - > extent )
+ ( unsigned long ) isonum_711 ( de - > ext_attr_length ) ;
}
}
2007-02-12 11:55:39 +03:00
extern const struct inode_operations isofs_dir_inode_operations ;
2006-03-28 13:56:42 +04:00
extern const struct file_operations isofs_dir_operations ;
2006-06-28 15:26:44 +04:00
extern const struct address_space_operations isofs_symlink_aops ;
2007-10-22 03:42:17 +04:00
extern const struct export_operations isofs_export_ops ;