On Thu 14-01-21 21:26:15, lianzhi chang wrote: > When the capacity of the disc is too large (assuming the 4.7G > specification), the disc (UDF file system) will be burned > multiple times in the windows (Multisession Usage). When the > remaining capacity of the CD is less than 300M (estimated > value, for reference only), open the CD in the Linux system, > the content of the CD is displayed as blank (the kernel will > say "No VRS found"). Windows can display the contents of the > CD normally. > Through analysis, in the "fs/udf/super.c": udf_check_vsd > function, the actual value of VSD_MAX_SECTOR_OFFSET may > be much larger than 0x800000. According to the current code > logic, it is found that the type of sbi->s_session is "__s32", > when the remaining capacity of the disc is less than 300M > (take a set of test values: sector=3154903040, > sbi->s_session=1540464, sb->s_blocksize_bits=11 ), the > calculation result of "sbi->s_session << sb->s_blocksize_bits" > will overflow. Therefore, it is necessary to convert the > type of s_session to "loff_t" (when udf_check_vsd starts, > assign a value to _sector, which is also converted in this > way), so that the result will not overflow, and then the > content of the disc can be displayed normally. > > Signed-off-by: lianzhi chang <changlian...@uniontech.com>
There was no need to resend the patch (I've fixed up the problem locally - it was easy enough) but thanks anyway :). Honza > --- > fs/udf/super.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/fs/udf/super.c b/fs/udf/super.c > index 5bef3a68395d..f2ff98f393fb 100644 > --- a/fs/udf/super.c > +++ b/fs/udf/super.c > @@ -705,6 +705,7 @@ static int udf_check_vsd(struct super_block *sb) > struct buffer_head *bh = NULL; > int nsr = 0; > struct udf_sb_info *sbi; > + loff_t sector_offset; > > sbi = UDF_SB(sb); > if (sb->s_blocksize < sizeof(struct volStructDesc)) > @@ -712,7 +713,8 @@ static int udf_check_vsd(struct super_block *sb) > else > sectorsize = sb->s_blocksize; > > - sector += (((loff_t)sbi->s_session) << sb->s_blocksize_bits); > + sector_offset = (loff_t)sbi->s_session << sb->s_blocksize_bits; > + sector += sector_offset; > > udf_debug("Starting at sector %u (%lu byte sectors)\n", > (unsigned int)(sector >> sb->s_blocksize_bits), > @@ -757,8 +759,7 @@ static int udf_check_vsd(struct super_block *sb) > > if (nsr > 0) > return 1; > - else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == > - VSD_FIRST_SECTOR_OFFSET) > + else if (!bh && sector - sector_offset == VSD_FIRST_SECTOR_OFFSET) > return -1; > else > return 0; > -- > 2.20.1 > > > -- Jan Kara <j...@suse.com> SUSE Labs, CR