udf: Drop VARCONV support
authorJan Kara <jack@suse.cz>
Wed, 18 Jan 2023 12:27:07 +0000 (13:27 +0100)
committerJan Kara <jack@suse.cz>
Thu, 26 Jan 2023 15:46:32 +0000 (16:46 +0100)
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>
fs/udf/balloc.c
fs/udf/directory.c
fs/udf/inode.c
fs/udf/misc.c
fs/udf/namei.c
fs/udf/super.c
fs/udf/truncate.c
fs/udf/udf_sb.h
fs/udf/udfdecl.h

index 8e597db4d971065d6adab256179d9017288002b9..cdf90928b7f21b163780c63d7e1cf0199050ab6b 100644 (file)
@@ -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;
 
index 31f1bf8ab8481825a41a448f7462294f80301bd7..2e13c4b5fb8109bdc2f03f6ff259f231c630feed 100644 (file)
@@ -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);
 }
 
 /*
index 96873fa2f68366a319355e9c2d8600ee8bdeb8da..bcb56674773a07c0f4c4975b41cdf7d50d813586 100644 (file)
@@ -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;
 }
index 1614d308d0f06039ee0a4b27e0e9e9f93c44e8da..3777468d06ce5852b39446331872e9d02c54d493 100644 (file)
 #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);
index 261ca813a1b8fe69df29827abb4d6938c8e77aa1..87257f49b5da192e7c14cd4c13a838eb9b87de14 100644 (file)
@@ -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);
index c756d903a862e0efcbe7b8f384e890b98d210b77..58a3148173acfbfb70f4b3414c454ff085a3c9f7 100644 (file)
@@ -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;
index 775edaba82eedcb93a75fac86c2b9c39831fab5d..871856c69df555ecb503046c36101530af215224 100644 (file)
@@ -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)
index 6bccff3c70f54fdee2e47742515c09e71d4118ec..9af6ff7f9747242092fcc299e9c3deb3a9e7800b 100644 (file)
@@ -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
index eaf9e6fd201e017e9c97e068058ad3887fdb8950..88667a80795dc87f62d2f645ffc8a79e52b41d48 100644 (file)
@@ -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,