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