2005-04-26 05:32:12 +04:00
# include <linux/fs.h>
# include <linux/buffer_head.h>
# 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 ;
unsigned char s_high_sierra ; /* A simple flag */
unsigned char s_mapping ;
int s_rock_offset ; /* offset of SUSP fields within SU area */
unsigned char s_rock ;
unsigned char s_joliet_level ;
unsigned char s_utf8 ;
unsigned char s_cruft ; /* Broken disks with high
byte of length containing
junk */
unsigned char s_unhide ;
unsigned char s_nosuid ;
unsigned char s_nodev ;
unsigned char s_nocompress ;
2005-06-22 04:16:53 +04:00
unsigned char s_hide ;
unsigned char s_showassoc ;
2005-04-26 05:32:12 +04:00
mode_t s_mode ;
gid_t s_gid ;
uid_t s_uid ;
struct nls_table * s_nls_iocharset ; /* Native language support table */
} ;
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 )
{
return le16_to_cpu ( get_unaligned ( ( __le16 * ) p ) ) ;
}
static inline unsigned int isonum_722 ( char * p )
{
return be16_to_cpu ( get_unaligned ( ( __le16 * ) p ) ) ;
}
static inline unsigned int isonum_723 ( char * p )
{
/* Ignore bigendian datum due to broken mastering programs */
return le16_to_cpu ( get_unaligned ( ( __le16 * ) p ) ) ;
}
static inline unsigned int isonum_731 ( char * p )
{
return le32_to_cpu ( get_unaligned ( ( __le32 * ) p ) ) ;
}
static inline unsigned int isonum_732 ( char * p )
{
return be32_to_cpu ( get_unaligned ( ( __le32 * ) p ) ) ;
}
static inline unsigned int isonum_733 ( char * p )
{
/* Ignore bigendian datum due to broken mastering programs */
return le32_to_cpu ( get_unaligned ( ( __le32 * ) p ) ) ;
}
extern int iso_date ( char * , int ) ;
struct inode ; /* To make gcc happy */
extern int parse_rock_ridge_inode ( struct iso_directory_record * , struct inode * ) ;
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 * ) ;
extern struct dentry * isofs_lookup ( struct inode * , struct dentry * , struct nameidata * ) ;
extern struct buffer_head * isofs_bread ( struct inode * , sector_t ) ;
extern int isofs_get_blocks ( struct inode * , sector_t , struct buffer_head * * , unsigned long ) ;
extern struct inode * isofs_iget ( struct super_block * sb ,
unsigned long block ,
unsigned long offset ) ;
/* 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 ) ;
}
}
extern struct inode_operations isofs_dir_inode_operations ;
extern struct file_operations isofs_dir_operations ;
extern struct address_space_operations isofs_symlink_aops ;
extern struct export_operations isofs_export_ops ;
/* The following macros are used to check for memory leaks. */
# ifdef LEAK_CHECK
# define free_s leak_check_free_s
# define malloc leak_check_malloc
# define sb_bread leak_check_bread
# define brelse leak_check_brelse
extern void * leak_check_malloc ( unsigned int size ) ;
extern void leak_check_free_s ( void * obj , int size ) ;
extern struct buffer_head * leak_check_bread ( struct super_block * sb , int block ) ;
extern void leak_check_brelse ( struct buffer_head * bh ) ;
# endif /* LEAK_CHECK */