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