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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
static int udf_remount_fs(struct super_block *sb, int *flags, char *options){	struct udf_options uopt;	uopt.flags = UDF_SB(sb)->s_flags;	uopt.uid   = UDF_SB(sb)->s_uid;	uopt.gid   = UDF_SB(sb)->s_gid;	uopt.umask = UDF_SB(sb)->s_umask;	if (!udf_parse_options(options, &uopt))		return -EINVAL;	UDF_SB(sb)->s_flags = uopt.flags;	UDF_SB(sb)->s_uid   = uopt.uid;	UDF_SB(sb)->s_gid   = uopt.gid;	UDF_SB(sb)->s_umask = uopt.umask;	if (UDF_SB_LVIDBH(sb)) {		int write_rev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);		if (write_rev > UDF_MAX_WRITE_VERSION)			*flags |= MS_RDONLY;	}	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))		return 0;	if (*flags & MS_RDONLY)		udf_close_lvid(sb);	else		udf_open_lvid(sb);	return 0;}/* * udf_set_blocksize * * PURPOSE *	Set the block size to be used in all transfers. * * DESCRIPTION *	To allow room for a DMA transfer, it is best to guess big when unsure. *	This routine picks 2048 bytes as the blocksize when guessing. This *	should be adequate until devices with larger block sizes become common. * *	Note that the Linux kernel can currently only deal with blocksizes of *	512, 1024, 2048, 4096, and 8192 bytes. * * PRE-CONDITIONS *	sb			Pointer to _locked_ superblock. * * POST-CONDITIONS *	sb->s_blocksize		Blocksize. *	sb->s_blocksize_bits	log2 of blocksize. *	<return>	0	Blocksize is valid. *	<return>	1	Blocksize is invalid. * * HISTORY *	July 1, 1997 - Andrew E. Mileski *	Written, tested, and released. */static int udf_set_blocksize(struct super_block *sb, int bsize){	if (!sb_min_blocksize(sb, bsize)) {		udf_debug("Bad block size (%d)\n", bsize);		printk(KERN_ERR "udf: bad block size (%d)\n", bsize);		return 0;	}	return sb->s_blocksize;}static int udf_vrs(struct super_block *sb, int silent){	struct volStructDesc *vsd = NULL;	int sector = 32768;	int sectorsize;	struct buffer_head *bh = NULL;	int iso9660 = 0;	int nsr02 = 0;	int nsr03 = 0;	/* Block size must be a multiple of 512 */	if (sb->s_blocksize & 511)		return 0;	if (sb->s_blocksize < sizeof(struct volStructDesc))		sectorsize = sizeof(struct volStructDesc);	else		sectorsize = sb->s_blocksize;	sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits);	udf_debug("Starting at sector %u (%ld byte sectors)\n",		  (sector >> sb->s_blocksize_bits), sb->s_blocksize);	/* Process the sequence (if applicable) */	for (; !nsr02 && !nsr03; sector += sectorsize) {		/* Read a block */		bh = udf_tread(sb, sector >> sb->s_blocksize_bits);		if (!bh)			break;		/* Look for ISO  descriptors */		vsd = (struct volStructDesc *)(bh->b_data +					       (sector & (sb->s_blocksize - 1)));		if (vsd->stdIdent[0] == 0) {			brelse(bh);			break;		} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {			iso9660 = sector;			switch (vsd->structType) {			case 0:				udf_debug("ISO9660 Boot Record found\n");				break;			case 1:				udf_debug				    ("ISO9660 Primary Volume Descriptor found\n");				break;			case 2:				udf_debug				    ("ISO9660 Supplementary Volume Descriptor found\n");				break;			case 3:				udf_debug				    ("ISO9660 Volume Partition Descriptor found\n");				break;			case 255:				udf_debug				    ("ISO9660 Volume Descriptor Set Terminator found\n");				break;			default:				udf_debug("ISO9660 VRS (%u) found\n",					  vsd->structType);				break;			}		} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) {		} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) {			brelse(bh);			break;		} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) {			nsr02 = sector;		} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) {			nsr03 = sector;		}		brelse(bh);	}	if (nsr03)		return nsr03;	else if (nsr02)		return nsr02;	else if (sector - (UDF_SB_SESSION(sb) << sb->s_blocksize_bits) == 32768)		return -1;	else		return 0;}/* * udf_find_anchor * * PURPOSE *	Find an anchor volume descriptor. * * PRE-CONDITIONS *	sb			Pointer to _locked_ superblock. *	lastblock		Last block on media. * * POST-CONDITIONS *	<return>		1 if not found, 0 if ok * * HISTORY *	July 1, 1997 - Andrew E. Mileski *	Written, tested, and released. */static void udf_find_anchor(struct super_block *sb){	int lastblock = UDF_SB_LASTBLOCK(sb);	struct buffer_head *bh = NULL;	uint16_t ident;	uint32_t location;	int i;	if (lastblock) {		int varlastblock = udf_variable_to_fixed(lastblock);		int last[] =  { lastblock, lastblock - 2,				lastblock - 150, lastblock - 152,				varlastblock, varlastblock - 2,				varlastblock - 150, varlastblock - 152 };		lastblock = 0;		/* Search for an anchor volume descriptor pointer */		/*  according to spec, anchor is in either:		 *     block 256		 *     lastblock-256		 *     lastblock		 *  however, if the disc isn't closed, it could be 512 */		for (i = 0; !lastblock && i < ARRAY_SIZE(last); i++) {			if (last[i] < 0 || !(bh = sb_bread(sb, last[i]))) {				ident = location = 0;			} else {				ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);				location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);				brelse(bh);			}			if (ident == TAG_IDENT_AVDP) {				if (location == last[i] - UDF_SB_SESSION(sb)) {					lastblock = UDF_SB_ANCHOR(sb)[0] = last[i] - UDF_SB_SESSION(sb);					UDF_SB_ANCHOR(sb)[1] = last[i] - 256 - UDF_SB_SESSION(sb);				} else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb)) {					UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);					lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb);					UDF_SB_ANCHOR(sb)[1] = lastblock - 256 - UDF_SB_SESSION(sb);				} else {					udf_debug("Anchor found at block %d, location mismatch %d.\n",						  last[i], location);				}			} else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE) {				lastblock = last[i];				UDF_SB_ANCHOR(sb)[3] = 512;			} else {				if (last[i] < 256 || !(bh = sb_bread(sb, last[i] - 256))) {					ident = location = 0;				} else {					ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);					location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);					brelse(bh);				}				if (ident == TAG_IDENT_AVDP &&				    location == last[i] - 256 - UDF_SB_SESSION(sb)) {					lastblock = last[i];					UDF_SB_ANCHOR(sb)[1] = last[i] - 256;				} else {					if (last[i] < 312 + UDF_SB_SESSION(sb) ||					    !(bh = sb_bread(sb, last[i] - 312 - UDF_SB_SESSION(sb)))) {						ident = location = 0;					} else {						ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);						location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);						brelse(bh);					}					if (ident == TAG_IDENT_AVDP &&					    location == udf_variable_to_fixed(last[i]) - 256) {						UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);						lastblock = udf_variable_to_fixed(last[i]);						UDF_SB_ANCHOR(sb)[1] = lastblock - 256;					}				}			}		}	}	if (!lastblock) {		/* We havn't found the lastblock. check 312 */		if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb)))) {			ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);			location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);			brelse(bh);			if (ident == TAG_IDENT_AVDP && location == 256)				UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);		}	}	for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {		if (UDF_SB_ANCHOR(sb)[i]) {			if (!(bh = udf_read_tagged(sb, UDF_SB_ANCHOR(sb)[i],						   UDF_SB_ANCHOR(sb)[i], &ident))) {				UDF_SB_ANCHOR(sb)[i] = 0;			} else {				brelse(bh);				if ((ident != TAG_IDENT_AVDP) &&				    (i || (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE))) {					UDF_SB_ANCHOR(sb)[i] = 0;				}			}		}	}	UDF_SB_LASTBLOCK(sb) = lastblock;}static int udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr *root){	struct buffer_head *bh = NULL;	long lastblock;	uint16_t ident;	if (fileset->logicalBlockNum != 0xFFFFFFFF ||	    fileset->partitionReferenceNum != 0xFFFF) {		bh = udf_read_ptagged(sb, *fileset, 0, &ident);		if (!bh) {			return 1;		} else if (ident != TAG_IDENT_FSD) {			brelse(bh);			return 1;		}	}	if (!bh) { /* Search backwards through the partitions */		kernel_lb_addr newfileset;/* --> cvg: FIXME - is it reasonable? */		return 1;		for (newfileset.partitionReferenceNum = UDF_SB_NUMPARTS(sb) - 1;		     (newfileset.partitionReferenceNum != 0xFFFF &&		      fileset->logicalBlockNum == 0xFFFFFFFF &&		      fileset->partitionReferenceNum == 0xFFFF);		     newfileset.partitionReferenceNum--) {			lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum);			newfileset.logicalBlockNum = 0;			do {				bh = udf_read_ptagged(sb, newfileset, 0, &ident);				if (!bh) {					newfileset.logicalBlockNum++;					continue;				}				switch (ident) {				case TAG_IDENT_SBD:				{					struct spaceBitmapDesc *sp;					sp = (struct spaceBitmapDesc *)bh->b_data;					newfileset.logicalBlockNum += 1 +						((le32_to_cpu(sp->numOfBytes) +						  sizeof(struct spaceBitmapDesc) - 1)						 >> sb->s_blocksize_bits);					brelse(bh);					break;				}				case TAG_IDENT_FSD:					*fileset = newfileset;					break;				default:					newfileset.logicalBlockNum++;					brelse(bh);					bh = NULL;					break;				}			} while (newfileset.logicalBlockNum < lastblock &&				 fileset->logicalBlockNum == 0xFFFFFFFF &&				 fileset->partitionReferenceNum == 0xFFFF);		}	}	if ((fileset->logicalBlockNum != 0xFFFFFFFF ||	     fileset->partitionReferenceNum != 0xFFFF) && bh) {		udf_debug("Fileset at block=%d, partition=%d\n",			  fileset->logicalBlockNum,			  fileset->partitionReferenceNum);		UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;		udf_load_fileset(sb, bh, root);		brelse(bh);		return 0;	}	return 1;}static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh){	struct primaryVolDesc *pvoldesc;	time_t recording;	long recording_usec;	struct ustr instr;	struct ustr outstr;	pvoldesc = (struct primaryVolDesc *)bh->b_data;	if (udf_stamp_to_time(&recording, &recording_usec,			      lets_to_cpu(pvoldesc->recordingDateAndTime))) {		kernel_timestamp ts;		ts = lets_to_cpu(pvoldesc->recordingDateAndTime);		udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",			  recording, recording_usec,			  ts.year, ts.month, ts.day, ts.hour,			  ts.minute, ts.typeAndTimezone);		UDF_SB_RECORDTIME(sb).tv_sec = recording;		UDF_SB_RECORDTIME(sb).tv_nsec = recording_usec * 1000;	}	if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) {		if (udf_CS0toUTF8(&outstr, &instr)) {			strncpy(UDF_SB_VOLIDENT(sb), outstr.u_name,				outstr.u_len > 31 ? 31 : outstr.u_len);			udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb));		}	}	if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) {		if (udf_CS0toUTF8(&outstr, &instr))			udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);	}}static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,			     kernel_lb_addr *root){	struct fileSetDesc *fset;	fset = (struct fileSetDesc *)bh->b_data;	*root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);	UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum);	udf_debug("Rootdir at block=%d, partition=%d\n",		  root->logicalBlockNum, root->partitionReferenceNum);}static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh){	struct partitionDesc *p;	int i;	p = (struct partitionDesc *)bh->b_data;	for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {		udf_debug("Searching map: (%d == %d)\n",			  UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber));		if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber)) {			UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */			UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation);			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY)				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY;			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE)				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_WRITE_ONCE;			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_REWRITABLE)				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_REWRITABLE;			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_OVERWRITABLE)				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_OVERWRITABLE;			if (!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) ||			    !strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) {				struct partitionHeaderDesc *phd;				phd = (struct partitionHeaderDesc *)(p->partitionContentsUse);				if (phd->unallocSpaceTable.extLength) {					kernel_lb_addr loc = {						.logicalBlockNum = le32_to_cpu(phd->unallocSpaceTable.extPosition),						.partitionReferenceNum = i,					};					UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =						udf_iget(sb, loc);					if (!UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table) {						udf_debug("cannot load unallocSpaceTable (part %d)\n", i);						return 1;					}

⌨️ 快捷键说明

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