Re: [PATCH] gadget: mass_storage: adapt logic block size to bound block devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Alan,
Thanks.

2011/8/13 Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>:
> On Fri, 12 Aug 2011, Barry Song wrote:
>
>> From: Peiyu Li <peiyu.li@xxxxxxx>
>>
>> Now the mass storage driver has fixed logic block size of 512 bytes.
>>
>> The mass storage gadget read/write bound devices only through vfs, so the bottom level
>> devices actually are just RAW devices to the driver and connected PC. As a raw, hosts
>> can always format, read and write it right in 512 bytes logic block and don't care about
>> the actual logic block devices bound to the gadget.
>>
>> But if we want to share the bound block device partition between target board and PC,
>> in case the logic block size of the bound block device is 4KB, we execute the following
>> steps:
>> 1. connect a board with mass storage gadget to PC(the board has set one partition of
>> on-board block device as file name of the mass storage)
>> 2. PC format the mass storage to VFAT by default logic block size and read/write it
>> 3. disconnect boards from PC
>> 4. target board mount the partition as VFAT
>> Step 4 will fail since kernel on target thinks the logic block size of the bound partition
>> as 4KB.
>> A typical error is
>> "FAT: logical sector size too small for device (logical sector size = 512)"
>>
>> If we execute opposite steps:
>> 1. format the partion to FAT on target board and read/write this partition
>> 2. connect the board to Windows PC as usb mass storage gadget, windows will think the disk
>> is not formatted
>>
>> So the conclusion is that only as a gadget, the mass storage driver has no any problem.
>> But being shared VFAT or other filesystem on PC and target board, it will fail.
>>
>> This patch adapts logic block size to bound block devices and fix the issue.
>
> ...
>
>> @@ -580,7 +581,9 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
>>               rc = (int) size;
>>               goto out;
>>       }
>> -     num_sectors = size >> 9;        /* File size in 512-byte blocks */
>> +     curlun->l_blkbits = blksize_bits(
>> +                     bdev_logical_block_size(inode->i_bdev));
>
> Will this work if the backing file is not a block device?  What if it's
> just a regular file?

if it is just a regular file not a block device node, it has no bound
block device, that means i_bdev is null.
i prefer we make it have default logic block size 512-bytes.
if (inode->i_bdev)
     curlun->l_blkbits = blksize_bits(bdev_logical_block_size(inode->i_bdev));
else
     curlun->l_blkbits = 9;

>
> As long as you're doing this, you might as well store (1 << l_blkbits)
> in curlun too, instead of recomputing it all the time.

only in the read/write loop we re-calculate it,
                                nread -= nread & ((1 << curlun->l_blkbits) - 1);
                                nwritten -= (nwritten & ((1 <<
curlun->l_blkbits) - 1));
we might add a l_blksize field and replace the re-calculation by
                                nread -= nread & (curlun->l_blksize - 1);
                                nwritten -= (nwritten &
(curlun->l_blksize - 1));

>
>> +     num_sectors = size >> curlun->l_blkbits; /* File size in logic-block-size blocks */
>>       min_sectors = 1;
>>       if (curlun->cdrom) {
>>               num_sectors &= ~3;      /* Reduce to a multiple of 2048 */
>
> And as long as you're using variable logical block sizes, you might as
> well set l_blkbits here to 11, because cdroms always use a block size
> of 2048.

ok. i'd like Xianglong make more tests.

>
> Alan Stern

-barry
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux