2005-04-25 18:32:12 -07:00
# include <linux/fs.h>
# include <linux/buffer_head.h>
2007-07-17 04:04:28 -07:00
# include <linux/exportfs.h>
2005-04-25 18:32:12 -07: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 ;
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-21 17:16:53 -07:00
unsigned char s_hide ;
unsigned char s_showassoc ;
2009-06-17 16:26:25 -07:00
unsigned char s_overriderockperm ;
2009-06-17 16:26:27 -07:00
unsigned char s_uid_set ;
unsigned char s_gid_set ;
2005-04-25 18:32:12 -07:00
2008-02-08 04:21:09 -08:00
mode_t s_fmode ;
mode_t s_dmode ;
2005-04-25 18:32:12 -07:00
gid_t s_gid ;
uid_t s_uid ;
struct nls_table * s_nls_iocharset ; /* Native language support table */
} ;
2009-06-17 16:26:25 -07:00
# define ISOFS_INVALID_MODE ((mode_t) -1)
2005-04-25 18:32:12 -07: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 01:03:44 -07:00
return get_unaligned_le16 ( p ) ;
2005-04-25 18:32:12 -07:00
}
static inline unsigned int isonum_722 ( char * p )
{
2008-04-29 01:03:44 -07:00
return get_unaligned_be16 ( p ) ;
2005-04-25 18:32:12 -07:00
}
static inline unsigned int isonum_723 ( char * p )
{
/* Ignore bigendian datum due to broken mastering programs */
2008-04-29 01:03:44 -07:00
return get_unaligned_le16 ( p ) ;
2005-04-25 18:32:12 -07:00
}
static inline unsigned int isonum_731 ( char * p )
{
2008-04-29 01:03:44 -07:00
return get_unaligned_le32 ( p ) ;
2005-04-25 18:32:12 -07:00
}
static inline unsigned int isonum_732 ( char * p )
{
2008-04-29 01:03:44 -07:00
return get_unaligned_be32 ( p ) ;
2005-04-25 18:32:12 -07:00
}
static inline unsigned int isonum_733 ( char * p )
{
/* Ignore bigendian datum due to broken mastering programs */
2008-04-29 01:03:44 -07:00
return get_unaligned_le32 ( p ) ;
2005-04-25 18:32:12 -07:00
}
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 ) ;
}
}
2007-02-12 00:55:39 -08:00
extern const struct inode_operations isofs_dir_inode_operations ;
2006-03-28 01:56:42 -08:00
extern const struct file_operations isofs_dir_operations ;
2006-06-28 04:26:44 -07:00
extern const struct address_space_operations isofs_symlink_aops ;
2007-10-21 16:42:17 -07:00
extern const struct export_operations isofs_export_ops ;