Bug 16531 - AFFS attempts access beyond end of medium at mount if sector size >512
Summary: AFFS attempts access beyond end of medium at mount if sector size >512
Status: NEW
Alias: None
Product: File System
Classification: Unclassified
Component: AFFS (show other bugs)
Hardware: All Linux
: P1 low
Assignee: Roman Zippel
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-06 17:00 UTC by Mark
Modified: 2016-03-20 09:48 UTC (History)
3 users (show)

See Also:
Kernel Version: any recent
Subsystem:
Regression: No
Bisected commit-id:


Attachments
start root block lookup from blkdev logical block size. (1.62 KB, patch)
2015-06-29 10:06 UTC, PKS
Details | Diff

Description Mark 2010-08-06 17:00:05 UTC
This bug applies when mounting affs partitions when:
 - the partition is on a medium which has physical sectors larger than 512 bytes (e.g. 1024, 2048 or 4096)
 - the bs= mount option is not used.

AFFS (Amiga Fast File System) partitions can use power-of-2 logical block sizes from 256 to 32768 bytes. (However support for 256-byte blocks was removed in later versions of the native Amiga FFS. Linux affs has never supported that, or block sizes >4096.)

Like most filesystems, the AFFS (logical) block size must be a multiple of the device sector size. If the medium has 2048-byte sectors for example, AFFS partitions on that medium cannot use 512- or 1024-byte logical blocks. The minimum logical block size in that case is 2048.

When the bs= mount option (which allows the block size to be specified) is not given, affs tries to determine the filesystem logical block size. In that case, affs tries to find the root block (which is normally "in the middle of" the partition). It checks where the root block would be if using 512-byte logical blocks, then if unsuccessful it checks assuming 1024-byte logical blocks, and so on for 2048- and finally 4096-byte blocks.

When the device sector size is >512 bytes, affs attempts accesses beyond the end of the medium as it checks for impossible block sizes. It should limit the checks to those block sizes which are >= the device sector size.

Here are two examples, for media with 2048 and 1024-byte sectors. (In both cases the filesystem block size is equal to the sector size.)

2048-byte sectors
-----------------
End of dmesg output on inserting disk:
[23019.800097] sd 12:0:0:0: [sdc] 1263472 2048-byte logical blocks: (2.58 GB/2.40 GiB)
[23019.806226]  sdc: unknown partition table

# mount -t affs -o ro /dev/sdc /media/test
[23202.015463] attempt to access beyond end of device
[23202.015467] sdc: rw=0, want=20215560, limit=5053888
[23202.015473] attempt to access beyond end of device
[23202.015475] sdc: rw=0, want=20215568, limit=5053888
[23202.015479] attempt to access beyond end of device
[23202.015481] sdc: rw=0, want=10107784, limit=5053888
[23202.015486] attempt to access beyond end of device
[23202.015488] sdc: rw=0, want=10107792, limit=5053888
[23202.035916] AFFS: Mounting volume "5.2GB_test": Type=DOS\1, Blocksize=2048


1024-byte sectors
-----------------
End of dmesg output on inserting disk:
[23632.799131] sd 12:0:0:0: [sdc] 2319786 1024-byte logical blocks: (2.37 GB/2.21 GiB)
[23632.805180]  sdc: unknown partition table

# mount -t affs -o ro /dev/sdc /media/test
[23646.866179] attempt to access beyond end of device
[23646.866186] sdc: rw=0, want=18558296, limit=4639572
[23646.866196] attempt to access beyond end of device
[23646.866200] sdc: rw=0, want=18558304, limit=4639572
[23646.939145] AFFS: Mounting volume "4.8GB_test": Type=DOS\1, Blocksize=1024



In the code below, instead of
  i = 512;
i should be set to the device sector size. (Possibly the preceding pr_debug should be changed too.)

The relevant code is in fs/affs/super.c:
        /* Get the size of the device in 512-byte blocks.
         * If we later see that the partition uses bigger
         * blocks, we will have to change it.
         */

        size = sb->s_bdev->bd_inode->i_size >> 9;
        pr_debug("AFFS: initial blocksize=%d, #blocks=%d\n", 512, size);

        affs_set_blocksize(sb, PAGE_SIZE);
        /* Try to find root block. Its location depends on the block size. */
        i = 512;
        j = 4096;
        if (blocksize > 0) {
                i = j = blocksize;
                size = size / (blocksize / 512);
Comment 1 Andrew Morton 2010-08-25 23:46:37 UTC
Please email me a patch, as per Documentation/SubmittingPatches?

Suitable recipients are

Andrew Morton <akpm@linux-foundation.org>
linux-fsdevel@vger.kernel.org
linux-kernel@vger.kernel.org
Roman Zippel <zippel@linux-m68k.org>

Thanks.
Comment 2 Mark 2014-01-26 14:50:54 UTC
If someone could tell me how to determine the block device sector size I can try to create a patch.
Comment 3 PKS 2015-06-29 10:06:14 UTC
Created attachment 181241 [details]
start root block lookup from blkdev logical block size.

Hi Mark

Can you check the attached patch.

Note You need to log in before you can comment on or make changes to this bug.