^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/exportfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/iso_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) enum isofs_file_format {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) isofs_file_normal = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) isofs_file_sparse = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) isofs_file_compressed = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * iso fs inode data in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct iso_inode_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) unsigned long i_iget5_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) unsigned long i_iget5_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) unsigned int i_first_extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned char i_file_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) unsigned char i_format_parm[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) unsigned long i_next_section_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned long i_next_section_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) off_t i_section_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct inode vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * iso9660 super-block data in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct isofs_sb_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned long s_ninodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned long s_nzones;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long s_firstdatazone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long s_log_zone_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned long s_max_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int s_rock_offset; /* offset of SUSP fields within SU area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) s32 s_sbsector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned char s_joliet_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned char s_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned char s_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned char s_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int s_high_sierra:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned int s_rock:2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned int s_cruft:1; /* Broken disks with high byte of length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * containing junk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned int s_nocompress:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned int s_hide:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) unsigned int s_showassoc:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int s_overriderockperm:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int s_uid_set:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int s_gid_set:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) umode_t s_fmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) umode_t s_dmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) kgid_t s_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) kuid_t s_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct nls_table *s_nls_iocharset; /* Native language support table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define ISOFS_INVALID_MODE ((umode_t) -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static inline struct isofs_sb_info *ISOFS_SB(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static inline struct iso_inode_info *ISOFS_I(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return container_of(inode, struct iso_inode_info, vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static inline int isonum_711(u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static inline int isonum_712(s8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static inline unsigned int isonum_721(u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return get_unaligned_le16(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static inline unsigned int isonum_722(u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return get_unaligned_be16(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static inline unsigned int isonum_723(u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Ignore bigendian datum due to broken mastering programs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return get_unaligned_le16(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static inline unsigned int isonum_731(u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return get_unaligned_le32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static inline unsigned int isonum_732(u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return get_unaligned_be32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static inline unsigned int isonum_733(u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Ignore bigendian datum due to broken mastering programs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return get_unaligned_le32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) extern int iso_date(u8 *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct inode; /* To make gcc happy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *, int relocated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int get_joliet_filename(struct iso_directory_record *, unsigned char *, struct inode *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int get_acorn_filename(struct iso_directory_record *, char *, struct inode *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) extern struct buffer_head *isofs_bread(struct inode *, sector_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct inode *__isofs_iget(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned long block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int relocated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline struct inode *isofs_iget(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned long block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return __isofs_iget(sb, block, offset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static inline struct inode *isofs_iget_reloc(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned long block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return __isofs_iget(sb, block, offset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Because the inode number is no longer relevant to finding the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * underlying meta-data for an inode, we are free to choose a more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * convenient 32-bit number as the inode number. The inode numbering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * scheme was recommended by Sergey Vlasov and Eric Lammerts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static inline unsigned long isofs_get_ino(unsigned long block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned long offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned long bufbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return (block << (bufbits - 5)) | (offset >> 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Every directory can have many redundant directory entries scattered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * throughout the directory tree. First there is the directory entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * with the name of the directory stored in the parent directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Then, there is the "." directory entry stored in the directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * itself. Finally, there are possibly many ".." directory entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * stored in all the subdirectories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * In order for the NFS get_parent() method to work and for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * general consistency of the dcache, we need to make sure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * "i_iget5_block" and "i_iget5_offset" all point to exactly one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * the many redundant entries for each directory. We normalize the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * block and offset by always making them point to the "." directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Notice that we do not use the entry for the directory with the name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * that is located in the parent directory. Even though choosing this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * first directory is more natural, it is much easier to find the "."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * entry in the NFS get_parent() method because it is implicitly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * encoded in the "extent + ext_attr_length" fields of _all_ the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * redundant entries for the directory. Thus, it can always be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * reached regardless of which directory entry you have in hand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * This works because the "." entry is simply the first directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * record when you start reading the file that holds all the directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * records, and this file starts at "extent + ext_attr_length" blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * Because the "." entry is always the first entry listed in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * directories file, the normalized "offset" value is always 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * You should pass the directory entry in "de". On return, "block"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * and "offset" will hold normalized values. Only directories are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * affected making it safe to call even for non-directory file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * types. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) isofs_normalize_block_and_offset(struct iso_directory_record* de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned long *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned long *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Only directories are normalized. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (de->flags[0] & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *block = (unsigned long)isonum_733(de->extent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) + (unsigned long)isonum_711(de->ext_attr_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) extern const struct inode_operations isofs_dir_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) extern const struct file_operations isofs_dir_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) extern const struct address_space_operations isofs_symlink_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) extern const struct export_operations isofs_export_ops;