mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
udf: Drop VARCONV support
UDF was supporting a strange mode where the media was containing 7 blocks of unknown data for every 32 blocks of the filesystem. I have yet to see the media that would need such conversion (maybe it comes from packet writing times) and the conversions have been inconsistent in the code. In particular any write will write to a wrong block and corrupt the media. This is an indication and no user actually needs this so let's just drop the support instead of trying to fix it. Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
bd904f3c74
commit
101ee137d3
@ -42,7 +42,7 @@ static int read_block_bitmap(struct super_block *sb,
|
||||
loc.logicalBlockNum = bitmap->s_extPosition;
|
||||
loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
|
||||
|
||||
bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block));
|
||||
bh = sb_bread(sb, udf_get_lb_pblock(sb, &loc, block));
|
||||
if (!bh)
|
||||
retval = -EIO;
|
||||
|
||||
|
@ -141,7 +141,7 @@ static void udf_readahead_dir(struct udf_fileident_iter *iter)
|
||||
for (i = 0; i < ralen; i++) {
|
||||
blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc,
|
||||
iter->loffset + i);
|
||||
tmp = udf_tgetblk(iter->dir->i_sb, blk);
|
||||
tmp = sb_getblk(iter->dir->i_sb, blk);
|
||||
if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
|
||||
bha[num++] = tmp;
|
||||
else
|
||||
@ -160,7 +160,7 @@ static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter)
|
||||
|
||||
udf_readahead_dir(iter);
|
||||
blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, iter->loffset);
|
||||
return udf_tread(iter->dir->i_sb, blk);
|
||||
return sb_bread(iter->dir->i_sb, blk);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1592,7 +1592,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
|
||||
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
|
||||
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||
|
||||
bh = udf_tgetblk(inode->i_sb,
|
||||
bh = sb_getblk(inode->i_sb,
|
||||
udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0));
|
||||
if (!bh) {
|
||||
udf_debug("getblk failure\n");
|
||||
@ -1852,7 +1852,7 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
|
||||
neloc.logicalBlockNum = block;
|
||||
neloc.partitionReferenceNum = epos->block.partitionReferenceNum;
|
||||
|
||||
bh = udf_tgetblk(sb, udf_get_lb_pblock(sb, &neloc, 0));
|
||||
bh = sb_getblk(sb, udf_get_lb_pblock(sb, &neloc, 0));
|
||||
if (!bh)
|
||||
return -EIO;
|
||||
lock_buffer(bh);
|
||||
@ -2069,7 +2069,7 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
|
||||
epos->offset = sizeof(struct allocExtDesc);
|
||||
brelse(epos->bh);
|
||||
block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0);
|
||||
epos->bh = udf_tread(inode->i_sb, block);
|
||||
epos->bh = sb_bread(inode->i_sb, block);
|
||||
if (!epos->bh) {
|
||||
udf_debug("reading block %u failed!\n", block);
|
||||
return -1;
|
||||
@ -2290,8 +2290,5 @@ udf_pblk_t udf_block_map(struct inode *inode, sector_t block)
|
||||
up_read(&UDF_I(inode)->i_data_sem);
|
||||
brelse(epos.bh);
|
||||
|
||||
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
|
||||
return udf_fixed_to_variable(ret);
|
||||
else
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
@ -28,22 +28,6 @@
|
||||
#include "udf_i.h"
|
||||
#include "udf_sb.h"
|
||||
|
||||
struct buffer_head *udf_tgetblk(struct super_block *sb, udf_pblk_t block)
|
||||
{
|
||||
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
|
||||
return sb_getblk(sb, udf_fixed_to_variable(block));
|
||||
else
|
||||
return sb_getblk(sb, block);
|
||||
}
|
||||
|
||||
struct buffer_head *udf_tread(struct super_block *sb, udf_pblk_t block)
|
||||
{
|
||||
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
|
||||
return sb_bread(sb, udf_fixed_to_variable(block));
|
||||
else
|
||||
return sb_bread(sb, block);
|
||||
}
|
||||
|
||||
struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
|
||||
uint32_t type, uint8_t loc)
|
||||
{
|
||||
@ -216,7 +200,7 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
|
||||
if (block == 0xFFFFFFFF)
|
||||
return NULL;
|
||||
|
||||
bh = udf_tread(sb, block);
|
||||
bh = sb_bread(sb, block);
|
||||
if (!bh) {
|
||||
udf_err(sb, "read failed, block=%u, location=%u\n",
|
||||
block, location);
|
||||
|
@ -171,7 +171,7 @@ static struct buffer_head *udf_expand_dir_adinicb(struct inode *inode,
|
||||
0);
|
||||
if (!newblock)
|
||||
return NULL;
|
||||
dbh = udf_tgetblk(inode->i_sb, newblock);
|
||||
dbh = sb_getblk(inode->i_sb, newblock);
|
||||
if (!dbh)
|
||||
return NULL;
|
||||
lock_buffer(dbh);
|
||||
@ -623,7 +623,7 @@ static int udf_symlink(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
block = udf_get_pblock(sb, block,
|
||||
iinfo->i_location.partitionReferenceNum,
|
||||
0);
|
||||
epos.bh = udf_tgetblk(sb, block);
|
||||
epos.bh = sb_getblk(sb, block);
|
||||
if (unlikely(!epos.bh)) {
|
||||
err = -ENOMEM;
|
||||
udf_free_blocks(sb, inode, &eloc, 0, 1);
|
||||
|
@ -734,7 +734,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;
|
||||
|
||||
@ -1839,10 +1839,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;
|
||||
@ -1924,46 +1920,6 @@ static int udf_scan_anchors(struct super_block *sb, udf_pblk_t *lastblock,
|
||||
return udf_check_anchor_block(sb, sbi->s_session + 512, fileset);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
@ -2004,7 +1960,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");
|
||||
@ -2455,7 +2411,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;
|
||||
|
@ -240,7 +240,7 @@ int udf_truncate_extents(struct inode *inode)
|
||||
brelse(epos.bh);
|
||||
epos.offset = sizeof(struct allocExtDesc);
|
||||
epos.block = eloc;
|
||||
epos.bh = udf_tread(sb,
|
||||
epos.bh = sb_bread(sb,
|
||||
udf_get_lb_pblock(sb, &eloc, 0));
|
||||
/* Error reading indirect block? */
|
||||
if (!epos.bh)
|
||||
|
@ -23,7 +23,6 @@
|
||||
#define UDF_FLAG_STRICT 5
|
||||
#define UDF_FLAG_UNDELETE 6
|
||||
#define UDF_FLAG_UNHIDE 7
|
||||
#define UDF_FLAG_VARCONV 8
|
||||
#define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */
|
||||
#define UDF_FLAG_GID_FORGET 12
|
||||
#define UDF_FLAG_UID_SET 13
|
||||
|
@ -34,9 +34,6 @@ extern __printf(3, 4) void _udf_warn(struct super_block *sb,
|
||||
#define udf_debug(fmt, ...) \
|
||||
pr_debug("%s:%d:%s: " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
|
||||
#define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) )
|
||||
|
||||
#define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF
|
||||
#define UDF_EXTENT_FLAG_MASK 0xC0000000
|
||||
|
||||
@ -179,9 +176,6 @@ extern int8_t udf_current_aext(struct inode *, struct extent_position *,
|
||||
extern void udf_update_extra_perms(struct inode *inode, umode_t mode);
|
||||
|
||||
/* misc.c */
|
||||
extern struct buffer_head *udf_tgetblk(struct super_block *sb,
|
||||
udf_pblk_t block);
|
||||
extern struct buffer_head *udf_tread(struct super_block *sb, udf_pblk_t block);
|
||||
extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t,
|
||||
uint32_t, uint8_t);
|
||||
extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t,
|
||||
|
Loading…
Reference in New Issue
Block a user