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