^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/isofs/rock.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (C) 1992, 1993 Eric Youngdale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Rock Ridge Extensions to iso9660
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "isofs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "rock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * These functions are designed to read the system areas of a directory record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * and extract relevant information. There are different functions provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * depending upon what information we need at the time. One function fills
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * out an inode structure, a second one extracts a filename, a third one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * returns a symbolic link name, and a fourth one returns the extent number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * for the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct rock_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) void *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned char *chr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int cont_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int cont_extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int cont_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int cont_loops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * This is a way of ensuring that we have something in the system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * use fields that is compatible with Rock Ridge. Return zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static int check_sp(struct rock_ridge *rr, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (rr->u.SP.magic[0] != 0xbe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (rr->u.SP.magic[1] != 0xef)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void setup_rock_ridge(struct iso_directory_record *de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct inode *inode, struct rock_state *rs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) rs->len = sizeof(struct iso_directory_record) + de->name_len[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (rs->len & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) (rs->len)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) rs->chr = (unsigned char *)de + rs->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) rs->len = *((unsigned char *)de) - rs->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (rs->len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) rs->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (rs->len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) rs->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static void init_rock_state(struct rock_state *rs, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) memset(rs, 0, sizeof(*rs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) rs->inode = inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Maximum number of Rock Ridge continuation entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define RR_MAX_CE_ENTRIES 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Returns 0 if the caller should continue scanning, 1 if the scan must end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * and -ve on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int rock_continue(struct rock_state *rs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int blocksize = 1 << rs->inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) const int min_de_size = offsetof(struct rock_ridge, u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) kfree(rs->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) rs->buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if ((unsigned)rs->cont_offset > blocksize - min_de_size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) (unsigned)rs->cont_size > blocksize ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) printk(KERN_NOTICE "rock: corrupted directory entry. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) "extent=%d, offset=%d, size=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) rs->cont_extent, rs->cont_offset, rs->cont_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (rs->cont_extent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!rs->buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) memcpy(rs->buffer, bh->b_data + rs->cont_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) rs->cont_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) put_bh(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) rs->chr = rs->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) rs->len = rs->cont_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rs->cont_extent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rs->cont_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) rs->cont_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) printk("Unable to read rock-ridge attributes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) kfree(rs->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) rs->buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^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) * We think there's a record of type `sig' at rs->chr. Parse the signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * and make sure that there's really room for a record of that type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int rock_check_overflow(struct rock_state *rs, int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) switch (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case SIG('S', 'P'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) len = sizeof(struct SU_SP_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case SIG('C', 'E'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) len = sizeof(struct SU_CE_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case SIG('E', 'R'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) len = sizeof(struct SU_ER_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case SIG('R', 'R'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) len = sizeof(struct RR_RR_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case SIG('P', 'X'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) len = sizeof(struct RR_PX_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case SIG('P', 'N'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) len = sizeof(struct RR_PN_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case SIG('S', 'L'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) len = sizeof(struct RR_SL_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case SIG('N', 'M'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) len = sizeof(struct RR_NM_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case SIG('C', 'L'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) len = sizeof(struct RR_CL_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) case SIG('P', 'L'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) len = sizeof(struct RR_PL_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case SIG('T', 'F'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) len = sizeof(struct RR_TF_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case SIG('Z', 'F'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) len = sizeof(struct RR_ZF_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) len += offsetof(struct rock_ridge, u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (len > rs->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) printk(KERN_NOTICE "rock: directory entry would overflow "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) "storage\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) sig, len, rs->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * return length of name field; 0: not found, -1: to be ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int get_rock_ridge_filename(struct iso_directory_record *de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) char *retname, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct rock_state rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct rock_ridge *rr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int retnamlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int truncate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (!ISOFS_SB(inode->i_sb)->s_rock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *retname = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) init_rock_state(&rs, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) setup_rock_ridge(de, inode, &rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) while (rs.len > 2) { /* There may be one byte for padding somewhere */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) rr = (struct rock_ridge *)rs.chr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Ignore rock ridge info if rr->len is out of range, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * don't return -EIO because that would make the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * invisible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (rr->len < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto out; /* Something got screwed up here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sig = isonum_721(rs.chr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (rock_check_overflow(&rs, sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) goto eio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rs.chr += rr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) rs.len -= rr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * As above, just ignore the rock ridge info if rr->len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * is bogus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (rs.len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) goto out; /* Something got screwed up here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) switch (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case SIG('R', 'R'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if ((rr->u.RR.flags[0] & RR_NM) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case SIG('S', 'P'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (check_sp(rr, inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) case SIG('C', 'E'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) rs.cont_extent = isonum_733(rr->u.CE.extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) rs.cont_offset = isonum_733(rr->u.CE.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) rs.cont_size = isonum_733(rr->u.CE.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case SIG('N', 'M'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (truncate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (rr->len < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * If the flags are 2 or 4, this indicates '.' or '..'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * We don't want to do anything with this, because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * screws up the code that calls us. We don't really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * care anyways, since we can just use the non-RR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (rr->u.NM.flags & 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (rr->u.NM.flags & ~1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) printk("Unsupported NM flag settings (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) rr->u.NM.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) len = rr->len - 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (retnamlen + len >= 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) truncate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) p = memchr(rr->u.NM.name, '\0', len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (unlikely(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) len = p - rr->u.NM.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) memcpy(retname + retnamlen, rr->u.NM.name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) retnamlen += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) retname[retnamlen] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case SIG('R', 'E'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) kfree(rs.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = rock_continue(&rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return retnamlen; /* If 0, this file did not have a NM field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) kfree(rs.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) eio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #define RR_REGARD_XA 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #define RR_RELOC_DE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) parse_rock_ridge_inode_internal(struct iso_directory_record *de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct inode *inode, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int symlink_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int cnt, sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned int reloc_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct inode *reloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct rock_ridge *rr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int rootflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct rock_state rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (!ISOFS_SB(inode->i_sb)->s_rock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) init_rock_state(&rs, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) setup_rock_ridge(de, inode, &rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (flags & RR_REGARD_XA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rs.chr += 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) rs.len -= 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (rs.len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) rs.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) while (rs.len > 2) { /* There may be one byte for padding somewhere */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) rr = (struct rock_ridge *)rs.chr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Ignore rock ridge info if rr->len is out of range, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * don't return -EIO because that would make the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * invisible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (rr->len < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto out; /* Something got screwed up here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) sig = isonum_721(rs.chr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (rock_check_overflow(&rs, sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto eio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) rs.chr += rr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) rs.len -= rr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * As above, just ignore the rock ridge info if rr->len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * is bogus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (rs.len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto out; /* Something got screwed up here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) switch (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case SIG('R', 'R'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if ((rr->u.RR.flags[0] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) (RR_PX | RR_TF | RR_SL | RR_CL)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) case SIG('S', 'P'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (check_sp(rr, inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case SIG('C', 'E'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) rs.cont_extent = isonum_733(rr->u.CE.extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) rs.cont_offset = isonum_733(rr->u.CE.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) rs.cont_size = isonum_733(rr->u.CE.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case SIG('E', 'R'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Invalid length of ER tag id? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ISOFS_SB(inode->i_sb)->s_rock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) printk(KERN_DEBUG "ISO 9660 Extensions: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) for (p = 0; p < rr->u.ER.len_id; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) printk(KERN_CONT "%c", rr->u.ER.data[p]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) printk(KERN_CONT "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case SIG('P', 'X'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) inode->i_mode = isonum_733(rr->u.PX.mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) set_nlink(inode, isonum_733(rr->u.PX.n_links));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) i_uid_write(inode, isonum_733(rr->u.PX.uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) i_gid_write(inode, isonum_733(rr->u.PX.gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) case SIG('P', 'N'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int high, low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) high = isonum_733(rr->u.PN.dev_high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) low = isonum_733(rr->u.PN.dev_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * The Rock Ridge standard specifies that if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * sizeof(dev_t) <= 4, then the high field is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * unused, and the device number is completely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * stored in the low field. Some writers may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * ignore this subtlety,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * and as a result we test to see if the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * device number is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * stored in the low field, and use that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if ((low & ~0xff) && high == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) inode->i_rdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) MKDEV(low >> 8, low & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) inode->i_rdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) MKDEV(high, low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case SIG('T', 'F'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * Some RRIP writers incorrectly place ctime in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * TF_CREATE field. Try to handle this correctly for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * either case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Rock ridge never appears on a High Sierra disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (rr->u.TF.flags & TF_CREATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) inode->i_ctime.tv_sec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) iso_date(rr->u.TF.times[cnt++].time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) inode->i_ctime.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (rr->u.TF.flags & TF_MODIFY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) inode->i_mtime.tv_sec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) iso_date(rr->u.TF.times[cnt++].time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) inode->i_mtime.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (rr->u.TF.flags & TF_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) inode->i_atime.tv_sec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) iso_date(rr->u.TF.times[cnt++].time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) inode->i_atime.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (rr->u.TF.flags & TF_ATTRIBUTES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) inode->i_ctime.tv_sec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) iso_date(rr->u.TF.times[cnt++].time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) inode->i_ctime.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case SIG('S', 'L'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct SL_component *slp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct SL_component *oldslp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) slen = rr->len - 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) slp = &rr->u.SL.link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) inode->i_size = symlink_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) while (slen > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) rootflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) switch (slp->flags & ~1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) inode->i_size +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) slp->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) inode->i_size += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) inode->i_size += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) rootflag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) inode->i_size += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) printk("Symlink component flag "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) "not implemented\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) slen -= slp->len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) oldslp = slp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) slp = (struct SL_component *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) (((char *)slp) + slp->len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (slen < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (((rr->u.SL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) flags & 1) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ((oldslp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) flags & 1) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) inode->i_size +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * If this component record isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * continued, then append a '/'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!rootflag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) && (oldslp->flags & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) inode->i_size += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) symlink_len = inode->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case SIG('R', 'E'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) printk(KERN_WARNING "Attempt to read inode for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) "relocated directory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case SIG('C', 'L'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (flags & RR_RELOC_DE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) "ISOFS: Recursive directory relocation "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) "is not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) goto eio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) reloc_block = isonum_733(rr->u.CL.location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (reloc_block == ISOFS_I(inode)->i_iget5_block &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ISOFS_I(inode)->i_iget5_offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) "ISOFS: Directory relocation points to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) "itself\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) goto eio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ISOFS_I(inode)->i_first_extent = reloc_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (IS_ERR(reloc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ret = PTR_ERR(reloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) inode->i_mode = reloc->i_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) set_nlink(inode, reloc->i_nlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) inode->i_uid = reloc->i_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) inode->i_gid = reloc->i_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) inode->i_rdev = reloc->i_rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) inode->i_size = reloc->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) inode->i_blocks = reloc->i_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) inode->i_atime = reloc->i_atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) inode->i_ctime = reloc->i_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) inode->i_mtime = reloc->i_mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) iput(reloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) #ifdef CONFIG_ZISOFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case SIG('Z', 'F'): {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ISOFS_SB(inode->i_sb)->s_nocompress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) algo = isonum_721(rr->u.ZF.algorithm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (algo == SIG('p', 'z')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int block_shift =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) isonum_711(&rr->u.ZF.parms[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (block_shift > 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) printk(KERN_WARNING "isofs: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) "Can't handle ZF block "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) "size of 2^%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) block_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * Note: we don't change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * i_blocks here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ISOFS_I(inode)->i_file_format =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) isofs_file_compressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * Parameters to compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * algorithm (header size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * block size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ISOFS_I(inode)->i_format_parm[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) isonum_711(&rr->u.ZF.parms[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) ISOFS_I(inode)->i_format_parm[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) isonum_711(&rr->u.ZF.parms[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) inode->i_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) isonum_733(rr->u.ZF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) real_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) "isofs: Unknown ZF compression "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) "algorithm: %c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) rr->u.ZF.algorithm[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) rr->u.ZF.algorithm[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ret = rock_continue(&rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) kfree(rs.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) eio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) int slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) int rootflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct SL_component *oldslp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct SL_component *slp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) slen = rr->len - 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) slp = &rr->u.SL.link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) while (slen > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) rootflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) switch (slp->flags & ~1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (slp->len > plimit - rpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) memcpy(rpnt, slp->text, slp->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) rpnt += slp->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (rpnt >= plimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *rpnt++ = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (2 > plimit - rpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) *rpnt++ = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) *rpnt++ = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (rpnt >= plimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) rootflag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) *rpnt++ = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) printk("Symlink component flag not implemented (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) slp->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) slen -= slp->len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) oldslp = slp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) slp = (struct SL_component *)((char *)slp + slp->len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (slen < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * If there is another SL record, and this component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * record isn't continued, then add a slash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if ((!rootflag) && (rr->u.SL.flags & 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) !(oldslp->flags & 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (rpnt >= plimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *rpnt++ = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * If this component record isn't continued, then append a '/'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (!rootflag && !(oldslp->flags & 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (rpnt >= plimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) *rpnt++ = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return rpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int relocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int flags = relocated ? RR_RELOC_DE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) int result = parse_rock_ridge_inode_internal(de, inode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * if rockridge flag was reset and we didn't look for attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * behind eventual XA attributes, have a look there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) result = parse_rock_ridge_inode_internal(de, inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) flags | RR_REGARD_XA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * readpage() for symlinks: reads symlink contents into the page and either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * makes it uptodate and returns 0 or returns error (-EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct inode *inode = page->mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct iso_inode_info *ei = ISOFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) char *link = page_address(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) char *rpnt = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned char *pnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct iso_directory_record *raw_de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) unsigned long block, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) int sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct rock_ridge *rr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct rock_state rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!sbi->s_rock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) init_rock_state(&rs, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) block = ei->i_iget5_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) bh = sb_bread(inode->i_sb, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) goto out_noread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) offset = ei->i_iget5_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) pnt = (unsigned char *)bh->b_data + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) raw_de = (struct iso_directory_record *)pnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * If we go past the end of the buffer, there is some sort of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (offset + *pnt > bufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) goto out_bad_span;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * Now test for possible Rock Ridge extensions which will override
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * some of these numbers in the inode structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) setup_rock_ridge(raw_de, inode, &rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) while (rs.len > 2) { /* There may be one byte for padding somewhere */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) rr = (struct rock_ridge *)rs.chr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (rr->len < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) goto out; /* Something got screwed up here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) sig = isonum_721(rs.chr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (rock_check_overflow(&rs, sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) rs.chr += rr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) rs.len -= rr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (rs.len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) goto out; /* corrupted isofs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) switch (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case SIG('R', 'R'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if ((rr->u.RR.flags[0] & RR_SL) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) case SIG('S', 'P'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (check_sp(rr, inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case SIG('S', 'L'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) rpnt = get_symlink_chunk(rpnt, rr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) link + (PAGE_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (rpnt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) case SIG('C', 'E'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* This tells is if there is a continuation record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) rs.cont_extent = isonum_733(rr->u.CE.extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) rs.cont_offset = isonum_733(rr->u.CE.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) rs.cont_size = isonum_733(rr->u.CE.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ret = rock_continue(&rs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (rpnt == link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) *rpnt = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* error exit from macro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) kfree(rs.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) out_noread:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) printk("unable to read i-node block");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) out_bad_span:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) printk("symlink spans iso9660 blocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) SetPageError(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) const struct address_space_operations isofs_symlink_aops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .readpage = rock_ridge_symlink_readpage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) };