diff options
Diffstat (limited to 'fs/udf/super.c')
| -rw-r--r-- | fs/udf/super.c | 77 | 
1 files changed, 22 insertions, 55 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 06eda8177b5f..6304e3c5c3d9 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -86,6 +86,13 @@ enum {  #define UDF_MAX_LVID_NESTING 1000  enum { UDF_MAX_LINKS = 0xffff }; +/* + * We limit filesize to 4TB. This is arbitrary as the on-disk format supports + * more but because the file space is described by a linked list of extents, + * each of which can have at most 1GB, the creation and handling of extents + * gets unusably slow beyond certain point... + */ +#define UDF_MAX_FILESIZE (1ULL << 42)  /* These are the "meat" - everything else is stuffing */  static int udf_fill_super(struct super_block *, void *, int); @@ -147,6 +154,7 @@ static struct inode *udf_alloc_inode(struct super_block *sb)  	ei->i_next_alloc_goal = 0;  	ei->i_strat4096 = 0;  	ei->i_streamdir = 0; +	ei->i_hidden = 0;  	init_rwsem(&ei->i_data_sem);  	ei->cached_extent.lstart = -1;  	spin_lock_init(&ei->i_extent_cache_lock); @@ -733,7 +741,7 @@ static int udf_check_vsd(struct super_block *sb)  	 * added */  	for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) {  		/* Read a block */ -		bh = udf_tread(sb, sector >> sb->s_blocksize_bits); +		bh = sb_bread(sb, sector >> sb->s_blocksize_bits);  		if (!bh)  			break; @@ -1175,7 +1183,6 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)  	struct udf_part_map *map = &sbi->s_partmaps[p_index];  	struct buffer_head *bh = NULL;  	struct udf_inode_info *vati; -	uint32_t pos;  	struct virtualAllocationTable20 *vat20;  	sector_t blocks = sb_bdev_nr_blocks(sb); @@ -1197,10 +1204,14 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)  	} else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {  		vati = UDF_I(sbi->s_vat_inode);  		if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { -			pos = udf_block_map(sbi->s_vat_inode, 0); -			bh = sb_bread(sb, pos); -			if (!bh) -				return -EIO; +			int err = 0; + +			bh = udf_bread(sbi->s_vat_inode, 0, 0, &err); +			if (!bh) { +				if (!err) +					err = -EFSCORRUPTED; +				return err; +			}  			vat20 = (struct virtualAllocationTable20 *)bh->b_data;  		} else {  			vat20 = (struct virtualAllocationTable20 *) @@ -1838,10 +1849,6 @@ static int udf_check_anchor_block(struct super_block *sb, sector_t block,  	uint16_t ident;  	int ret; -	if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && -	    udf_fixed_to_variable(block) >= sb_bdev_nr_blocks(sb)) -		return -EAGAIN; -  	bh = udf_read_tagged(sb, block, block, &ident);  	if (!bh)  		return -EAGAIN; @@ -1860,10 +1867,10 @@ static int udf_check_anchor_block(struct super_block *sb, sector_t block,   * Returns < 0 on error, 0 on success. -EAGAIN is special - try next set   * of anchors.   */ -static int udf_scan_anchors(struct super_block *sb, sector_t *lastblock, +static int udf_scan_anchors(struct super_block *sb, udf_pblk_t *lastblock,  			    struct kernel_lb_addr *fileset)  { -	sector_t last[6]; +	udf_pblk_t last[6];  	int i;  	struct udf_sb_info *sbi = UDF_SB(sb);  	int last_count = 0; @@ -1924,46 +1931,6 @@ static int udf_scan_anchors(struct super_block *sb, sector_t *lastblock,  }  /* - * Find an anchor volume descriptor and load Volume Descriptor Sequence from - * area specified by it. The function expects sbi->s_lastblock to be the last - * block on the media. - * - * Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor - * was not found. - */ -static int udf_find_anchor(struct super_block *sb, -			   struct kernel_lb_addr *fileset) -{ -	struct udf_sb_info *sbi = UDF_SB(sb); -	sector_t lastblock = sbi->s_last_block; -	int ret; - -	ret = udf_scan_anchors(sb, &lastblock, fileset); -	if (ret != -EAGAIN) -		goto out; - -	/* No anchor found? Try VARCONV conversion of block numbers */ -	UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); -	lastblock = udf_variable_to_fixed(sbi->s_last_block); -	/* Firstly, we try to not convert number of the last block */ -	ret = udf_scan_anchors(sb, &lastblock, fileset); -	if (ret != -EAGAIN) -		goto out; - -	lastblock = sbi->s_last_block; -	/* Secondly, we try with converted number of the last block */ -	ret = udf_scan_anchors(sb, &lastblock, fileset); -	if (ret < 0) { -		/* VARCONV didn't help. Clear it. */ -		UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); -	} -out: -	if (ret == 0) -		sbi->s_last_block = lastblock; -	return ret; -} - -/*   * Check Volume Structure Descriptor, find Anchor block and load Volume   * Descriptor Sequence.   * @@ -2003,7 +1970,7 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,  	/* Look for anchor block and load Volume Descriptor Sequence */  	sbi->s_anchor = uopt->anchor; -	ret = udf_find_anchor(sb, fileset); +	ret = udf_scan_anchors(sb, &sbi->s_last_block, fileset);  	if (ret < 0) {  		if (!silent && ret == -EAGAIN)  			udf_warn(sb, "No anchor found\n"); @@ -2297,7 +2264,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)  		ret = -ENOMEM;  		goto error_out;  	} -	sb->s_maxbytes = MAX_LFS_FILESIZE; +	sb->s_maxbytes = UDF_MAX_FILESIZE;  	sb->s_max_links = UDF_MAX_LINKS;  	return 0; @@ -2454,7 +2421,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,  		if (bytes) {  			brelse(bh);  			newblock = udf_get_lb_pblock(sb, &loc, ++block); -			bh = udf_tread(sb, newblock); +			bh = sb_bread(sb, newblock);  			if (!bh) {  				udf_debug("read failed\n");  				goto out;  |