Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Jan Kara 101ee137 bd904f3c

+14 -84
+1 -1
fs/udf/balloc.c
··· 42 42 loc.logicalBlockNum = bitmap->s_extPosition; 43 43 loc.partitionReferenceNum = UDF_SB(sb)->s_partition; 44 44 45 - bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block)); 45 + bh = sb_bread(sb, udf_get_lb_pblock(sb, &loc, block)); 46 46 if (!bh) 47 47 retval = -EIO; 48 48
+2 -2
fs/udf/directory.c
··· 141 141 for (i = 0; i < ralen; i++) { 142 142 blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, 143 143 iter->loffset + i); 144 - tmp = udf_tgetblk(iter->dir->i_sb, blk); 144 + tmp = sb_getblk(iter->dir->i_sb, blk); 145 145 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) 146 146 bha[num++] = tmp; 147 147 else ··· 160 160 161 161 udf_readahead_dir(iter); 162 162 blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, iter->loffset); 163 - return udf_tread(iter->dir->i_sb, blk); 163 + return sb_bread(iter->dir->i_sb, blk); 164 164 } 165 165 166 166 /*
+4 -7
fs/udf/inode.c
··· 1592 1592 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; 1593 1593 struct udf_inode_info *iinfo = UDF_I(inode); 1594 1594 1595 - bh = udf_tgetblk(inode->i_sb, 1595 + bh = sb_getblk(inode->i_sb, 1596 1596 udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0)); 1597 1597 if (!bh) { 1598 1598 udf_debug("getblk failure\n"); ··· 1852 1852 neloc.logicalBlockNum = block; 1853 1853 neloc.partitionReferenceNum = epos->block.partitionReferenceNum; 1854 1854 1855 - bh = udf_tgetblk(sb, udf_get_lb_pblock(sb, &neloc, 0)); 1855 + bh = sb_getblk(sb, udf_get_lb_pblock(sb, &neloc, 0)); 1856 1856 if (!bh) 1857 1857 return -EIO; 1858 1858 lock_buffer(bh); ··· 2069 2069 epos->offset = sizeof(struct allocExtDesc); 2070 2070 brelse(epos->bh); 2071 2071 block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0); 2072 - epos->bh = udf_tread(inode->i_sb, block); 2072 + epos->bh = sb_bread(inode->i_sb, block); 2073 2073 if (!epos->bh) { 2074 2074 udf_debug("reading block %u failed!\n", block); 2075 2075 return -1; ··· 2290 2290 up_read(&UDF_I(inode)->i_data_sem); 2291 2291 brelse(epos.bh); 2292 2292 2293 - if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) 2294 - return udf_fixed_to_variable(ret); 2295 - else 2296 - return ret; 2293 + return ret; 2297 2294 }
+1 -17
fs/udf/misc.c
··· 28 28 #include "udf_i.h" 29 29 #include "udf_sb.h" 30 30 31 - struct buffer_head *udf_tgetblk(struct super_block *sb, udf_pblk_t block) 32 - { 33 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) 34 - return sb_getblk(sb, udf_fixed_to_variable(block)); 35 - else 36 - return sb_getblk(sb, block); 37 - } 38 - 39 - struct buffer_head *udf_tread(struct super_block *sb, udf_pblk_t block) 40 - { 41 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) 42 - return sb_bread(sb, udf_fixed_to_variable(block)); 43 - else 44 - return sb_bread(sb, block); 45 - } 46 - 47 31 struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, 48 32 uint32_t type, uint8_t loc) 49 33 { ··· 200 216 if (block == 0xFFFFFFFF) 201 217 return NULL; 202 218 203 - bh = udf_tread(sb, block); 219 + bh = sb_bread(sb, block); 204 220 if (!bh) { 205 221 udf_err(sb, "read failed, block=%u, location=%u\n", 206 222 block, location);
+2 -2
fs/udf/namei.c
··· 171 171 0); 172 172 if (!newblock) 173 173 return NULL; 174 - dbh = udf_tgetblk(inode->i_sb, newblock); 174 + dbh = sb_getblk(inode->i_sb, newblock); 175 175 if (!dbh) 176 176 return NULL; 177 177 lock_buffer(dbh); ··· 623 623 block = udf_get_pblock(sb, block, 624 624 iinfo->i_location.partitionReferenceNum, 625 625 0); 626 - epos.bh = udf_tgetblk(sb, block); 626 + epos.bh = sb_getblk(sb, block); 627 627 if (unlikely(!epos.bh)) { 628 628 err = -ENOMEM; 629 629 udf_free_blocks(sb, inode, &eloc, 0, 1);
+3 -47
fs/udf/super.c
··· 734 734 * added */ 735 735 for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) { 736 736 /* Read a block */ 737 - bh = udf_tread(sb, sector >> sb->s_blocksize_bits); 737 + bh = sb_bread(sb, sector >> sb->s_blocksize_bits); 738 738 if (!bh) 739 739 break; 740 740 ··· 1839 1839 uint16_t ident; 1840 1840 int ret; 1841 1841 1842 - if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && 1843 - udf_fixed_to_variable(block) >= sb_bdev_nr_blocks(sb)) 1844 - return -EAGAIN; 1845 - 1846 1842 bh = udf_read_tagged(sb, block, block, &ident); 1847 1843 if (!bh) 1848 1844 return -EAGAIN; ··· 1921 1925 } 1922 1926 1923 1927 /* 1924 - * Find an anchor volume descriptor and load Volume Descriptor Sequence from 1925 - * area specified by it. The function expects sbi->s_lastblock to be the last 1926 - * block on the media. 1927 - * 1928 - * Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor 1929 - * was not found. 1930 - */ 1931 - static int udf_find_anchor(struct super_block *sb, 1932 - struct kernel_lb_addr *fileset) 1933 - { 1934 - struct udf_sb_info *sbi = UDF_SB(sb); 1935 - sector_t lastblock = sbi->s_last_block; 1936 - int ret; 1937 - 1938 - ret = udf_scan_anchors(sb, &lastblock, fileset); 1939 - if (ret != -EAGAIN) 1940 - goto out; 1941 - 1942 - /* No anchor found? Try VARCONV conversion of block numbers */ 1943 - UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); 1944 - lastblock = udf_variable_to_fixed(sbi->s_last_block); 1945 - /* Firstly, we try to not convert number of the last block */ 1946 - ret = udf_scan_anchors(sb, &lastblock, fileset); 1947 - if (ret != -EAGAIN) 1948 - goto out; 1949 - 1950 - lastblock = sbi->s_last_block; 1951 - /* Secondly, we try with converted number of the last block */ 1952 - ret = udf_scan_anchors(sb, &lastblock, fileset); 1953 - if (ret < 0) { 1954 - /* VARCONV didn't help. Clear it. */ 1955 - UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); 1956 - } 1957 - out: 1958 - if (ret == 0) 1959 - sbi->s_last_block = lastblock; 1960 - return ret; 1961 - } 1962 - 1963 - /* 1964 1928 * Check Volume Structure Descriptor, find Anchor block and load Volume 1965 1929 * Descriptor Sequence. 1966 1930 * ··· 1960 2004 1961 2005 /* Look for anchor block and load Volume Descriptor Sequence */ 1962 2006 sbi->s_anchor = uopt->anchor; 1963 - ret = udf_find_anchor(sb, fileset); 2007 + ret = udf_scan_anchors(sb, &sbi->s_last_block, fileset); 1964 2008 if (ret < 0) { 1965 2009 if (!silent && ret == -EAGAIN) 1966 2010 udf_warn(sb, "No anchor found\n"); ··· 2411 2455 if (bytes) { 2412 2456 brelse(bh); 2413 2457 newblock = udf_get_lb_pblock(sb, &loc, ++block); 2414 - bh = udf_tread(sb, newblock); 2458 + bh = sb_bread(sb, newblock); 2415 2459 if (!bh) { 2416 2460 udf_debug("read failed\n"); 2417 2461 goto out;
+1 -1
fs/udf/truncate.c
··· 240 240 brelse(epos.bh); 241 241 epos.offset = sizeof(struct allocExtDesc); 242 242 epos.block = eloc; 243 - epos.bh = udf_tread(sb, 243 + epos.bh = sb_bread(sb, 244 244 udf_get_lb_pblock(sb, &eloc, 0)); 245 245 /* Error reading indirect block? */ 246 246 if (!epos.bh)
-1
fs/udf/udf_sb.h
··· 23 23 #define UDF_FLAG_STRICT 5 24 24 #define UDF_FLAG_UNDELETE 6 25 25 #define UDF_FLAG_UNHIDE 7 26 - #define UDF_FLAG_VARCONV 8 27 26 #define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */ 28 27 #define UDF_FLAG_GID_FORGET 12 29 28 #define UDF_FLAG_UID_SET 13
-6
fs/udf/udfdecl.h
··· 34 34 #define udf_debug(fmt, ...) \ 35 35 pr_debug("%s:%d:%s: " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__) 36 36 37 - #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) 38 - #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) 39 - 40 37 #define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF 41 38 #define UDF_EXTENT_FLAG_MASK 0xC0000000 42 39 ··· 176 179 extern void udf_update_extra_perms(struct inode *inode, umode_t mode); 177 180 178 181 /* misc.c */ 179 - extern struct buffer_head *udf_tgetblk(struct super_block *sb, 180 - udf_pblk_t block); 181 - extern struct buffer_head *udf_tread(struct super_block *sb, udf_pblk_t block); 182 182 extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, 183 183 uint32_t, uint8_t); 184 184 extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t,