📄 rock.c
字号:
*/ if((low & ~0xff) && high == 0) { inode->i_rdev = MKDEV(low >> 8, low & 0xff); } else { inode->i_rdev = MKDEV(high, low); } } break; case SIG('T','F'): /* Some RRIP writers incorrectly place ctime in the TF_CREATE field. Try to handle this correctly for either case. */ cnt = 0; /* Rock ridge never appears on a High Sierra disk */ if(rr->u.TF.flags & TF_CREATE) inode->i_ctime = iso_date(rr->u.TF.times[cnt++].time, 0); if(rr->u.TF.flags & TF_MODIFY) inode->i_mtime = iso_date(rr->u.TF.times[cnt++].time, 0); if(rr->u.TF.flags & TF_ACCESS) inode->i_atime = iso_date(rr->u.TF.times[cnt++].time, 0); if(rr->u.TF.flags & TF_ATTRIBUTES) inode->i_ctime = iso_date(rr->u.TF.times[cnt++].time, 0); break; case SIG('S','L'): {int slen; struct SL_component * slp; struct SL_component * oldslp; slen = rr->len - 5; slp = &rr->u.SL.link; inode->i_size = symlink_len; while (slen > 1){ rootflag = 0; switch(slp->flags &~1){ case 0: inode->i_size += slp->len; break; case 2: inode->i_size += 1; break; case 4: inode->i_size += 2; break; case 8: rootflag = 1; inode->i_size += 1; break; default: printk("Symlink component flag not implemented\n"); } slen -= slp->len + 2; oldslp = slp; slp = (struct SL_component *) (((char *) slp) + slp->len + 2); if(slen < 2) { if( ((rr->u.SL.flags & 1) != 0) && ((oldslp->flags & 1) == 0) ) inode->i_size += 1; break; } /* * If this component record isn't continued, then append a '/'. */ if (!rootflag && (oldslp->flags & 1) == 0) inode->i_size += 1; } } symlink_len = inode->i_size; break; case SIG('R','E'): printk(KERN_WARNING "Attempt to read inode for relocated directory\n"); goto out; case SIG('C','L'): inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location); reloc = iget(inode->i_sb, (inode->u.isofs_i.i_first_extent << inode -> i_sb -> u.isofs_sb.s_log_zone_size)); if (!reloc) goto out; inode->i_mode = reloc->i_mode; inode->i_nlink = reloc->i_nlink; inode->i_uid = reloc->i_uid; inode->i_gid = reloc->i_gid; inode->i_rdev = reloc->i_rdev; inode->i_size = reloc->i_size; inode->i_blocks = reloc->i_blocks; inode->i_atime = reloc->i_atime; inode->i_ctime = reloc->i_ctime; inode->i_mtime = reloc->i_mtime; iput(reloc); break;#ifdef CONFIG_ZISOFS case SIG('Z','F'): if ( !inode->i_sb->u.isofs_sb.s_nocompress ) { int algo; algo = isonum_721(rr->u.ZF.algorithm); if ( algo == SIG('p','z') ) { int block_shift = isonum_711(&rr->u.ZF.parms[1]); if ( block_shift < PAGE_CACHE_SHIFT || block_shift > 17 ) { printk(KERN_WARNING "isofs: Can't handle ZF block size of 2^%d\n", block_shift); } else { /* Note: we don't change i_blocks here */ inode->u.isofs_i.i_file_format = isofs_file_compressed; /* Parameters to compression algorithm (header size, block size) */ inode->u.isofs_i.i_format_parm[0] = isonum_711(&rr->u.ZF.parms[0]); inode->u.isofs_i.i_format_parm[1] = isonum_711(&rr->u.ZF.parms[1]); inode->i_size = isonum_733(rr->u.ZF.real_size); } } else { printk(KERN_WARNING "isofs: Unknown ZF compression algorithm: %c%c\n", rr->u.ZF.algorithm[0], rr->u.ZF.algorithm[1]); } } break;#endif default: break; } } } MAYBE_CONTINUE(repeat,inode); return 0; out: if(buffer) kfree(buffer); return 0;}static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr){ int slen; int rootflag; struct SL_component *oldslp; struct SL_component *slp; slen = rr->len - 5; slp = &rr->u.SL.link; while (slen > 1) { rootflag = 0; switch (slp->flags & ~1) { case 0: memcpy(rpnt, slp->text, slp->len); rpnt+=slp->len; break; case 4: *rpnt++='.'; /* fallthru */ case 2: *rpnt++='.'; break; case 8: rootflag = 1; *rpnt++='/'; break; default: printk("Symlink component flag not implemented (%d)\n", slp->flags); } slen -= slp->len + 2; oldslp = slp; slp = (struct SL_component *) ((char *) slp + slp->len + 2); if (slen < 2) { /* * If there is another SL record, and this component * record isn't continued, then add a slash. */ if ((!rootflag) && (rr->u.SL.flags & 1) && !(oldslp->flags & 1)) *rpnt++='/'; break; } /* * If this component record isn't continued, then append a '/'. */ if (!rootflag && !(oldslp->flags & 1)) *rpnt++='/'; } return rpnt;}int parse_rock_ridge_inode(struct iso_directory_record * de, struct inode * inode){ int result=parse_rock_ridge_inode_internal(de,inode,0); /* if rockridge flag was reset and we didn't look for attributes * behind eventual XA attributes, have a look there */ if ((inode->i_sb->u.isofs_sb.s_rock_offset==-1) &&(inode->i_sb->u.isofs_sb.s_rock==2)) { result=parse_rock_ridge_inode_internal(de,inode,14); }; return result;};/* readpage() for symlinks: reads symlink contents into the page and either makes it uptodate and returns 0 or returns error (-EIO) */static int rock_ridge_symlink_readpage(struct file *file, struct page *page){ struct inode *inode = page->mapping->host; char *link = kmap(page); unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); unsigned char bufbits = ISOFS_BUFFER_BITS(inode); struct buffer_head *bh; char *rpnt = link; unsigned char *pnt; struct iso_directory_record *raw_inode; CONTINUE_DECLS; int block; int sig; int len; unsigned char *chr; struct rock_ridge *rr; if (!inode->i_sb->u.isofs_sb.s_rock) panic ("Cannot have symlink with high sierra variant of iso filesystem\n"); block = inode->i_ino >> bufbits; lock_kernel(); bh = sb_bread(inode->i_sb, block); if (!bh) goto out_noread; pnt = (unsigned char *) bh->b_data + (inode->i_ino & (bufsize - 1)); raw_inode = (struct iso_directory_record *) pnt; /* * If we go past the end of the buffer, there is some sort of error. */ if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize) goto out_bad_span; /* Now test for possible Rock Ridge extensions which will override some of these numbers in the inode structure. */ SETUP_ROCK_RIDGE(raw_inode, chr, len); repeat: while (len > 1) { /* There may be one byte for padding somewhere */ rr = (struct rock_ridge *) chr; if (rr->len == 0) goto out; /* Something got screwed up here */ sig = isonum_721(chr); chr += rr->len; len -= rr->len; switch (sig) { case SIG('R', 'R'): if ((rr->u.RR.flags[0] & RR_SL) == 0) goto out; break; case SIG('S', 'P'): CHECK_SP(goto out); break; case SIG('S', 'L'): rpnt = get_symlink_chunk(rpnt, rr); break; case SIG('C', 'E'): /* This tells is if there is a continuation record */ CHECK_CE; default: break; } } MAYBE_CONTINUE(repeat, inode); if (rpnt == link) goto fail; brelse(bh); *rpnt = '\0'; unlock_kernel(); SetPageUptodate(page); kunmap(page); UnlockPage(page); return 0; /* error exit from macro */ out: if (buffer) kfree(buffer); goto fail; out_noread: printk("unable to read i-node block"); goto fail; out_bad_span: printk("symlink spans iso9660 blocks\n"); fail: brelse(bh); unlock_kernel(); SetPageError(page); kunmap(page); UnlockPage(page); return -EIO;}struct address_space_operations isofs_symlink_aops = { readpage: rock_ridge_symlink_readpage};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -