⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rock.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			 * either case.			 */			/* Rock ridge never appears on a High Sierra disk */			cnt = 0;			if (rr->u.TF.flags & TF_CREATE) {				inode->i_ctime.tv_sec =				    iso_date(rr->u.TF.times[cnt++].time,					     0);				inode->i_ctime.tv_nsec = 0;			}			if (rr->u.TF.flags & TF_MODIFY) {				inode->i_mtime.tv_sec =				    iso_date(rr->u.TF.times[cnt++].time,					     0);				inode->i_mtime.tv_nsec = 0;			}			if (rr->u.TF.flags & TF_ACCESS) {				inode->i_atime.tv_sec =				    iso_date(rr->u.TF.times[cnt++].time,					     0);				inode->i_atime.tv_nsec = 0;			}			if (rr->u.TF.flags & TF_ATTRIBUTES) {				inode->i_ctime.tv_sec =				    iso_date(rr->u.TF.times[cnt++].time,					     0);				inode->i_ctime.tv_nsec = 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'):			ISOFS_I(inode)->i_first_extent =			    isonum_733(rr->u.CL.location);			reloc =			    isofs_iget(inode->i_sb,				       ISOFS_I(inode)->i_first_extent,				       0);			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'): {			int algo;			if (ISOFS_SB(inode->i_sb)->s_nocompress)				break;			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					 */					ISOFS_I(inode)->i_file_format =						isofs_file_compressed;					/*					 * Parameters to compression					 * algorithm (header size,					 * block size)					 */					ISOFS_I(inode)->i_format_parm[0] =						isonum_711(&rr->u.ZF.parms[0]);					ISOFS_I(inode)->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;		}	}	ret = rock_continue(&rs);	if (ret == 0)		goto repeat;	if (ret == 1)		ret = 0;out:	kfree(rs.buffer);	return ret;eio:	ret = -EIO;	goto out;}static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit){	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:			if (slp->len > plimit - rpnt)				return NULL;			memcpy(rpnt, slp->text, slp->len);			rpnt += slp->len;			break;		case 2:			if (rpnt >= plimit)				return NULL;			*rpnt++ = '.';			break;		case 4:			if (2 > plimit - rpnt)				return NULL;			*rpnt++ = '.';			*rpnt++ = '.';			break;		case 8:			if (rpnt >= plimit)				return NULL;			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)) {				if (rpnt >= plimit)					return NULL;				*rpnt++ = '/';			}			break;		}		/*		 * If this component record isn't continued, then append a '/'.		 */		if (!rootflag && !(oldslp->flags & 1)) {			if (rpnt >= plimit)				return NULL;			*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 ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)	    && (ISOFS_SB(inode->i_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;	struct iso_inode_info *ei = ISOFS_I(inode);	char *link = kmap(page);	unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);	struct buffer_head *bh;	char *rpnt = link;	unsigned char *pnt;	struct iso_directory_record *raw_de;	unsigned long block, offset;	int sig;	struct rock_ridge *rr;	struct rock_state rs;	int ret;	if (!ISOFS_SB(inode->i_sb)->s_rock)		goto error;	init_rock_state(&rs, inode);	block = ei->i_iget5_block;	lock_kernel();	bh = sb_bread(inode->i_sb, block);	if (!bh)		goto out_noread;	offset = ei->i_iget5_offset;	pnt = (unsigned char *)bh->b_data + offset;	raw_de = (struct iso_directory_record *)pnt;	/*	 * If we go past the end of the buffer, there is some sort of error.	 */	if (offset + *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_de, inode, &rs);repeat:	while (rs.len > 2) { /* There may be one byte for padding somewhere */		rr = (struct rock_ridge *)rs.chr;		if (rr->len < 3)			goto out;	/* Something got screwed up here */		sig = isonum_721(rs.chr);		if (rock_check_overflow(&rs, sig))			goto out;		rs.chr += rr->len;		rs.len -= rr->len;		if (rs.len < 0)			goto out;	/* corrupted isofs */		switch (sig) {		case SIG('R', 'R'):			if ((rr->u.RR.flags[0] & RR_SL) == 0)				goto out;			break;		case SIG('S', 'P'):			if (check_sp(rr, inode))				goto out;			break;		case SIG('S', 'L'):			rpnt = get_symlink_chunk(rpnt, rr,						 link + (PAGE_SIZE - 1));			if (rpnt == NULL)				goto out;			break;		case SIG('C', 'E'):			/* This tells is if there is a continuation record */			rs.cont_extent = isonum_733(rr->u.CE.extent);			rs.cont_offset = isonum_733(rr->u.CE.offset);			rs.cont_size = isonum_733(rr->u.CE.size);		default:			break;		}	}	ret = rock_continue(&rs);	if (ret == 0)		goto repeat;	if (ret < 0)		goto fail;	if (rpnt == link)		goto fail;	brelse(bh);	*rpnt = '\0';	unlock_kernel();	SetPageUptodate(page);	kunmap(page);	unlock_page(page);	return 0;	/* error exit from macro */out:	kfree(rs.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();error:	SetPageError(page);	kunmap(page);	unlock_page(page);	return -EIO;}const struct address_space_operations isofs_symlink_aops = {	.readpage = rock_ridge_symlink_readpage};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -