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