📄 inode.c
字号:
rootp = (struct iso_directory_record *) h_pri->root_directory_record;#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS if (isonum_723 (h_pri->volume_set_size) != 1) { printk("Multi-volume disks not supported.\n"); goto out; }#endif IGNORE_WRONG_MULTI_VOLUME_SPECS s->u.isofs_sb.s_nzones = isonum_733 (h_pri->volume_space_size); s->u.isofs_sb.s_log_zone_size = isonum_723 (h_pri->logical_block_size); s->u.isofs_sb.s_max_size = isonum_733(h_pri->volume_space_size); } else { rootp = (struct iso_directory_record *) pri->root_directory_record;#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS if (isonum_723 (pri->volume_set_size) != 1) { printk("Multi-volume disks not supported.\n"); goto out; }#endif IGNORE_WRONG_MULTI_VOLUME_SPECS s->u.isofs_sb.s_nzones = isonum_733 (pri->volume_space_size); s->u.isofs_sb.s_log_zone_size = isonum_723 (pri->logical_block_size); s->u.isofs_sb.s_max_size = isonum_733(pri->volume_space_size); } s->u.isofs_sb.s_ninodes = 0; /* No way to figure this out easily */ /* RDE: convert log zone size to bit shift */ orig_zonesize = s -> u.isofs_sb.s_log_zone_size; switch (s -> u.isofs_sb.s_log_zone_size) { case 512: s -> u.isofs_sb.s_log_zone_size = 9; break; case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break; case 2048: s -> u.isofs_sb.s_log_zone_size = 11; break; default: printk("Bad logical zone size %ld\n", s -> u.isofs_sb.s_log_zone_size); goto out; } s->s_magic = ISOFS_SUPER_MAGIC; /* The CDROM is read-only, has no nodes (devices) on it, and since all of the files appear to be owned by root, we really do not want to allow suid. (suid or devices will not show up unless we have Rock Ridge extensions) */ s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */; brelse(bh); /* RDE: data zone now byte offset! */ s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) + isonum_711 (rootp->ext_attr_length)) << s -> u.isofs_sb.s_log_zone_size); printk(KERN_DEBUG "Max size:%ld Log zone size:%ld\n", s->u.isofs_sb.s_max_size, 1UL << s->u.isofs_sb.s_log_zone_size); printk(KERN_DEBUG "First datazone:%ld Root inode number %ld\n", s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size, s->u.isofs_sb.s_firstdatazone); if(high_sierra) printk(KERN_DEBUG "Disc in High Sierra format.\n"); unlock_super(s); /* set up enough so that it can read an inode */ /* * Force the blocksize to 512 for 512 byte sectors. The file * read primitives really get it wrong in a bad way if we don't * do this. */ if( orig_zonesize < opt.blocksize ) { opt.blocksize = orig_zonesize; blocksize_bits = 0; { int i = opt.blocksize; while (i != 1){ blocksize_bits++; i >>=1; } } set_blocksize(dev, opt.blocksize); printk(KERN_DEBUG "Forcing new log zone size:%d\n", opt.blocksize); } s->u.isofs_sb.s_nls_iocharset = NULL; if (joliet_level == 0) { if (opt.iocharset) { kfree(opt.iocharset); opt.iocharset = NULL; } } else if (opt.utf8 == 0) { p = opt.iocharset ? opt.iocharset : "iso8859-1"; s->u.isofs_sb.s_nls_iocharset = load_nls(p); if (! s->u.isofs_sb.s_nls_iocharset) { /* Fail only if explicit charset specified */ if (opt.iocharset) { kfree(opt.iocharset); goto out; } else { s->u.isofs_sb.s_nls_iocharset = load_nls_default(); } } } s->s_dev = dev; s->s_op = &isofs_sops; s->u.isofs_sb.s_mapping = opt.map; s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 2 : 0); s->u.isofs_sb.s_name_check = opt.check; s->u.isofs_sb.s_conversion = opt.conversion; s->u.isofs_sb.s_cruft = opt.cruft; s->u.isofs_sb.s_unhide = opt.unhide; s->u.isofs_sb.s_uid = opt.uid; s->u.isofs_sb.s_gid = opt.gid; s->u.isofs_sb.s_utf8 = opt.utf8; /* * It would be incredibly stupid to allow people to mark every file on the disk * as suid, so we merely allow them to set the default permissions. */ s->u.isofs_sb.s_mode = opt.mode & 0777; s->s_blocksize = opt.blocksize; s->s_blocksize_bits = blocksize_bits; s->s_mounted = iget(s, s->u.isofs_sb.s_firstdatazone); /* * If this disk has both Rock Ridge and Joliet on it, then we * want to use Rock Ridge by default. This can be overridden * by using the norock mount option. There is still one other * possibility that is not taken into account: a Rock Ridge * CD with Unicode names. Until someone sees such a beast, it * will not be supported. */ if (joliet_level && opt.rock == 'y' && s->u.isofs_sb.s_rock != 1) { iput(s->s_mounted); pri = (struct iso_primary_descriptor *) sec; rootp = (struct iso_directory_record *) pri->root_directory_record; s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) + isonum_711 (rootp->ext_attr_length)) << s -> u.isofs_sb.s_log_zone_size); s->s_mounted = iget(s, s->u.isofs_sb.s_firstdatazone); s->u.isofs_sb.s_rock = 0; } unlock_super(s); if (!(s->s_mounted)) { s->s_dev = 0; printk("get root inode failed\n"); if (s->u.isofs_sb.s_nls_iocharset) unload_nls(s->u.isofs_sb.s_nls_iocharset); if (opt.iocharset) kfree(opt.iocharset); MOD_DEC_USE_COUNT; return NULL; } if(!check_disk_change(s->s_dev)) { return s; } if (s->u.isofs_sb.s_nls_iocharset) unload_nls(s->u.isofs_sb.s_nls_iocharset); if (opt.iocharset) kfree(opt.iocharset); out: /* Kick out for various error conditions */ brelse(bh); s->s_dev = 0; unlock_super(s); MOD_DEC_USE_COUNT; return NULL;}void isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz){ struct statfs tmp; tmp.f_type = ISOFS_SUPER_MAGIC; tmp.f_bsize = sb->s_blocksize; tmp.f_blocks = (sb->u.isofs_sb.s_nzones << (sb->u.isofs_sb.s_log_zone_size - sb->s_blocksize_bits)); tmp.f_bfree = 0; tmp.f_bavail = 0; tmp.f_files = sb->u.isofs_sb.s_ninodes; tmp.f_ffree = 0; tmp.f_namelen = NAME_MAX; memcpy_tofs(buf, &tmp, bufsiz);}int isofs_bmap(struct inode * inode,int block){ off_t b_off, offset, size; struct inode *ino; unsigned int firstext; unsigned long nextino; int i; if (block<0) { printk("_isofs_bmap: block<0"); return 0; } b_off = block << ISOFS_BUFFER_BITS(inode); /* * If we are beyond the end of this file, don't give out any * blocks. */ if( b_off > inode->i_size ) { off_t max_legal_read_offset; /* * If we are *way* beyond the end of the file, print a message. * Access beyond the end of the file up to the next page boundary * is normal because of the way the page cache works. * In this case, we just return 0 so that we can properly fill * the page with useless information without generating any * I/O errors. */ max_legal_read_offset = (inode->i_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); if( b_off >= max_legal_read_offset ) { printk("_isofs_bmap: block>= EOF(%d, %ld)", block, inode->i_size); } return 0; } offset = 0; firstext = inode->u.isofs_i.i_first_extent; size = inode->u.isofs_i.i_section_size; nextino = inode->u.isofs_i.i_next_section_ino;#ifdef DEBUG printk("first inode: inode=%lu nextino=%lu firstext=%u size=%lu\n", inode->i_ino, nextino, firstext, size);#endif i = 0; if (nextino) { while(b_off >= offset + size) { offset += size; if(nextino == 0) return 0; ino = iget(inode->i_sb, nextino); if(!ino) return 0; firstext = ino->u.isofs_i.i_first_extent; size = ino->u.isofs_i.i_section_size;#ifdef DEBUG printk("read inode: inode=%lu ino=%lu nextino=%lu firstext=%u size=%lu\n", inode->i_ino, nextino, ino->u.isofs_i.i_next_section_ino, firstext, size);#endif nextino = ino->u.isofs_i.i_next_section_ino; iput(ino); if(++i > 100) { printk("isofs_bmap: More than 100 file sections ?!?, aborting...\n"); printk("isofs_bmap: ino=%lu block=%d firstext=%u size=%u nextino=%lu\n", inode->i_ino, block, firstext, (unsigned)size, nextino); return 0; } } }#ifdef DEBUG printk("isofs_bmap: mapped inode:block %lu:%d to block %lu\n", inode->i_ino, block, (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode));#endif return (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode);}static void test_and_set_uid(uid_t *p, uid_t value){ if(value) { *p = value;#if 0 printk("Resetting to %d\n", value);#endif }}static int isofs_read_level3_size(struct inode * inode){ unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); struct buffer_head * bh = NULL; struct iso_directory_record * raw_inode = NULL; /* quiet gcc */ unsigned char *pnt = NULL; void *cpnt = NULL; int block = 0; /* Quiet GCC */ unsigned long ino; int i; inode->i_size = 0; inode->u.isofs_i.i_next_section_ino = 0; ino = inode->i_ino; i = 0; do { if(i > 100) { printk("isofs_read_level3_size: More than 100 file sections ?!?, aborting...\n" "isofs_read_level3_size: inode=%lu ino=%lu\n", inode->i_ino, ino); return 0; } if(bh == NULL || block != ino >> ISOFS_BUFFER_BITS(inode)) { if(bh) brelse(bh); block = ino >> ISOFS_BUFFER_BITS(inode); if (!(bh=bread(inode->i_dev,block, bufsize))) { printk("unable to read i-node block"); return 1; } } pnt = ((unsigned char *) bh->b_data + (ino & (bufsize - 1))); if ((ino & (bufsize - 1)) + *pnt > bufsize){ int frag1, offset; offset = (ino & (bufsize - 1)); frag1 = bufsize - offset; cpnt = kmalloc(*pnt,GFP_KERNEL); if (cpnt == NULL) { printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino); brelse(bh); return 1; } memcpy(cpnt, bh->b_data + offset, frag1); brelse(bh); if (!(bh = bread(inode->i_dev,++block, bufsize))) { kfree(cpnt); printk("unable to read i-node block"); return 1; } offset += *pnt - bufsize; memcpy((char *)cpnt+frag1, bh->b_data, offset); pnt = ((unsigned char *) cpnt); } if(*pnt == 0) { ino = (ino & ~(ISOFS_BLOCK_SIZE - 1)) + ISOFS_BLOCK_SIZE; continue; } raw_inode = ((struct iso_directory_record *) pnt); inode->i_size += isonum_733 (raw_inode->size); if(i == 1) inode->u.isofs_i.i_next_section_ino = ino; ino += *pnt; if (cpnt) { kfree (cpnt); cpnt = NULL; } i++; } while(raw_inode->flags[-inode->i_sb->u.isofs_sb.s_high_sierra] & 0x80); brelse(bh); return 0;}void isofs_read_inode(struct inode * inode){ unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); struct buffer_head * bh; struct iso_directory_record * raw_inode; unsigned char *pnt = NULL; void *cpnt = NULL; int high_sierra; int block; int volume_seq_no ; int i; block = inode->i_ino >> ISOFS_BUFFER_BITS(inode); if (!(bh=bread(inode->i_dev,block, bufsize))) { printk("unable to read i-node block"); goto fail; } pnt = ((unsigned char *) bh->b_data + (inode->i_ino & (bufsize - 1))); raw_inode = ((struct iso_directory_record *) pnt); high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra; if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){ int frag1, offset; offset = (inode->i_ino & (bufsize - 1)); frag1 = bufsize - offset; cpnt = kmalloc(*pnt,GFP_KERNEL); if (cpnt == NULL) { printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino); brelse(bh); goto fail; } memcpy(cpnt, bh->b_data + offset, frag1); brelse(bh); if (!(bh = bread(inode->i_dev,++block, bufsize))) { kfree(cpnt); printk("unable to read i-node block");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -