blob: e99f7ff4ecb4470876a2713a551c00de765f284c [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/fs/isofs/inode.c
3 *
4 * (C) 1991 Linus Torvalds - minix filesystem
5 * 1992, 1993, 1994 Eric Youngdale Modified for ISO 9660 filesystem.
6 * 1994 Eberhard Moenkeberg - multi session handling.
7 * 1995 Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs.
8 * 1997 Gordon Chaffee - Joliet CDs
9 * 1998 Eric Lammerts - ISO 9660 Level 3
10 * 2004 Paul Serice - Inode Support pushed out from 4GB to 128GB
11 * 2004 Paul Serice - NFS Export Operations
12 */
13
Al Viro94f2f712005-04-25 18:32:12 -070014#include <linux/init.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <linux/module.h>
16
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/nls.h>
19#include <linux/ctype.h>
20#include <linux/smp_lock.h>
Al Viro94f2f712005-04-25 18:32:12 -070021#include <linux/statfs.h>
22#include <linux/cdrom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/parser.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Al Viro94f2f712005-04-25 18:32:12 -070025#include "isofs.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include "zisofs.h"
27
28#define BEQUIET
29
Linus Torvalds1da177e2005-04-16 15:20:36 -070030static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
31static int isofs_hash(struct dentry *parent, struct qstr *qstr);
32static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
33static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
34
35#ifdef CONFIG_JOLIET
36static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);
37static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);
38static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
39static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
40#endif
41
42static void isofs_put_super(struct super_block *sb)
43{
44 struct isofs_sb_info *sbi = ISOFS_SB(sb);
45#ifdef CONFIG_JOLIET
46 if (sbi->s_nls_iocharset) {
47 unload_nls(sbi->s_nls_iocharset);
48 sbi->s_nls_iocharset = NULL;
49 }
50#endif
51
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 kfree(sbi);
53 sb->s_fs_info = NULL;
54 return;
55}
56
57static void isofs_read_inode(struct inode *);
David Howells726c3342006-06-23 02:02:58 -070058static int isofs_statfs (struct dentry *, struct kstatfs *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Christoph Lametere18b8902006-12-06 20:33:20 -080060static struct kmem_cache *isofs_inode_cachep;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
62static struct inode *isofs_alloc_inode(struct super_block *sb)
63{
64 struct iso_inode_info *ei;
Christoph Lametere94b1762006-12-06 20:33:17 -080065 ei = kmem_cache_alloc(isofs_inode_cachep, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 if (!ei)
67 return NULL;
68 return &ei->vfs_inode;
69}
70
71static void isofs_destroy_inode(struct inode *inode)
72{
73 kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
74}
75
Christoph Lametere18b8902006-12-06 20:33:20 -080076static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Andrew Morton9eb7f2c2005-06-21 17:16:49 -070078 struct iso_inode_info *ei = foo;
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
Christoph Lameter50953fe2007-05-06 14:50:16 -070080 if (flags & SLAB_CTOR_CONSTRUCTOR)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 inode_init_once(&ei->vfs_inode);
82}
83
84static int init_inodecache(void)
85{
86 isofs_inode_cachep = kmem_cache_create("isofs_inode_cache",
87 sizeof(struct iso_inode_info),
Paul Jacksonfffb60f2006-03-24 03:16:06 -080088 0, (SLAB_RECLAIM_ACCOUNT|
89 SLAB_MEM_SPREAD),
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 init_once, NULL);
91 if (isofs_inode_cachep == NULL)
92 return -ENOMEM;
93 return 0;
94}
95
96static void destroy_inodecache(void)
97{
Alexey Dobriyan1a1d92c2006-09-27 01:49:40 -070098 kmem_cache_destroy(isofs_inode_cachep);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099}
100
101static int isofs_remount(struct super_block *sb, int *flags, char *data)
102{
103 /* we probably want a lot more here */
104 *flags |= MS_RDONLY;
105 return 0;
106}
107
Josef 'Jeff' Sipekee9b6d62007-02-12 00:55:41 -0800108static const struct super_operations isofs_sops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 .alloc_inode = isofs_alloc_inode,
110 .destroy_inode = isofs_destroy_inode,
111 .read_inode = isofs_read_inode,
112 .put_super = isofs_put_super,
113 .statfs = isofs_statfs,
114 .remount_fs = isofs_remount,
115};
116
117
118static struct dentry_operations isofs_dentry_ops[] = {
119 {
120 .d_hash = isofs_hash,
121 .d_compare = isofs_dentry_cmp,
122 },
123 {
124 .d_hash = isofs_hashi,
125 .d_compare = isofs_dentry_cmpi,
126 },
127#ifdef CONFIG_JOLIET
128 {
129 .d_hash = isofs_hash_ms,
130 .d_compare = isofs_dentry_cmp_ms,
131 },
132 {
133 .d_hash = isofs_hashi_ms,
134 .d_compare = isofs_dentry_cmpi_ms,
Andrew Morton9eb7f2c2005-06-21 17:16:49 -0700135 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136#endif
137};
138
139struct iso9660_options{
140 char map;
141 char rock;
142 char joliet;
143 char cruft;
Jeremy White9769f4e2005-06-21 17:16:53 -0700144 char hide;
145 char showassoc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 char nocompress;
147 unsigned char check;
148 unsigned int blocksize;
149 mode_t mode;
150 gid_t gid;
151 uid_t uid;
152 char *iocharset;
153 unsigned char utf8;
154 /* LVE */
155 s32 session;
156 s32 sbsector;
157};
158
159/*
160 * Compute the hash for the isofs name corresponding to the dentry.
161 */
162static int
163isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
164{
165 const char *name;
166 int len;
167
168 len = qstr->len;
169 name = qstr->name;
170 if (ms) {
171 while (len && name[len-1] == '.')
172 len--;
173 }
174
175 qstr->hash = full_name_hash(name, len);
176
177 return 0;
178}
179
180/*
181 * Compute the hash for the isofs name corresponding to the dentry.
182 */
183static int
184isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
185{
186 const char *name;
187 int len;
188 char c;
189 unsigned long hash;
190
191 len = qstr->len;
192 name = qstr->name;
193 if (ms) {
194 while (len && name[len-1] == '.')
195 len--;
196 }
197
198 hash = init_name_hash();
199 while (len--) {
200 c = tolower(*name++);
201 hash = partial_name_hash(tolower(c), hash);
202 }
203 qstr->hash = end_name_hash(hash);
204
205 return 0;
206}
207
208/*
209 * Case insensitive compare of two isofs names.
210 */
Andrew Morton9eb7f2c2005-06-21 17:16:49 -0700211static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a,
212 struct qstr *b, int ms)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213{
214 int alen, blen;
215
216 /* A filename cannot end in '.' or we treat it like it has none */
217 alen = a->len;
218 blen = b->len;
219 if (ms) {
220 while (alen && a->name[alen-1] == '.')
221 alen--;
222 while (blen && b->name[blen-1] == '.')
223 blen--;
224 }
225 if (alen == blen) {
226 if (strnicmp(a->name, b->name, alen) == 0)
227 return 0;
228 }
229 return 1;
230}
231
232/*
233 * Case sensitive compare of two isofs names.
234 */
Andrew Morton9eb7f2c2005-06-21 17:16:49 -0700235static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a,
236 struct qstr *b, int ms)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237{
238 int alen, blen;
239
240 /* A filename cannot end in '.' or we treat it like it has none */
241 alen = a->len;
242 blen = b->len;
243 if (ms) {
244 while (alen && a->name[alen-1] == '.')
245 alen--;
246 while (blen && b->name[blen-1] == '.')
247 blen--;
248 }
249 if (alen == blen) {
250 if (strncmp(a->name, b->name, alen) == 0)
251 return 0;
252 }
253 return 1;
254}
255
256static int
257isofs_hash(struct dentry *dentry, struct qstr *qstr)
258{
259 return isofs_hash_common(dentry, qstr, 0);
260}
261
262static int
263isofs_hashi(struct dentry *dentry, struct qstr *qstr)
264{
265 return isofs_hashi_common(dentry, qstr, 0);
266}
267
268static int
269isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b)
270{
271 return isofs_dentry_cmp_common(dentry, a, b, 0);
272}
273
274static int
275isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b)
276{
277 return isofs_dentry_cmpi_common(dentry, a, b, 0);
278}
279
280#ifdef CONFIG_JOLIET
281static int
282isofs_hash_ms(struct dentry *dentry, struct qstr *qstr)
283{
284 return isofs_hash_common(dentry, qstr, 1);
285}
286
287static int
288isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr)
289{
290 return isofs_hashi_common(dentry, qstr, 1);
291}
292
293static int
294isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
295{
296 return isofs_dentry_cmp_common(dentry, a, b, 1);
297}
298
299static int
300isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
301{
302 return isofs_dentry_cmpi_common(dentry, a, b, 1);
303}
304#endif
305
306enum {
307 Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
308 Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
309 Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
Jeremy White9769f4e2005-06-21 17:16:53 -0700310 Opt_nocompress, Opt_hide, Opt_showassoc,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311};
312
313static match_table_t tokens = {
314 {Opt_norock, "norock"},
315 {Opt_nojoliet, "nojoliet"},
316 {Opt_unhide, "unhide"},
Jeremy White9769f4e2005-06-21 17:16:53 -0700317 {Opt_hide, "hide"},
318 {Opt_showassoc, "showassoc"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 {Opt_cruft, "cruft"},
320 {Opt_utf8, "utf8"},
321 {Opt_iocharset, "iocharset=%s"},
322 {Opt_map_a, "map=acorn"},
323 {Opt_map_a, "map=a"},
324 {Opt_map_n, "map=normal"},
325 {Opt_map_n, "map=n"},
326 {Opt_map_o, "map=off"},
327 {Opt_map_o, "map=o"},
328 {Opt_session, "session=%u"},
329 {Opt_sb, "sbsector=%u"},
330 {Opt_check_r, "check=relaxed"},
331 {Opt_check_r, "check=r"},
332 {Opt_check_s, "check=strict"},
333 {Opt_check_s, "check=s"},
334 {Opt_uid, "uid=%u"},
335 {Opt_gid, "gid=%u"},
336 {Opt_mode, "mode=%u"},
337 {Opt_block, "block=%u"},
338 {Opt_ignore, "conv=binary"},
339 {Opt_ignore, "conv=b"},
340 {Opt_ignore, "conv=text"},
341 {Opt_ignore, "conv=t"},
342 {Opt_ignore, "conv=mtext"},
343 {Opt_ignore, "conv=m"},
344 {Opt_ignore, "conv=auto"},
345 {Opt_ignore, "conv=a"},
346 {Opt_nocompress, "nocompress"},
347 {Opt_err, NULL}
348};
349
Andrew Morton9eb7f2c2005-06-21 17:16:49 -0700350static int parse_options(char *options, struct iso9660_options *popt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351{
352 char *p;
353 int option;
354
355 popt->map = 'n';
356 popt->rock = 'y';
357 popt->joliet = 'y';
358 popt->cruft = 'n';
Jeremy White9769f4e2005-06-21 17:16:53 -0700359 popt->hide = 'n';
360 popt->showassoc = 'n';
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 popt->check = 'u'; /* unset */
362 popt->nocompress = 0;
363 popt->blocksize = 1024;
364 popt->mode = S_IRUGO | S_IXUGO; /* r-x for all. The disc could
365 be shared with DOS machines so
366 virtually anything could be
367 a valid executable. */
368 popt->gid = 0;
369 popt->uid = 0;
370 popt->iocharset = NULL;
371 popt->utf8 = 0;
372 popt->session=-1;
373 popt->sbsector=-1;
374 if (!options)
375 return 1;
376
377 while ((p = strsep(&options, ",")) != NULL) {
378 int token;
379 substring_t args[MAX_OPT_ARGS];
380 unsigned n;
381
382 if (!*p)
383 continue;
384
385 token = match_token(p, tokens, args);
386 switch (token) {
387 case Opt_norock:
388 popt->rock = 'n';
389 break;
390 case Opt_nojoliet:
391 popt->joliet = 'n';
392 break;
Jeremy White9769f4e2005-06-21 17:16:53 -0700393 case Opt_hide:
394 popt->hide = 'y';
395 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 case Opt_unhide:
Jeremy White9769f4e2005-06-21 17:16:53 -0700397 case Opt_showassoc:
398 popt->showassoc = 'y';
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 break;
400 case Opt_cruft:
401 popt->cruft = 'y';
402 break;
403 case Opt_utf8:
404 popt->utf8 = 1;
405 break;
406#ifdef CONFIG_JOLIET
407 case Opt_iocharset:
408 popt->iocharset = match_strdup(&args[0]);
409 break;
410#endif
411 case Opt_map_a:
412 popt->map = 'a';
413 break;
414 case Opt_map_o:
415 popt->map = 'o';
416 break;
417 case Opt_map_n:
418 popt->map = 'n';
419 break;
420 case Opt_session:
421 if (match_int(&args[0], &option))
422 return 0;
423 n = option;
424 if (n > 99)
425 return 0;
426 popt->session = n + 1;
427 break;
428 case Opt_sb:
429 if (match_int(&args[0], &option))
430 return 0;
431 popt->sbsector = option;
432 break;
433 case Opt_check_r:
434 popt->check = 'r';
435 break;
436 case Opt_check_s:
437 popt->check = 's';
438 break;
439 case Opt_ignore:
440 break;
441 case Opt_uid:
442 if (match_int(&args[0], &option))
443 return 0;
444 popt->uid = option;
445 break;
446 case Opt_gid:
447 if (match_int(&args[0], &option))
448 return 0;
449 popt->gid = option;
450 break;
451 case Opt_mode:
452 if (match_int(&args[0], &option))
453 return 0;
454 popt->mode = option;
455 break;
456 case Opt_block:
457 if (match_int(&args[0], &option))
458 return 0;
459 n = option;
460 if (n != 512 && n != 1024 && n != 2048)
461 return 0;
462 popt->blocksize = n;
463 break;
464 case Opt_nocompress:
465 popt->nocompress = 1;
466 break;
467 default:
468 return 0;
469 }
470 }
471 return 1;
472}
473
474/*
475 * look if the driver can tell the multi session redirection value
476 *
477 * don't change this if you don't know what you do, please!
478 * Multisession is legal only with XA disks.
479 * A non-XA disk with more than one volume descriptor may do it right, but
480 * usually is written in a nowhere standardized "multi-partition" manner.
481 * Multisession uses absolute addressing (solely the first frame of the whole
482 * track is #0), multi-partition uses relative addressing (each first frame of
483 * each track is #0), and a track is not a session.
484 *
485 * A broken CDwriter software or drive firmware does not set new standards,
486 * at least not if conflicting with the existing ones.
487 *
488 * emoenke@gwdg.de
489 */
490#define WE_OBEY_THE_WRITTEN_STANDARDS 1
491
Andrew Morton9eb7f2c2005-06-21 17:16:49 -0700492static unsigned int isofs_get_last_session(struct super_block *sb, s32 session)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493{
494 struct cdrom_multisession ms_info;
495 unsigned int vol_desc_start;
496 struct block_device *bdev = sb->s_bdev;
497 int i;
498
499 vol_desc_start=0;
500 ms_info.addr_format=CDROM_LBA;
501 if(session >= 0 && session <= 99) {
502 struct cdrom_tocentry Te;
503 Te.cdte_track=session;
504 Te.cdte_format=CDROM_LBA;
505 i = ioctl_by_bdev(bdev, CDROMREADTOCENTRY, (unsigned long) &Te);
506 if (!i) {
507 printk(KERN_DEBUG "Session %d start %d type %d\n",
508 session, Te.cdte_addr.lba,
509 Te.cdte_ctrl&CDROM_DATA_TRACK);
510 if ((Te.cdte_ctrl&CDROM_DATA_TRACK) == 4)
511 return Te.cdte_addr.lba;
512 }
513
514 printk(KERN_ERR "Invalid session number or type of track\n");
515 }
516 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
Andrew Morton9eb7f2c2005-06-21 17:16:49 -0700517 if (session > 0)
518 printk(KERN_ERR "Invalid session number\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519#if 0
520 printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
521 if (i==0) {
522 printk("isofs.inode: XA disk: %s\n",ms_info.xa_flag?"yes":"no");
523 printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
524 }
525#endif
526 if (i==0)
527#if WE_OBEY_THE_WRITTEN_STANDARDS
528 if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
529#endif
530 vol_desc_start=ms_info.addr.lba;
531 return vol_desc_start;
532}
533
534/*
535 * Initialize the superblock and read the root inode.
536 *
537 * Note: a check_disk_change() has been done immediately prior
538 * to this call, so we don't need to check again.
539 */
540static int isofs_fill_super(struct super_block *s, void *data, int silent)
541{
542 struct buffer_head * bh = NULL, *pri_bh = NULL;
543 struct hs_primary_descriptor * h_pri = NULL;
544 struct iso_primary_descriptor * pri = NULL;
545 struct iso_supplementary_descriptor *sec = NULL;
546 struct iso_directory_record * rootp;
547 int joliet_level = 0;
548 int iso_blknum, block;
549 int orig_zonesize;
550 int table;
551 unsigned int vol_desc_start;
552 unsigned long first_data_zone;
553 struct inode * inode;
554 struct iso9660_options opt;
555 struct isofs_sb_info * sbi;
556
Panagiotis Issarisf8314dc2006-09-27 01:49:37 -0700557 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 if (!sbi)
559 return -ENOMEM;
560 s->s_fs_info = sbi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
Andrew Morton9eb7f2c2005-06-21 17:16:49 -0700562 if (!parse_options((char *)data, &opt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 goto out_freesbi;
564
565 /*
566 * First of all, get the hardware blocksize for this device.
567 * If we don't know what it is, or the hardware blocksize is
568 * larger than the blocksize the user specified, then use
569 * that value.
570 */
571 /*
572 * What if bugger tells us to go beyond page size?
573 */
574 opt.blocksize = sb_min_blocksize(s, opt.blocksize);
575
576 sbi->s_high_sierra = 0; /* default is iso9660 */
577
578 vol_desc_start = (opt.sbsector != -1) ?
579 opt.sbsector : isofs_get_last_session(s,opt.session);
580
581 for (iso_blknum = vol_desc_start+16;
582 iso_blknum < vol_desc_start+100; iso_blknum++)
583 {
584 struct hs_volume_descriptor * hdp;
585 struct iso_volume_descriptor * vdp;
586
587 block = iso_blknum << (ISOFS_BLOCK_BITS - s->s_blocksize_bits);
588 if (!(bh = sb_bread(s, block)))
589 goto out_no_read;
590
591 vdp = (struct iso_volume_descriptor *)bh->b_data;
592 hdp = (struct hs_volume_descriptor *)bh->b_data;
593
594 /* Due to the overlapping physical location of the descriptors,
595 * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure
596 * proper identification in this case, we first check for ISO.
597 */
598 if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
599 if (isonum_711 (vdp->type) == ISO_VD_END)
600 break;
601 if (isonum_711 (vdp->type) == ISO_VD_PRIMARY) {
602 if (pri == NULL) {
603 pri = (struct iso_primary_descriptor *)vdp;
604 /* Save the buffer in case we need it ... */
605 pri_bh = bh;
606 bh = NULL;
607 }
608 }
609#ifdef CONFIG_JOLIET
610 else if (isonum_711 (vdp->type) == ISO_VD_SUPPLEMENTARY) {
611 sec = (struct iso_supplementary_descriptor *)vdp;
612 if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) {
613 if (opt.joliet == 'y') {
614 if (sec->escape[2] == 0x40) {
615 joliet_level = 1;
616 } else if (sec->escape[2] == 0x43) {
617 joliet_level = 2;
618 } else if (sec->escape[2] == 0x45) {
619 joliet_level = 3;
620 }
621 printk(KERN_DEBUG"ISO 9660 Extensions: Microsoft Joliet Level %d\n",
622 joliet_level);
623 }
624 goto root_found;
625 } else {
626 /* Unknown supplementary volume descriptor */
627 sec = NULL;
628 }
629 }
630#endif
631 } else {
632 if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {
633 if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)
634 goto out_freebh;
635
636 sbi->s_high_sierra = 1;
637 opt.rock = 'n';
638 h_pri = (struct hs_primary_descriptor *)vdp;
639 goto root_found;
640 }
641 }
642
643 /* Just skip any volume descriptors we don't recognize */
644
645 brelse(bh);
646 bh = NULL;
647 }
648 /*
649 * If we fall through, either no volume descriptor was found,
650 * or else we passed a primary descriptor looking for others.
651 */
652 if (!pri)
653 goto out_unknown_format;
654 brelse(bh);
655 bh = pri_bh;
656 pri_bh = NULL;
657
658root_found:
659
660 if (joliet_level && (pri == NULL || opt.rock == 'n')) {
661 /* This is the case of Joliet with the norock mount flag.
662 * A disc with both Joliet and Rock Ridge is handled later
663 */
664 pri = (struct iso_primary_descriptor *) sec;
665 }
666
667 if(sbi->s_high_sierra){
668 rootp = (struct iso_directory_record *) h_pri->root_directory_record;
669 sbi->s_nzones = isonum_733 (h_pri->volume_space_size);
670 sbi->s_log_zone_size = isonum_723 (h_pri->logical_block_size);
671 sbi->s_max_size = isonum_733(h_pri->volume_space_size);
672 } else {
673 if (!pri)
674 goto out_freebh;
675 rootp = (struct iso_directory_record *) pri->root_directory_record;
676 sbi->s_nzones = isonum_733 (pri->volume_space_size);
677 sbi->s_log_zone_size = isonum_723 (pri->logical_block_size);
678 sbi->s_max_size = isonum_733(pri->volume_space_size);
679 }
680
681 sbi->s_ninodes = 0; /* No way to figure this out easily */
682
683 orig_zonesize = sbi->s_log_zone_size;
684 /*
685 * If the zone size is smaller than the hardware sector size,
686 * this is a fatal error. This would occur if the disc drive
687 * had sectors that were 2048 bytes, but the filesystem had
688 * blocks that were 512 bytes (which should only very rarely
689 * happen.)
690 */
691 if(orig_zonesize < opt.blocksize)
692 goto out_bad_size;
693
694 /* RDE: convert log zone size to bit shift */
695 switch (sbi->s_log_zone_size)
696 { case 512: sbi->s_log_zone_size = 9; break;
697 case 1024: sbi->s_log_zone_size = 10; break;
698 case 2048: sbi->s_log_zone_size = 11; break;
699
700 default:
701 goto out_bad_zone_size;
702 }
703
704 s->s_magic = ISOFS_SUPER_MAGIC;
705 s->s_maxbytes = 0xffffffff; /* We can handle files up to 4 GB */
706
707 /* The CDROM is read-only, has no nodes (devices) on it, and since
708 all of the files appear to be owned by root, we really do not want
709 to allow suid. (suid or devices will not show up unless we have
710 Rock Ridge extensions) */
711
712 s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */;
713
714 /* Set this for reference. Its not currently used except on write
715 which we don't have .. */
716
717 first_data_zone = isonum_733 (rootp->extent) +
718 isonum_711 (rootp->ext_attr_length);
719 sbi->s_firstdatazone = first_data_zone;
720#ifndef BEQUIET
721 printk(KERN_DEBUG "Max size:%ld Log zone size:%ld\n",
722 sbi->s_max_size,
723 1UL << sbi->s_log_zone_size);
724 printk(KERN_DEBUG "First datazone:%ld\n", sbi->s_firstdatazone);
725 if(sbi->s_high_sierra)
726 printk(KERN_DEBUG "Disc in High Sierra format.\n");
727#endif
728
729 /*
730 * If the Joliet level is set, we _may_ decide to use the
731 * secondary descriptor, but can't be sure until after we
732 * read the root inode. But before reading the root inode
733 * we may need to change the device blocksize, and would
734 * rather release the old buffer first. So, we cache the
735 * first_data_zone value from the secondary descriptor.
736 */
737 if (joliet_level) {
738 pri = (struct iso_primary_descriptor *) sec;
739 rootp = (struct iso_directory_record *)
740 pri->root_directory_record;
741 first_data_zone = isonum_733 (rootp->extent) +
742 isonum_711 (rootp->ext_attr_length);
743 }
744
745 /*
746 * We're all done using the volume descriptor, and may need
747 * to change the device blocksize, so release the buffer now.
748 */
749 brelse(pri_bh);
750 brelse(bh);
751
752 /*
753 * Force the blocksize to 512 for 512 byte sectors. The file
754 * read primitives really get it wrong in a bad way if we don't
755 * do this.
756 *
757 * Note - we should never be setting the blocksize to something
758 * less than the hardware sector size for the device. If we
759 * do, we would end up having to read larger buffers and split
760 * out portions to satisfy requests.
761 *
762 * Note2- the idea here is that we want to deal with the optimal
763 * zonesize in the filesystem. If we have it set to something less,
764 * then we have horrible problems with trying to piece together
765 * bits of adjacent blocks in order to properly read directory
766 * entries. By forcing the blocksize in this way, we ensure
767 * that we will never be required to do this.
768 */
769 sb_set_blocksize(s, orig_zonesize);
770
771 sbi->s_nls_iocharset = NULL;
772
773#ifdef CONFIG_JOLIET
774 if (joliet_level && opt.utf8 == 0) {
775 char * p = opt.iocharset ? opt.iocharset : CONFIG_NLS_DEFAULT;
776 sbi->s_nls_iocharset = load_nls(p);
777 if (! sbi->s_nls_iocharset) {
778 /* Fail only if explicit charset specified */
779 if (opt.iocharset)
780 goto out_freesbi;
781 sbi->s_nls_iocharset = load_nls_default();
782 }
783 }
784#endif
785 s->s_op = &isofs_sops;
786 s->s_export_op = &isofs_export_ops;
787 sbi->s_mapping = opt.map;
788 sbi->s_rock = (opt.rock == 'y' ? 2 : 0);
789 sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/
790 sbi->s_cruft = opt.cruft;
Jeremy White9769f4e2005-06-21 17:16:53 -0700791 sbi->s_hide = opt.hide;
792 sbi->s_showassoc = opt.showassoc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 sbi->s_uid = opt.uid;
794 sbi->s_gid = opt.gid;
795 sbi->s_utf8 = opt.utf8;
796 sbi->s_nocompress = opt.nocompress;
797 /*
798 * It would be incredibly stupid to allow people to mark every file
799 * on the disk as suid, so we merely allow them to set the default
800 * permissions.
801 */
802 sbi->s_mode = opt.mode & 0777;
803
804 /*
805 * Read the root inode, which _may_ result in changing
806 * the s_rock flag. Once we have the final s_rock value,
807 * we then decide whether to use the Joliet descriptor.
808 */
809 inode = isofs_iget(s, sbi->s_firstdatazone, 0);
810
811 /*
812 * If this disk has both Rock Ridge and Joliet on it, then we
813 * want to use Rock Ridge by default. This can be overridden
814 * by using the norock mount option. There is still one other
815 * possibility that is not taken into account: a Rock Ridge
816 * CD with Unicode names. Until someone sees such a beast, it
817 * will not be supported.
818 */
819 if (sbi->s_rock == 1) {
820 joliet_level = 0;
821 } else if (joliet_level) {
822 sbi->s_rock = 0;
823 if (sbi->s_firstdatazone != first_data_zone) {
824 sbi->s_firstdatazone = first_data_zone;
825 printk(KERN_DEBUG
826 "ISOFS: changing to secondary root\n");
827 iput(inode);
828 inode = isofs_iget(s, sbi->s_firstdatazone, 0);
829 }
830 }
831
832 if (opt.check == 'u') {
833 /* Only Joliet is case insensitive by default */
834 if (joliet_level) opt.check = 'r';
835 else opt.check = 's';
836 }
837 sbi->s_joliet_level = joliet_level;
838
839 /* check the root inode */
840 if (!inode)
841 goto out_no_root;
842 if (!inode->i_op)
843 goto out_bad_root;
844 /* get the root dentry */
845 s->s_root = d_alloc_root(inode);
846 if (!(s->s_root))
847 goto out_no_root;
848
849 table = 0;
850 if (joliet_level) table += 2;
851 if (opt.check == 'r') table++;
852 s->s_root->d_op = &isofs_dentry_ops[table];
853
Jesper Juhlf99d49a2005-11-07 01:01:34 -0800854 kfree(opt.iocharset);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
856 return 0;
857
858 /*
859 * Display error messages and free resources.
860 */
861out_bad_root:
862 printk(KERN_WARNING "isofs_fill_super: root inode not initialized\n");
863 goto out_iput;
864out_no_root:
865 printk(KERN_WARNING "isofs_fill_super: get root inode failed\n");
866out_iput:
867 iput(inode);
868#ifdef CONFIG_JOLIET
869 if (sbi->s_nls_iocharset)
870 unload_nls(sbi->s_nls_iocharset);
871#endif
872 goto out_freesbi;
873out_no_read:
874 printk(KERN_WARNING "isofs_fill_super: "
875 "bread failed, dev=%s, iso_blknum=%d, block=%d\n",
876 s->s_id, iso_blknum, block);
877 goto out_freesbi;
878out_bad_zone_size:
879 printk(KERN_WARNING "Bad logical zone size %ld\n",
880 sbi->s_log_zone_size);
881 goto out_freebh;
882out_bad_size:
883 printk(KERN_WARNING "Logical zone size(%d) < hardware blocksize(%u)\n",
884 orig_zonesize, opt.blocksize);
885 goto out_freebh;
886out_unknown_format:
887 if (!silent)
888 printk(KERN_WARNING "Unable to identify CD-ROM format.\n");
889
890out_freebh:
891 brelse(bh);
892out_freesbi:
Jesper Juhlf99d49a2005-11-07 01:01:34 -0800893 kfree(opt.iocharset);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 kfree(sbi);
895 s->s_fs_info = NULL;
896 return -EINVAL;
897}
898
David Howells726c3342006-06-23 02:02:58 -0700899static int isofs_statfs (struct dentry *dentry, struct kstatfs *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900{
David Howells726c3342006-06-23 02:02:58 -0700901 struct super_block *sb = dentry->d_sb;
902
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 buf->f_type = ISOFS_SUPER_MAGIC;
904 buf->f_bsize = sb->s_blocksize;
905 buf->f_blocks = (ISOFS_SB(sb)->s_nzones
906 << (ISOFS_SB(sb)->s_log_zone_size - sb->s_blocksize_bits));
907 buf->f_bfree = 0;
908 buf->f_bavail = 0;
909 buf->f_files = ISOFS_SB(sb)->s_ninodes;
910 buf->f_ffree = 0;
911 buf->f_namelen = NAME_MAX;
912 return 0;
913}
914
915/*
916 * Get a set of blocks; filling in buffer_heads if already allocated
917 * or getblk() if they are not. Returns the number of blocks inserted
918 * (0 == error.)
919 */
920int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
921 struct buffer_head **bh, unsigned long nblocks)
922{
923 unsigned long b_off;
924 unsigned offset, sect_size;
925 unsigned int firstext;
926 unsigned long nextblk, nextoff;
927 long iblock = (long)iblock_s;
928 int section, rv;
929 struct iso_inode_info *ei = ISOFS_I(inode);
930
931 lock_kernel();
932
933 rv = 0;
934 if (iblock < 0 || iblock != iblock_s) {
935 printk("isofs_get_blocks: block number too large\n");
936 goto abort;
937 }
938
939 b_off = iblock;
940
941 offset = 0;
942 firstext = ei->i_first_extent;
943 sect_size = ei->i_section_size >> ISOFS_BUFFER_BITS(inode);
944 nextblk = ei->i_next_section_block;
945 nextoff = ei->i_next_section_offset;
946 section = 0;
947
948 while ( nblocks ) {
949 /* If we are *way* beyond the end of the file, print a message.
950 * Access beyond the end of the file up to the next page boundary
951 * is normal, however because of the way the page cache works.
952 * In this case, we just return 0 so that we can properly fill
953 * the page with useless information without generating any
954 * I/O errors.
955 */
956 if (b_off > ((inode->i_size + PAGE_CACHE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) {
957 printk("isofs_get_blocks: block >= EOF (%ld, %ld)\n",
958 iblock, (unsigned long) inode->i_size);
959 goto abort;
960 }
961
Joel & Rebecca VanderZeefb50ae72006-09-29 02:00:30 -0700962 /* On the last section, nextblk == 0, section size is likely to
963 * exceed sect_size by a partial block, and access beyond the
964 * end of the file will reach beyond the section size, too.
965 */
966 while (nextblk && (b_off >= (offset + sect_size))) {
967 struct inode *ninode;
968
969 offset += sect_size;
970 ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
971 if (!ninode)
972 goto abort;
973 firstext = ISOFS_I(ninode)->i_first_extent;
974 sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
975 nextblk = ISOFS_I(ninode)->i_next_section_block;
976 nextoff = ISOFS_I(ninode)->i_next_section_offset;
977 iput(ninode);
978
979 if (++section > 100) {
980 printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
981 printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
982 "nextblk=%lu nextoff=%lu\n",
983 iblock, firstext, (unsigned) sect_size,
984 nextblk, nextoff);
985 goto abort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 }
987 }
988
989 if ( *bh ) {
990 map_bh(*bh, inode->i_sb, firstext + b_off - offset);
991 } else {
992 *bh = sb_getblk(inode->i_sb, firstext+b_off-offset);
993 if ( !*bh )
994 goto abort;
995 }
996 bh++; /* Next buffer head */
997 b_off++; /* Next buffer offset */
998 nblocks--;
999 rv++;
1000 }
1001
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002abort:
1003 unlock_kernel();
1004 return rv;
1005}
1006
1007/*
1008 * Used by the standard interfaces.
1009 */
1010static int isofs_get_block(struct inode *inode, sector_t iblock,
1011 struct buffer_head *bh_result, int create)
1012{
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001013 if (create) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 printk("isofs_get_block: Kernel tries to allocate a block\n");
1015 return -EROFS;
1016 }
1017
1018 return isofs_get_blocks(inode, iblock, &bh_result, 1) ? 0 : -EIO;
1019}
1020
1021static int isofs_bmap(struct inode *inode, sector_t block)
1022{
1023 struct buffer_head dummy;
1024 int error;
1025
1026 dummy.b_state = 0;
1027 dummy.b_blocknr = -1000;
1028 error = isofs_get_block(inode, block, &dummy, 0);
1029 if (!error)
1030 return dummy.b_blocknr;
1031 return 0;
1032}
1033
1034struct buffer_head *isofs_bread(struct inode *inode, sector_t block)
1035{
1036 sector_t blknr = isofs_bmap(inode, block);
1037 if (!blknr)
1038 return NULL;
1039 return sb_bread(inode->i_sb, blknr);
1040}
1041
1042static int isofs_readpage(struct file *file, struct page *page)
1043{
1044 return block_read_full_page(page,isofs_get_block);
1045}
1046
1047static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
1048{
1049 return generic_block_bmap(mapping,block,isofs_get_block);
1050}
1051
Christoph Hellwigf5e54d62006-06-28 04:26:44 -07001052static const struct address_space_operations isofs_aops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 .readpage = isofs_readpage,
1054 .sync_page = block_sync_page,
1055 .bmap = _isofs_bmap
1056};
1057
1058static inline void test_and_set_uid(uid_t *p, uid_t value)
1059{
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001060 if (value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 *p = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062}
1063
1064static inline void test_and_set_gid(gid_t *p, gid_t value)
1065{
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001066 if (value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 *p = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068}
1069
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001070static int isofs_read_level3_size(struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071{
1072 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
1073 int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra;
1074 struct buffer_head * bh = NULL;
1075 unsigned long block, offset, block_saved, offset_saved;
1076 int i = 0;
1077 int more_entries = 0;
1078 struct iso_directory_record * tmpde = NULL;
1079 struct iso_inode_info *ei = ISOFS_I(inode);
1080
1081 inode->i_size = 0;
1082
1083 /* The first 16 blocks are reserved as the System Area. Thus,
1084 * no inodes can appear in block 0. We use this to flag that
1085 * this is the last section. */
1086 ei->i_next_section_block = 0;
1087 ei->i_next_section_offset = 0;
1088
1089 block = ei->i_iget5_block;
1090 offset = ei->i_iget5_offset;
1091
1092 do {
1093 struct iso_directory_record * de;
1094 unsigned int de_len;
1095
1096 if (!bh) {
1097 bh = sb_bread(inode->i_sb, block);
1098 if (!bh)
1099 goto out_noread;
1100 }
1101 de = (struct iso_directory_record *) (bh->b_data + offset);
1102 de_len = *(unsigned char *) de;
1103
1104 if (de_len == 0) {
1105 brelse(bh);
1106 bh = NULL;
1107 ++block;
1108 offset = 0;
1109 continue;
1110 }
1111
1112 block_saved = block;
1113 offset_saved = offset;
1114 offset += de_len;
1115
1116 /* Make sure we have a full directory entry */
1117 if (offset >= bufsize) {
1118 int slop = bufsize - offset + de_len;
1119 if (!tmpde) {
1120 tmpde = kmalloc(256, GFP_KERNEL);
1121 if (!tmpde)
1122 goto out_nomem;
1123 }
1124 memcpy(tmpde, de, slop);
1125 offset &= bufsize - 1;
1126 block++;
1127 brelse(bh);
1128 bh = NULL;
1129 if (offset) {
1130 bh = sb_bread(inode->i_sb, block);
1131 if (!bh)
1132 goto out_noread;
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001133 memcpy((void *)tmpde+slop, bh->b_data, offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 }
1135 de = tmpde;
1136 }
1137
1138 inode->i_size += isonum_733(de->size);
1139 if (i == 1) {
1140 ei->i_next_section_block = block_saved;
1141 ei->i_next_section_offset = offset_saved;
1142 }
1143
1144 more_entries = de->flags[-high_sierra] & 0x80;
1145
1146 i++;
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001147 if (i > 100)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 goto out_toomany;
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001149 } while (more_entries);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150out:
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001151 kfree(tmpde);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 if (bh)
1153 brelse(bh);
1154 return 0;
1155
1156out_nomem:
1157 if (bh)
1158 brelse(bh);
1159 return -ENOMEM;
1160
1161out_noread:
1162 printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
Jesper Juhlf99d49a2005-11-07 01:01:34 -08001163 kfree(tmpde);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 return -EIO;
1165
1166out_toomany:
1167 printk(KERN_INFO "isofs_read_level3_size: "
1168 "More than 100 file sections ?!?, aborting...\n"
1169 "isofs_read_level3_size: inode=%lu\n",
1170 inode->i_ino);
1171 goto out;
1172}
1173
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001174static void isofs_read_inode(struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175{
1176 struct super_block *sb = inode->i_sb;
1177 struct isofs_sb_info *sbi = ISOFS_SB(sb);
1178 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
1179 unsigned long block;
1180 int high_sierra = sbi->s_high_sierra;
1181 struct buffer_head * bh = NULL;
1182 struct iso_directory_record * de;
1183 struct iso_directory_record * tmpde = NULL;
1184 unsigned int de_len;
1185 unsigned long offset;
1186 struct iso_inode_info *ei = ISOFS_I(inode);
1187
1188 block = ei->i_iget5_block;
1189 bh = sb_bread(inode->i_sb, block);
1190 if (!bh)
1191 goto out_badread;
1192
1193 offset = ei->i_iget5_offset;
1194
1195 de = (struct iso_directory_record *) (bh->b_data + offset);
1196 de_len = *(unsigned char *) de;
1197
1198 if (offset + de_len > bufsize) {
1199 int frag1 = bufsize - offset;
1200
1201 tmpde = kmalloc(de_len, GFP_KERNEL);
1202 if (tmpde == NULL) {
1203 printk(KERN_INFO "isofs_read_inode: out of memory\n");
1204 goto fail;
1205 }
1206 memcpy(tmpde, bh->b_data + offset, frag1);
1207 brelse(bh);
1208 bh = sb_bread(inode->i_sb, ++block);
1209 if (!bh)
1210 goto out_badread;
1211 memcpy((char *)tmpde+frag1, bh->b_data, de_len - frag1);
1212 de = tmpde;
1213 }
1214
1215 inode->i_ino = isofs_get_ino(ei->i_iget5_block,
1216 ei->i_iget5_offset,
1217 ISOFS_BUFFER_BITS(inode));
1218
1219 /* Assume it is a normal-format file unless told otherwise */
1220 ei->i_file_format = isofs_file_normal;
1221
1222 if (de->flags[-high_sierra] & 2) {
1223 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
1224 inode->i_nlink = 1; /* Set to 1. We know there are 2, but
1225 the find utility tries to optimize
1226 if it is 2, and it screws up. It is
1227 easier to give 1 which tells find to
1228 do it the hard way. */
1229 } else {
1230 /* Everybody gets to read the file. */
1231 inode->i_mode = sbi->s_mode;
1232 inode->i_nlink = 1;
1233 inode->i_mode |= S_IFREG;
1234 }
1235 inode->i_uid = sbi->s_uid;
1236 inode->i_gid = sbi->s_gid;
Theodore Ts'oba52de12006-09-27 01:50:49 -07001237 inode->i_blocks = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238
1239 ei->i_format_parm[0] = 0;
1240 ei->i_format_parm[1] = 0;
1241 ei->i_format_parm[2] = 0;
1242
1243 ei->i_section_size = isonum_733 (de->size);
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001244 if (de->flags[-high_sierra] & 0x80) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 if(isofs_read_level3_size(inode)) goto fail;
1246 } else {
1247 ei->i_next_section_block = 0;
1248 ei->i_next_section_offset = 0;
1249 inode->i_size = isonum_733 (de->size);
1250 }
1251
1252 /*
1253 * Some dipshit decided to store some other bit of information
1254 * in the high byte of the file length. Truncate size in case
1255 * this CDROM was mounted with the cruft option.
1256 */
1257
1258 if (sbi->s_cruft == 'y')
1259 inode->i_size &= 0x00ffffff;
1260
1261 if (de->interleave[0]) {
1262 printk("Interleaved files not (yet) supported.\n");
1263 inode->i_size = 0;
1264 }
1265
1266 /* I have no idea what file_unit_size is used for, so
1267 we will flag it for now */
1268 if (de->file_unit_size[0] != 0) {
1269 printk("File unit size != 0 for ISO file (%ld).\n",
1270 inode->i_ino);
1271 }
1272
1273 /* I have no idea what other flag bits are used for, so
1274 we will flag it for now */
1275#ifdef DEBUG
1276 if((de->flags[-high_sierra] & ~2)!= 0){
1277 printk("Unusual flag settings for ISO file (%ld %x).\n",
1278 inode->i_ino, de->flags[-high_sierra]);
1279 }
1280#endif
1281
1282 inode->i_mtime.tv_sec =
1283 inode->i_atime.tv_sec =
1284 inode->i_ctime.tv_sec = iso_date(de->date, high_sierra);
1285 inode->i_mtime.tv_nsec =
1286 inode->i_atime.tv_nsec =
1287 inode->i_ctime.tv_nsec = 0;
1288
1289 ei->i_first_extent = (isonum_733 (de->extent) +
1290 isonum_711 (de->ext_attr_length));
1291
1292 /* Set the number of blocks for stat() - should be done before RR */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293 inode->i_blocks = (inode->i_size + 511) >> 9;
1294
1295 /*
1296 * Now test for possible Rock Ridge extensions which will override
1297 * some of these numbers in the inode structure.
1298 */
1299
1300 if (!high_sierra) {
1301 parse_rock_ridge_inode(de, inode);
1302 /* if we want uid/gid set, override the rock ridge setting */
1303 test_and_set_uid(&inode->i_uid, sbi->s_uid);
1304 test_and_set_gid(&inode->i_gid, sbi->s_gid);
1305 }
1306
1307 /* Install the inode operations vector */
1308 if (S_ISREG(inode->i_mode)) {
1309 inode->i_fop = &generic_ro_fops;
1310 switch ( ei->i_file_format ) {
1311#ifdef CONFIG_ZISOFS
1312 case isofs_file_compressed:
1313 inode->i_data.a_ops = &zisofs_aops;
1314 break;
1315#endif
1316 default:
1317 inode->i_data.a_ops = &isofs_aops;
1318 break;
1319 }
1320 } else if (S_ISDIR(inode->i_mode)) {
1321 inode->i_op = &isofs_dir_inode_operations;
1322 inode->i_fop = &isofs_dir_operations;
1323 } else if (S_ISLNK(inode->i_mode)) {
1324 inode->i_op = &page_symlink_inode_operations;
1325 inode->i_data.a_ops = &isofs_symlink_aops;
1326 } else
1327 /* XXX - parse_rock_ridge_inode() had already set i_rdev. */
1328 init_special_inode(inode, inode->i_mode, inode->i_rdev);
1329
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001330out:
Jesper Juhlf99d49a2005-11-07 01:01:34 -08001331 kfree(tmpde);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 if (bh)
1333 brelse(bh);
1334 return;
1335
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001336out_badread:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 printk(KERN_WARNING "ISOFS: unable to read i-node block\n");
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001338fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 make_bad_inode(inode);
1340 goto out;
1341}
1342
1343struct isofs_iget5_callback_data {
1344 unsigned long block;
1345 unsigned long offset;
1346};
1347
1348static int isofs_iget5_test(struct inode *ino, void *data)
1349{
1350 struct iso_inode_info *i = ISOFS_I(ino);
1351 struct isofs_iget5_callback_data *d =
1352 (struct isofs_iget5_callback_data*)data;
1353 return (i->i_iget5_block == d->block)
1354 && (i->i_iget5_offset == d->offset);
1355}
1356
1357static int isofs_iget5_set(struct inode *ino, void *data)
1358{
1359 struct iso_inode_info *i = ISOFS_I(ino);
1360 struct isofs_iget5_callback_data *d =
1361 (struct isofs_iget5_callback_data*)data;
1362 i->i_iget5_block = d->block;
1363 i->i_iget5_offset = d->offset;
1364 return 0;
1365}
1366
1367/* Store, in the inode's containing structure, the block and block
1368 * offset that point to the underlying meta-data for the inode. The
1369 * code below is otherwise similar to the iget() code in
1370 * include/linux/fs.h */
1371struct inode *isofs_iget(struct super_block *sb,
1372 unsigned long block,
1373 unsigned long offset)
1374{
1375 unsigned long hashval;
1376 struct inode *inode;
1377 struct isofs_iget5_callback_data data;
1378
1379 if (offset >= 1ul << sb->s_blocksize_bits)
1380 return NULL;
1381
1382 data.block = block;
1383 data.offset = offset;
1384
1385 hashval = (block << sb->s_blocksize_bits) | offset;
1386
Andrew Morton9eb7f2c2005-06-21 17:16:49 -07001387 inode = iget5_locked(sb, hashval, &isofs_iget5_test,
1388 &isofs_iget5_set, &data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
1390 if (inode && (inode->i_state & I_NEW)) {
1391 sb->s_op->read_inode(inode);
1392 unlock_new_inode(inode);
1393 }
1394
1395 return inode;
1396}
1397
David Howells454e2392006-06-23 02:02:57 -07001398static int isofs_get_sb(struct file_system_type *fs_type,
1399 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400{
David Howells454e2392006-06-23 02:02:57 -07001401 return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super,
1402 mnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403}
1404
1405static struct file_system_type iso9660_fs_type = {
1406 .owner = THIS_MODULE,
1407 .name = "iso9660",
1408 .get_sb = isofs_get_sb,
1409 .kill_sb = kill_block_super,
1410 .fs_flags = FS_REQUIRES_DEV,
1411};
1412
1413static int __init init_iso9660_fs(void)
1414{
1415 int err = init_inodecache();
1416 if (err)
1417 goto out;
1418#ifdef CONFIG_ZISOFS
1419 err = zisofs_init();
1420 if (err)
1421 goto out1;
1422#endif
1423 err = register_filesystem(&iso9660_fs_type);
1424 if (err)
1425 goto out2;
1426 return 0;
1427out2:
1428#ifdef CONFIG_ZISOFS
1429 zisofs_cleanup();
1430out1:
1431#endif
1432 destroy_inodecache();
1433out:
1434 return err;
1435}
1436
1437static void __exit exit_iso9660_fs(void)
1438{
1439 unregister_filesystem(&iso9660_fs_type);
1440#ifdef CONFIG_ZISOFS
1441 zisofs_cleanup();
1442#endif
1443 destroy_inodecache();
1444}
1445
1446module_init(init_iso9660_fs)
1447module_exit(exit_iso9660_fs)
1448MODULE_LICENSE("GPL");
1449/* Actual filesystem name is iso9660, as requested in filesystems.c */
1450MODULE_ALIAS("iso9660");