VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

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